adlibtracker2-2.4.24/0000755000000000000000000000000013414571216013016 5ustar rootrootadlibtracker2-2.4.24/.gitignore0000644000000000000000000000004713411003760014776 0ustar rootrootbin/* release *.o *.ppu *.res adtrack2 adlibtracker2-2.4.24/adt2play/0000755000000000000000000000000013411003760014525 5ustar rootrootadlibtracker2-2.4.24/adt2play/a2data.pas0000644000000000000000000063063213411003760016400 0ustar rootroot// 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.pas0000644000000000000000000010706413411003760016714 0ustar rootroot// 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.inc0000644000000000000000000003137313411003760017112 0ustar rootroot// 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.pas0000644000000000000000000004236413411003760016763 0ustar rootroot// 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.pas0000644000000000000000000001002113411003760017050 0ustar rootroot// 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.pas0000644000000000000000000002211113411003760017065 0ustar rootroot// 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.pas0000644000000000000000000051036513411003760016763 0ustar rootroot// 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.pas0000644000000000000000000003340313411003760017114 0ustar rootroot// 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.pas0000644000000000000000000002106013411003760016700 0ustar rootroot { þ 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.pas0000644000000000000000000003606113411003760016602 0ustar rootroot// 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.inc0000644000000000000000000061142113411003760017027 0ustar rootroot// 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.pas0000644000000000000000000000522513411003760016730 0ustar rootroot// 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.inc0000644000000000000000000011311413411003760015261 0ustar rootroot// 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.pas0000644000000000000000000063641313411003760015261 0ustar rootroot// 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.pas0000644000000000000000000002721113411003760015226 0ustar rootroot// 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.ico0000644000000000000000000001465613411003760015335 0ustar rootroot èF 0. ¨^ ¨  ( @€€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌÌÌÌÌÌÌÌÌÌÌÌÌ̳ ÌDCDDDDDDDDDD³DDK0DDDDDDDDD³DDK³DDDDDDDDD³DDD»0DDDDDDDD³DDDK³DDDDDDDD³DDDD»0DDDDDDD³DDDDK³DDD@³DDDDD»0DDC333³DDDDDK³DDK»»»³DDDDDD»0DDDDD³DDDDDDK³DDDDD³DDDDDDD»0DDDD³D ³³»0³ ³³»0³³³³³³³³( @ÎØ(((ÿÿÿ00000000000 000€0Àð`ð000 000€0À00000000( @€T€Œ8(¨˜€0¨À°p @„ÔÌDL //////////////////////////////:=#/////////////////////////////- /////////////////////- /- - &&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&AAAAAAAA@@AAAAAAAA@@@@@@@A AAA6'7 HHH"3BHHHHHHHHHHHHHHHHHHH7nul if exist adtrack2.exe goto :error :exe_ok echo. echo ************************************ echo ** ** echo ** Compiling ADTRACK2 ** echo ** ** echo ************************************ echo. fpc.exe -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Twin32 -WC -Fusdl adtrack2.pas -oadtrack2.exe set ERR_RESULT="OK" goto :end :error echo. echo ************************************ echo ** ** echo ** COMPILATION WAS ABORTED ** echo ** ** echo ** Some files are still in use ** echo ** by other process! ** echo ** ** echo ************************************ :end adlibtracker2-2.4.24/adt2data.pas0000644000000000000000000007527413411003760015215 0ustar rootroot// 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 AdT2data; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const font8x16: array[0..1023] of Dword = ( $00000000,$00000000,$00000000,$00000000,$71300000,$313131F1,$FC313131,$00000000, $CD780000,$31190DCD,$FCCDC161,$00000000,$29CE0000,$2E292929,$C8282828,$00000000, $19080000,$FDD97939,$3C191919,$00000000,$00000000,$06361C00,$BE32180C,$00000000, $00000000,$18181F00,$9E33031E,$00000000,$00000000,$28440000,$44281010,$00000000, $E7E70000,$E7E7E7E7,$E7E7E7E7,$000000E7,$FFFF0000,$C3C7CFDF,$FFDFCFC7,$000000FF, $38100000,$1010107C,$10387C10,$00000000,$00000000,$7E7E7E3C,$00003C7E,$00000000, $991F0000,$1818385F,$70793A1C,$00000000,$191F0000,$1818181F,$70783818,$00000000, $55555500,$55555555,$55555555,$00000055,$7F7F7F00,$7F7F7F7F,$7F7F7F7F,$0000007F, $60400000,$7E7C7870,$6070787C,$00000040,$06020000,$7E3E1E0E,$060E1E3E,$00000002, $38100000,$1010107C,$10001000,$00000000,$82FE0000,$32128282,$3070FE72,$00000010, $00000000,$AA000000,$00000000,$00000000,$28140000,$50505050,$14285050,$00000000, $14280000,$0A0A0A0A,$28140A0A,$00000000,$00100000,$10100010,$10387C10,$00000000, $38100000,$1010107C,$10101010,$00000000,$10100000,$10101010,$10387C10,$00000000, $00000000,$FF0E0C08,$00080C0E,$00000000,$00000000,$FF703010,$00103070,$00000000, $00000000,$3C3C1800,$00000018,$00000000,$F3FE0000,$81FFF3F3,$FF81FF81,$00000000, $00000000,$7C383810,$00FEFE7C,$00000000,$00000000,$7C7CFEFE,$00103838,$00000000, $00000000,$00000000,$00000000,$00000000,$3C180000,$18183C3C,$18180018,$00000000, $28282800,$00002828,$00000000,$00000000,$28000000,$28287C28,$28287C28,$00000000, $D67C1010,$167CD0D2,$7CD69616,$00001010,$00000000,$08C4C200,$86462010,$00000000, $6C380000,$DC76386C,$76CCCCCC,$00000000,$10101000,$00000020,$00000000,$00000000, $10080000,$20202020,$08102020,$00000000,$08100000,$04040404,$10080404,$00000000, $00000000,$FE385410,$00105438,$00000000,$00000000,$7C101000,$00001010,$00000000, $00000000,$00000000,$10101000,$00000020,$00000000,$7C000000,$00000000,$00000000, $00000000,$00000000,$10000000,$00000000,$00000000,$08040200,$80402010,$00000000, $6C380000,$D6D6C6C6,$386CC6C6,$00000000,$38180000,$18181878,$7E181818,$00000000, $C67C0000,$30180C06,$FEC6C060,$00000000,$C67C0000,$063C0606,$7CC60606,$00000000, $1C0C0000,$FECC6C3C,$1E0C0C0C,$00000000,$C0FE0000,$06FCC0C0,$7CC60606,$00000000, $60380000,$C6FCC0C0,$7CC6C6C6,$00000000,$C6FE0000,$180C0606,$30303030,$00000000, $C67C0000,$C67CC6C6,$7CC6C6C6,$00000000,$C67C0000,$067EC6C6,$780C0606,$00000000, $00000000,$00001000,$00001000,$00000000,$00000000,$00001000,$20101000,$00000000, $04000000,$40201008,$04081020,$00000000,$00000000,$00003C00,$0000003C,$00000000, $20000000,$02040810,$20100804,$00000000,$C67C0000,$18180CC6,$18180018,$00000000, $7C000000,$DEDEC6C6,$7CC0DCDE,$00000000,$38100000,$FEC6C66C,$C6C6C6C6,$00000000, $66FC0000,$667C6666,$FC666666,$00000000,$663C0000,$C0C0C0C2,$3C66C2C0,$00000000, $6CF80000,$66666666,$F86C6666,$00000000,$66FE0000,$68786862,$FE666260,$00000000, $66FE0000,$68786862,$F0606060,$00000000,$663C0000,$DEC0C0C2,$3A66C6C6,$00000000, $C6C60000,$C6FEC6C6,$C6C6C6C6,$00000000,$183C0000,$18181818,$3C181818,$00000000, $0C1E0000,$0C0C0C0C,$78CCCCCC,$00000000,$66E60000,$78786C66,$E666666C,$00000000, $60F00000,$60606060,$FE666260,$00000000,$EEC60000,$C6D6FEFE,$C6C6C6C6,$00000000, $E6C60000,$CEDEFEF6,$C6C6C6C6,$00000000,$C67C0000,$C6C6C6C6,$7CC6C6C6,$00000000, $66FC0000,$607C6666,$F0606060,$00000000,$C67C0000,$C6C6C6C6,$7CDED6C6,$00000E0C, $66FC0000,$6C7C6666,$E6666666,$00000000,$C67C0000,$0C3860C6,$7CC6C606,$00000000, $7E7E0000,$1818185A,$3C181818,$00000000,$C6C60000,$C6C6C6C6,$7CC6C6C6,$00000000, $C6C60000,$C6C6C6C6,$10386CC6,$00000000,$C6C60000,$D6D6C6C6,$6CEEFED6,$00000000, $C6C60000,$38387C6C,$C6C66C7C,$00000000,$66660000,$183C6666,$3C181818,$00000000, $C6FE0000,$30180C86,$FEC6C260,$00000000,$20380000,$20202020,$38202020,$00000000, $00000000,$20408000,$02040810,$00000000,$041C0000,$04040404,$1C040404,$00000000, $6C381000,$000000C6,$00000000,$00000000,$00000000,$00000000,$00000000,$0000FF00, $00081010,$00000000,$00000000,$00000000,$00000000,$7C0C7800,$76CCCCCC,$00000000, $60E00000,$666C7860,$7C666666,$00000000,$00000000,$C0C67C00,$7CC6C0C0,$00000000, $0C1C0000,$CC6C3C0C,$76CCCCCC,$00000000,$00000000,$FEC67C00,$7CC6C0C0,$00000000, $6C380000,$60F06064,$F0606060,$00000000,$00000000,$CCCC7600,$7CCCCCCC,$0078CC0C, $60E00000,$66766C60,$E6666666,$00000000,$18000000,$18183800,$3C181818,$00000000, $06000000,$06060E00,$06060606,$003C6666,$60E00000,$786C6660,$E6666C78,$00000000, $18380000,$18181818,$3C181818,$00000000,$00000000,$D6FEEC00,$C6D6D6D6,$00000000, $00000000,$6666DC00,$66666666,$00000000,$00000000,$C6C67C00,$7CC6C6C6,$00000000, $00000000,$6666DC00,$7C666666,$00F06060,$00000000,$CCCC7600,$7CCCCCCC,$001E0C0C, $00000000,$6676DC00,$F0606060,$00000000,$00000000,$60C67C00,$7CC60C38,$00000000, $30100000,$3030FC30,$1C363030,$00000000,$00000000,$CCCCCC00,$76CCCCCC,$00000000, $00000000,$66666600,$183C6666,$00000000,$00000000,$D6C6C600,$6CFED6D6,$00000000, $00000000,$386CC600,$C66C3838,$00000000,$00000000,$C6C6C600,$7EC6C6C6,$00F80C06, $00000000,$18CCFE00,$FEC66030,$00000000,$100C0000,$10601010,$0C101010,$00000000, $10100000,$10001010,$10101010,$00000000,$08300000,$08060808,$30080808,$00000000, $DC760000,$00000000,$00000000,$00000000,$023E0000,$12020202,$10307E32,$00000000, $00000000,$00000000,$00000000,$FF000000,$00000000,$00000000,$00000000,$FFFF0000, $00000000,$00000000,$00000000,$FFFFFF00,$00000000,$00000000,$00000000,$FFFFFFFF, $00000000,$00000000,$FF000000,$FFFFFFFF,$00000000,$00000000,$FFFF0000,$FFFFFFFF, $00000000,$00000000,$FFFFFF00,$FFFFFFFF,$00000000,$00000000,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFF0000,$FFFFFFFF,$FFFFFFFF, $00000000,$FFFFFF00,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FF000000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFF0000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FFFFFF00,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$00FFFFFF, $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$0000FFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$000000FF, $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$00FFFFFF,$00000000, $FFFFFFFF,$FFFFFFFF,$0000FFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$000000FF,$00000000, $FFFFFFFF,$FFFFFFFF,$00000000,$00000000,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $FFFFFFFF,$0000FFFF,$00000000,$00000000,$FFFFFFFF,$000000FF,$00000000,$00000000, $FFFFFFFF,$00000000,$00000000,$00000000,$00FFFFFF,$00000000,$00000000,$00000000, $0000FFFF,$00000000,$00000000,$00000000,$000000FF,$00000000,$00000000,$00000000, $10101010,$10101010,$10101010,$7C101010,$00000000,$0A110000,$110A0404,$00000000, $AACC0000,$AACAAAAA,$CCAAAAAA,$00000000,$AA4C0000,$4A8A8AAA,$4CAA2A2A,$00000000, $44EE0000,$44444444,$44444444,$00000000,$4AE40000,$4848484A,$444A4848,$00000000, $AAAA0000,$AAEEAAAA,$AAAAAAAA,$00000000,$00000000,$FFFFFF00,$80808000,$00808080, $00000000,$FFFFFF00,$A0A0A000,$00A0A0A0,$00000000,$FFFFFF00,$A8A8A800,$00A8A8A8, $00000000,$FFFFFF00,$AAAAAA00,$00AAAAAA,$10101010,$FFFFFF10,$AAAAAA00,$00AAAAAA, $00000000,$60606000,$7E606060,$00000000,$00000000,$C6C6FC00,$C6C6CCFC,$00000000, $00100015,$1C0C0010,$0C7E6C3C,$001E0C0C,$96959566,$10006494,$10001000,$00001500, $90900000,$F7F09090,$97949291,$00000000,$00100010,$38000010,$00003838,$00000000, $44114411,$44114411,$44114411,$44114411,$AA55AA55,$AA55AA55,$AA55AA55,$AA55AA55, $77DD77DD,$77DD77DD,$77DD77DD,$77DD77DD,$10101010,$10101010,$10101010,$10101010, $10101010,$F0101010,$10101010,$10101010,$10101010,$F0F0F010,$10101010,$10101010, $3C3C3C3C,$FC3C3C3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FC000000,$3C3C3C3C,$3C3C3C3C, $00000000,$F0F0F000,$10101010,$10101010,$3C3C3C3C,$FCFCFC3C,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FCFCFC00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$FCFCFC3C,$00000000,$00000000,$3C3C3C3C,$FC3C3C3C,$00000000,$00000000, $10101010,$F0F0F010,$00000000,$00000000,$00000000,$F0000000,$10101010,$10101010, $10101010,$1F101010,$00000000,$00000000,$10101010,$FF101010,$00000000,$00000000, $00000000,$FF000000,$10101010,$10101010,$10101010,$1F101010,$10101010,$10101010, $00000000,$FF000000,$00000000,$00000000,$10101010,$FF101010,$10101010,$10101010, $10101010,$1F1F1F10,$10101010,$10101010,$3C3C3C3C,$3F3C3C3C,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3F3F3F3C,$00000000,$00000000,$00000000,$3F3F3F00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$FFFFFF3C,$00000000,$00000000,$00000000,$FFFFFF00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3F3F3F3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FFFFFF00,$00000000,$00000000, $3C3C3C3C,$FFFFFF3C,$3C3C3C3C,$3C3C3C3C,$10101010,$FFFFFF10,$00000000,$00000000, $3C3C3C3C,$FF3C3C3C,$00000000,$00000000,$00000000,$FFFFFF00,$10101010,$10101010, $00000000,$FF000000,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$3F3C3C3C,$00000000,$00000000, $10101010,$1F1F1F10,$00000000,$00000000,$00000000,$1F1F1F00,$10101010,$10101010, $00000000,$3F000000,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$FF3C3C3C,$3C3C3C3C,$3C3C3C3C, $10101010,$FFFFFF10,$10101010,$10101010,$10101010,$F0101010,$00000000,$00000000, $00000000,$1F000000,$10101010,$10101010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0, $0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $00100010,$00920010,$00100010,$00920010,$00100010,$00920010,$00100010,$FF100010, $00100010,$00920010,$00100010,$FFFF0010,$00100010,$00920010,$00100010,$FFFFFF10, $00100010,$00920010,$00100010,$FFFFFFFF,$00100010,$00920010,$FF100010,$FFFFFFFF, $00100010,$00920010,$FFFF0010,$FFFFFFFF,$00100010,$00920010,$FFFFFF10,$FFFFFFFF, $00100010,$00920010,$FFFFFFFF,$FFFFFFFF,$00100010,$FF920010,$FFFFFFFF,$FFFFFFFF, $00100010,$FFFF0010,$FFFFFFFF,$FFFFFFFF,$00100010,$FFFFFF10,$FFFFFFFF,$FFFFFFFF, $00100010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FF100010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FFFF0010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFF10,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $01010101,$01010101,$01010101,$01010101,$10000000,$10101010,$10101010,$00000000, $00000000,$FF000000,$00100010,$00920010,$00100010,$FF100010,$00000000,$00000000, $18783818,$10081C1A,$00000020,$00000000,$186C6C38,$10087C32,$00000020,$00000000, $00100010,$00100010,$00100010,$00100010,$00010001,$00010001,$00010001,$00010001, $00100015,$00100010,$00100010,$00100010,$00000000,$28281000,$00001028,$00000000, $00000000,$10000000,$00000000,$00000000,$03010000,$CC040602,$307058C8,$00000000, $3E1C0800,$FFFFFF7F,$00000000,$00000000,$00000000,$FFFFFF00,$081C3E7F,$00000000, $00000000,$7C7C7C7C,$007C7C7C,$00000000,$00000000,$00000000,$00000000,$00000000); const vga_font8x16: array[0..1023] of Dword = ( $00000000,$00000000,$00000000,$00000000,$817E0000,$BD8181A5,$7E818199,$00000000, $FF7E0000,$C3FFFFDB,$7EFFFFE7,$00000000,$00000000,$FEFEFE6C,$10387CFE,$00000000, $00000000,$FE7C3810,$0010387C,$00000000,$18000000,$E7E73C3C,$3C1818E7,$00000000, $18000000,$FFFF7E3C,$3C18187E,$00000000,$00000000,$3C180000,$0000183C,$00000000, $FFFFFFFF,$C3E7FFFF,$FFFFE7C3,$FFFFFFFF,$00000000,$42663C00,$003C6642,$00000000, $FFFFFFFF,$BD99C3FF,$FFC399BD,$FFFFFFFF,$0E1E0000,$CC78321A,$78CCCCCC,$00000000, $663C0000,$3C666666,$18187E18,$00000000,$333F0000,$3030303F,$E0F07030,$00000000, $637F0000,$6363637F,$E6E76763,$000000C0,$18000000,$E73CDB18,$1818DB3C,$00000000, $E0C08000,$F8FEF8F0,$80C0E0F0,$00000000,$0E060200,$3EFE3E1E,$02060E1E,$00000000, $3C180000,$1818187E,$00183C7E,$00000000,$66660000,$66666666,$66660066,$00000000, $DB7F0000,$1B7BDBDB,$1B1B1B1B,$00000000,$60C67C00,$C6C66C38,$C60C386C,$0000007C, $00000000,$00000000,$FEFEFEFE,$00000000,$3C180000,$1818187E,$7E183C7E,$00000000, $3C180000,$1818187E,$18181818,$00000000,$18180000,$18181818,$183C7E18,$00000000, $00000000,$FE0C1800,$0000180C,$00000000,$00000000,$FE603000,$00003060,$00000000, $00000000,$C0C00000,$0000FEC0,$00000000,$00000000,$FF662400,$00002466,$00000000, $00000000,$7C383810,$00FEFE7C,$00000000,$00000000,$7C7CFEFE,$00103838,$00000000, $00000000,$00000000,$00000000,$00000000,$3C180000,$18183C3C,$18180018,$00000000, $66666600,$00000024,$00000000,$00000000,$6C000000,$6C6CFE6C,$6C6CFE6C,$00000000, $C67C1818,$067CC0C2,$7CC68606,$00001818,$00000000,$180CC6C2,$86C66030,$00000000, $6C380000,$DC76386C,$76CCCCCC,$00000000,$30303000,$00000060,$00000000,$00000000, $180C0000,$30303030,$0C183030,$00000000,$18300000,$0C0C0C0C,$30180C0C,$00000000, $00000000,$FF3C6600,$0000663C,$00000000,$00000000,$7E181800,$00001818,$00000000, $00000000,$00000000,$18181800,$00000030,$00000000,$FE000000,$00000000,$00000000, $00000000,$00000000,$18180000,$00000000,$00000000,$180C0602,$80C06030,$00000000, $663C0000,$DBDBC3C3,$3C66C3C3,$00000000,$38180000,$18181878,$7E181818,$00000000, $C67C0000,$30180C06,$FEC6C060,$00000000,$C67C0000,$063C0606,$7CC60606,$00000000, $1C0C0000,$FECC6C3C,$1E0C0C0C,$00000000,$C0FE0000,$06FCC0C0,$7CC60606,$00000000, $60380000,$C6FCC0C0,$7CC6C6C6,$00000000,$C6FE0000,$180C0606,$30303030,$00000000, $C67C0000,$C67CC6C6,$7CC6C6C6,$00000000,$C67C0000,$067EC6C6,$780C0606,$00000000, $00000000,$00001818,$00181800,$00000000,$00000000,$00001818,$30181800,$00000000, $06000000,$6030180C,$060C1830,$00000000,$00000000,$00007E00,$0000007E,$00000000, $60000000,$060C1830,$6030180C,$00000000,$C67C0000,$18180CC6,$18180018,$00000000, $7C000000,$DEDEC6C6,$7CC0DCDE,$00000000,$38100000,$FEC6C66C,$C6C6C6C6,$00000000, $66FC0000,$667C6666,$FC666666,$00000000,$663C0000,$C0C0C0C2,$3C66C2C0,$00000000, $6CF80000,$66666666,$F86C6666,$00000000,$66FE0000,$68786862,$FE666260,$00000000, $66FE0000,$68786862,$F0606060,$00000000,$663C0000,$DEC0C0C2,$3A66C6C6,$00000000, $C6C60000,$C6FEC6C6,$C6C6C6C6,$00000000,$183C0000,$18181818,$3C181818,$00000000, $0C1E0000,$0C0C0C0C,$78CCCCCC,$00000000,$66E60000,$78786C66,$E666666C,$00000000, $60F00000,$60606060,$FE666260,$00000000,$E7C30000,$C3DBFFFF,$C3C3C3C3,$00000000, $E6C60000,$CEDEFEF6,$C6C6C6C6,$00000000,$C67C0000,$C6C6C6C6,$7CC6C6C6,$00000000, $66FC0000,$607C6666,$F0606060,$00000000,$C67C0000,$C6C6C6C6,$7CDED6C6,$00000E0C, $66FC0000,$6C7C6666,$E6666666,$00000000,$C67C0000,$0C3860C6,$7CC6C606,$00000000, $DBFF0000,$18181899,$3C181818,$00000000,$C6C60000,$C6C6C6C6,$7CC6C6C6,$00000000, $C3C30000,$C3C3C3C3,$183C66C3,$00000000,$C3C30000,$DBC3C3C3,$6666FFDB,$00000000, $C3C30000,$18183C66,$C3C3663C,$00000000,$C3C30000,$183C66C3,$3C181818,$00000000, $C3FF0000,$30180C86,$FFC3C160,$00000000,$303C0000,$30303030,$3C303030,$00000000, $80000000,$3870E0C0,$02060E1C,$00000000,$0C3C0000,$0C0C0C0C,$3C0C0C0C,$00000000, $C66C3810,$00000000,$00000000,$00000000,$00000000,$00000000,$00000000,$0000FF00, $00183030,$00000000,$00000000,$00000000,$00000000,$7C0C7800,$76CCCCCC,$00000000, $60E00000,$666C7860,$7C666666,$00000000,$00000000,$C0C67C00,$7CC6C0C0,$00000000, $0C1C0000,$CC6C3C0C,$76CCCCCC,$00000000,$00000000,$FEC67C00,$7CC6C0C0,$00000000, $6C380000,$60F06064,$F0606060,$00000000,$00000000,$CCCC7600,$7CCCCCCC,$0078CC0C, $60E00000,$66766C60,$E6666666,$00000000,$18180000,$18183800,$3C181818,$00000000, $06060000,$06060E00,$06060606,$003C6666,$60E00000,$786C6660,$E6666C78,$00000000, $18380000,$18181818,$3C181818,$00000000,$00000000,$DBFFE600,$DBDBDBDB,$00000000, $00000000,$6666DC00,$66666666,$00000000,$00000000,$C6C67C00,$7CC6C6C6,$00000000, $00000000,$6666DC00,$7C666666,$00F06060,$00000000,$CCCC7600,$7CCCCCCC,$001E0C0C, $00000000,$6676DC00,$F0606060,$00000000,$00000000,$60C67C00,$7CC60C38,$00000000, $30100000,$3030FC30,$1C363030,$00000000,$00000000,$CCCCCC00,$76CCCCCC,$00000000, $00000000,$C3C3C300,$183C66C3,$00000000,$00000000,$C3C3C300,$66FFDBDB,$00000000, $00000000,$3C66C300,$C3663C18,$00000000,$00000000,$C6C6C600,$7EC6C6C6,$00F80C06, $00000000,$18CCFE00,$FEC66030,$00000000,$180E0000,$18701818,$0E181818,$00000000, $18180000,$18001818,$18181818,$00000000,$18700000,$180E1818,$70181818,$00000000, $DC760000,$00000000,$00000000,$00000000,$00000000,$C66C3810,$00FEC6C6,$00000000, $663C0000,$C0C0C0C2,$0C3C66C2,$00007C06,$00CC0000,$CCCCCC00,$76CCCCCC,$00000000, $30180C00,$FEC67C00,$7CC6C0C0,$00000000,$6C381000,$7C0C7800,$76CCCCCC,$00000000, $00CC0000,$7C0C7800,$76CCCCCC,$00000000,$18306000,$7C0C7800,$76CCCCCC,$00000000, $386C3800,$7C0C7800,$76CCCCCC,$00000000,$00000000,$6060663C,$060C3C66,$0000003C, $6C381000,$FEC67C00,$7CC6C0C0,$00000000,$00C60000,$FEC67C00,$7CC6C0C0,$00000000, $18306000,$FEC67C00,$7CC6C0C0,$00000000,$00660000,$18183800,$3C181818,$00000000, $663C1800,$18183800,$3C181818,$00000000,$18306000,$18183800,$3C181818,$00000000, $1000C600,$C6C66C38,$C6C6C6FE,$00000000,$00386C38,$C6C66C38,$C6C6C6FE,$00000000, $00603018,$7C6066FE,$FE666060,$00000000,$00000000,$1B3B6E00,$77DCD87E,$00000000, $6C3E0000,$CCFECCCC,$CECCCCCC,$00000000,$6C381000,$C6C67C00,$7CC6C6C6,$00000000, $00C60000,$C6C67C00,$7CC6C6C6,$00000000,$18306000,$C6C67C00,$7CC6C6C6,$00000000, $CC783000,$CCCCCC00,$76CCCCCC,$00000000,$18306000,$CCCCCC00,$76CCCCCC,$00000000, $00C60000,$C6C6C600,$7EC6C6C6,$00780C06,$7C00C600,$C6C6C6C6,$7CC6C6C6,$00000000, $C600C600,$C6C6C6C6,$7CC6C6C6,$00000000,$7E181800,$C0C0C0C3,$18187EC3,$00000000, $646C3800,$6060F060,$FCE66060,$00000000,$66C30000,$18FF183C,$181818FF,$00000000, $6666FC00,$6F66627C,$F3666666,$00000000,$181B0E00,$187E1818,$18181818,$000070D8, $60301800,$7C0C7800,$76CCCCCC,$00000000,$30180C00,$18183800,$3C181818,$00000000, $60301800,$C6C67C00,$7CC6C6C6,$00000000,$60301800,$CCCCCC00,$76CCCCCC,$00000000, $DC760000,$6666DC00,$66666666,$00000000,$C600DC76,$DEFEF6E6,$C6C6C6CE,$00000000, $6C6C3C00,$007E003E,$00000000,$00000000,$6C6C3800,$007C0038,$00000000,$00000000, $30300000,$60303000,$7CC6C6C0,$00000000,$00000000,$C0FE0000,$00C0C0C0,$00000000, $00000000,$06FE0000,$00060606,$00000000,$C2C0C000,$3018CCC6,$069BCE60,$00001F0C, $C2C0C000,$3018CCC6,$3E96CE66,$00000606,$18180000,$18181800,$183C3C3C,$00000000, $00000000,$D86C3600,$0000366C,$00000000,$00000000,$366CD800,$0000D86C,$00000000, $44114411,$44114411,$44114411,$44114411,$AA55AA55,$AA55AA55,$AA55AA55,$AA55AA55, $77DD77DD,$77DD77DD,$77DD77DD,$77DD77DD,$18181818,$18181818,$18181818,$18181818, $18181818,$F8181818,$18181818,$18181818,$18181818,$F818F818,$18181818,$18181818, $36363636,$F6363636,$36363636,$36363636,$00000000,$FE000000,$36363636,$36363636, $00000000,$F818F800,$18181818,$18181818,$36363636,$F606F636,$36363636,$36363636, $36363636,$36363636,$36363636,$36363636,$00000000,$F606FE00,$36363636,$36363636, $36363636,$FE06F636,$00000000,$00000000,$36363636,$FE363636,$00000000,$00000000, $18181818,$F818F818,$00000000,$00000000,$00000000,$F8000000,$18181818,$18181818, $18181818,$1F181818,$00000000,$00000000,$18181818,$FF181818,$00000000,$00000000, $00000000,$FF000000,$18181818,$18181818,$18181818,$1F181818,$18181818,$18181818, $00000000,$FF000000,$00000000,$00000000,$18181818,$FF181818,$18181818,$18181818, $18181818,$1F181F18,$18181818,$18181818,$36363636,$37363636,$36363636,$36363636, $36363636,$3F303736,$00000000,$00000000,$00000000,$37303F00,$36363636,$36363636, $36363636,$FF00F736,$00000000,$00000000,$00000000,$F700FF00,$36363636,$36363636, $36363636,$37303736,$36363636,$36363636,$00000000,$FF00FF00,$00000000,$00000000, $36363636,$F700F736,$36363636,$36363636,$18181818,$FF00FF18,$00000000,$00000000, $36363636,$FF363636,$00000000,$00000000,$00000000,$FF00FF00,$18181818,$18181818, $00000000,$FF000000,$36363636,$36363636,$36363636,$3F363636,$00000000,$00000000, $18181818,$1F181F18,$00000000,$00000000,$00000000,$1F181F00,$18181818,$18181818, $00000000,$3F000000,$36363636,$36363636,$36363636,$FF363636,$36363636,$36363636, $18181818,$FF18FF18,$18181818,$18181818,$18181818,$F8181818,$00000000,$00000000, $00000000,$1F000000,$18181818,$18181818,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0, $0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $00000000,$D8DC7600,$76DCD8D8,$00000000,$CC780000,$CCD8CCCC,$CCC6C6C6,$00000000, $C6FE0000,$C0C0C0C6,$C0C0C0C0,$00000000,$00000000,$6C6C6CFE,$6C6C6C6C,$00000000, $FE000000,$183060C6,$FEC66030,$00000000,$00000000,$D8D87E00,$70D8D8D8,$00000000, $00000000,$66666666,$60607C66,$000000C0,$00000000,$1818DC76,$18181818,$00000000, $7E000000,$66663C18,$7E183C66,$00000000,$38000000,$FEC6C66C,$386CC6C6,$00000000, $6C380000,$6CC6C6C6,$EE6C6C6C,$00000000,$301E0000,$663E0C18,$3C666666,$00000000, $00000000,$DBDB7E00,$00007EDB,$00000000,$03000000,$DBDB7E06,$C0607EF3,$00000000, $301C0000,$607C6060,$1C306060,$00000000,$7C000000,$C6C6C6C6,$C6C6C6C6,$00000000, $00000000,$FE0000FE,$00FE0000,$00000000,$00000000,$187E1818,$FF000018,$00000000, $30000000,$0C060C18,$7E003018,$00000000,$0C000000,$30603018,$7E000C18,$00000000, $1B0E0000,$1818181B,$18181818,$18181818,$18181818,$18181818,$70D8D8D8,$00000000, $00000000,$7E001818,$00181800,$00000000,$00000000,$00DC7600,$0000DC76,$00000000, $6C6C3800,$00000038,$00000000,$00000000,$00000000,$18000000,$00000018,$00000000, $00000000,$00000000,$00000018,$00000000,$0C0C0F00,$EC0C0C0C,$1C3C6C6C,$00000000, $6C6CD800,$006C6C6C,$00000000,$00000000,$30D87000,$00F8C860,$00000000,$00000000, $00000000,$7C7C7C7C,$007C7C7C,$00000000,$00000000,$00000000,$00000000,$00000000); {$IFNDEF GO32V2} const adt2_icon_bitmap: array[0..782] of Dword = ( $0C364D42,$00000000,$00360000,$00280000,$00200000,$00200000,$00010000,$00000018, $0C000000,$00000000,$00000000,$00000000,$00000000,$CAFF0000,$77CAFF77,$FF7ACDFF, $CDFF7ACD,$7ACDFF7A,$FF77CAFF,$CDFF77CA,$7ACDFF7A,$FF77CAFF,$CDFF77CA,$7ACDFF7A, $FF77CAFF,$CDFF77CA,$7ACDFF7A,$FF7ACDFF,$CDFF7ACD,$7ACDFF7A,$FF7ACCFF,$CDFF7ACC, $7ACDFF7A,$EA81CFFA,$C4F681C7,$79CCFF77,$FF7ACDFF,$C9FF7ACD,$76C9FF77,$FF76C9FF, $C9FF76C9,$77C9FF77,$FF77CAFF,$CAFF77CA,$77CAFF77,$FF77CAFF,$CAFF77CA,$77CAFF77, $FF77CAFF,$CAFF77CA,$77CAFF77,$FF77CAFF,$C9FF77CA,$77C9FF77,$FF77CAFF,$C9FF77CA, $76C9FF77,$19D4E397,$5366A487,$76C9FF53,$FF77C9FF,$C4FF76C5,$76C5FF74,$FF76C5FF, $C5FF76C5,$76C5FF76,$FF76C5FF,$C5FF76C5,$76C5FF76,$FF76C5FF,$C5FF76C5,$76C5FF76, $FF76C5FF,$C5FF76C5,$76C5FF76,$FF76C5FF,$C5FF76C5,$76C5FF76,$FF76C5FF,$C4FF76C5, $74C4FF74,$1AEFF47E,$45578571,$74C4FF48,$FF74C4FF,$BFFF74C1,$73C1FF73,$FF73BFFF, $BFFF73BF,$73BFFF73,$FF74C1FF,$C1FF74C1,$74C1FF74,$FF73C1FF,$C1FF73C1,$74C1FF74, $FF73BFFF,$C1FF73BF,$73C1FF73,$FF74C1FF,$C1FF74C1,$74C1FF74,$FF73C1FF,$C1FF73C1, $73BFFF74,$1AECF27D,$40528773,$73BFFF44,$FF73C1FF,$BBFF73BF,$71BBFF6E,$FF71BBFF, $BBFF71BB,$71BBFF71,$FF71BBFF,$BBFF71BB,$6EBBFF6E,$FF71BBFF,$BCFF71BB,$71BCFF71, $FF71BCFF,$BCFF71BC,$71BCFF71,$FF71BCFF,$BBFF71BC,$71BBFF71,$FF71BCFF,$BBFF71BC, $6EBBFF71,$16ECF07B,$4052836E,$6EBBFF45,$FF71BBFF,$B1FF6EB9,$6BB1FF6B,$FF6CB5FF, $B5FF6CB5,$6CB5FF6C,$FF6CB5FF,$B6FF6CB5,$6CB6FF6C,$FF6CB6FF,$B6FF6CB6,$6CB6FF6C, $FF6CB5FF,$B5FF6CB5,$6CB5FF6C,$FF6EB6FF,$B6FF6EB6,$6CB6FF6C,$FF6CB5FF,$B5FF6CB5, $6BB5FF6B,$16EAEF79,$4452836E,$6BB1FF47,$FF6BB1FF,$ADFF6BB1,$68ABFF68,$FF68ADFF, $ABFF68AD,$68ABFF68,$FF68ADFF,$ADFF68AD,$69ADFF69,$FF69ADFF,$ADFF69AD,$69ADFF69, $FF69ADFF,$ADFF69AD,$69ADFF69,$FF69B0FF,$ADFF69B0,$68ADFF68,$FF69B0FF,$ADFF69B0, $68ADFF68,$26F0F380,$45539080,$68ABFF4B,$FF68ADFF,$A5FF68AB,$63A5FF63,$FF63A5FF, $A5FF63A5,$63A5FF63,$FF63A7FF,$A5FF63A7,$63A5FF63,$FF63A5FF,$A5FF63A5,$63A5FF63, $FF63A5FF,$A5FF63A5,$63A5FF63,$FF66A7FF,$A5FF66A7,$63A5FF63,$FF63A5FF,$A5FF63A5, $62A2FF63,$28F0F381,$404D9382,$63A5FF47,$FF63A5FF,$99FF62A2,$5F9CFF5F,$FF5F9CFF, $9CFF5F9C,$5F9CFF5F,$FF5F99FF,$9EFF5F9C,$609EFF60,$FF5F9CFF,$9CFF5F9C,$5F9CFF5F, $FF5F9CFF,$9CFF5F9C,$5F9CFF5F,$FF609EFF,$9EFF609E,$609EFF60,$FF609CFF,$9CFF609C, $5F9CFF60,$28F1F480,$3B489382,$5F9CFF44,$FF5F99FF,$8EF45D99,$5891F457,$AB588EF4, $3D328299,$3B191058,$F55891F4,$91F55891,$5891F558,$F55891F5,$91F55891,$5891F558, $F55891F5,$91F55891,$5891F558,$F75893F7,$91F55893,$5891F558,$F55891F5,$91F55891, $578EF458,$2AF0F27F,$404A9585,$578EF447,$F4578EF4,$82E3578E,$5283E64F,$A44F83E6, $7619D2E3,$2D00009A,$E6350F05,$83E65283,$5283E74F,$E65283E6,$85E75283,$5485E754, $E65283E6,$83E75283,$5283E752,$E65283E6,$85E75283,$5485E754,$E65283E6,$85E75283, $5283E652,$33F0F27F,$47529D8F,$4F82E650,$E34F82E3,$74D24F82,$4B76D549,$9E4971D2, $FF96D2E0,$9F7D1EFF,$012F0000,$74D3350F,$4974D349,$D54B76D5,$76D54B76,$4B76D54B, $D54B76D5,$76D54B76,$4B76D54B,$D34B74D3,$74D34B74,$4B74D34B,$D54B76D5,$76D54B76, $4B76D54B,$3AF2F37F,$444CA294,$4974D34D,$D34B74D3,$65BF4B74,$4166C141,$B64165BF, $FF907693,$FFFF85FF,$00967113,$07002D00,$4165C130,$C14165BF,$65C14166,$4165C141, $C14165C1,$65C14165,$4165C141,$C14166C1,$65C14166,$4165C141,$C14166C1,$65BF4166, $4062BF40,$2FF1F27E,$29339988,$4062BF3A,$BE4165BF,$51AA4062,$3752AB37,$A73751AA, $82A23551,$FDFF7D6B,$07FFFF71,$00008B65,$27000023,$AA3752AA,$52AA3751,$3752AA37, $AA3752AA,$52AA3752,$3752AA37,$AA3752AA,$51AA3752,$3751AA37,$AA3751AA,$52AB3751, $3752AB38,$23EDED79,$1B238F7C,$3751AA32,$A73751AA,$3D90354E,$2C3D912A,$902C3D90, $3D902C3D,$2C3D902C,$65F8F876,$5A00FFFF,$1C000082,$90210000,$3A902A3A,$2C3D902A, $912C3D91,$3D902C3D,$2A3D902A,$902C3D90,$3D912C3D,$2C3D912C,$902A3D90,$3D912A3D, $2C3D902C,$2DEEED78,$262B9988,$2A3A903B,$8E2C3D90,$23712A3A,$1E26741C,$741E2674, $24741E26,$1C24711E,$761C2471,$FF62FDFB,$7C5100FF,$00180000,$24711C00,$1C24711C, $711C2471,$24741C24,$1C24741C,$741C2371,$24741C24,$1C24741C,$741C2474,$24711C24, $1C24711C,$40F1F07A,$2F30A89D,$1C247445,$711C2474,$13601C24,$12136210,$60101360, $13621013,$12136212,$60101360,$F8741013,$FFFF69FA,$007D5200,$00001300,$10136019, $62101360,$13621215,$12136212,$24101360,$06041901,$33120B26,$1A402711,$3517503B, $31200E49,$2CD5CA63,$0B109887,$10136029,$62121562,$05571213,$04055704,$57040557, $05570405,$04055704,$55040557,$05550402,$FFFF7C04,$00FFFF6F,$00008057,$16000012, $55040255,$05570402,$04055704,$34040557,$F5676E5D,$FAF46DF9,$72F9F36D,$F875F9F5, $FCFA73FB,$3BFCFA7C,$0209AA9F,$04025521,$57040557,$004E0405,$00004E00,$4E00004E, $004E0000,$00004E00,$4E00004E,$004E0000,$00004F00,$71FFFF7C,$5100FFFF,$1000007C, $4E100000,$004E0000,$00004F00,$4E00004E,$6B542F2D,$6C6B546C,$51716F57,$69506B69, $7877586C,$49F8F778,$0B10B4AD,$00004E28,$4E00004F,$00470000,$00004600,$47000047, $00470000,$00004700,$46000046,$00470000,$00004600,$7C000046,$FF7CFFFF,$B3961BFF, $00120000,$00461600,$00004700,$47000047,$00470000,$00004700,$47000047,$00470000, $00004600,$3BE1DF71,$060FA89C,$00004623,$47000047,$00400000,$00004000,$40000040, $00410000,$00004100,$41000041,$00410000,$00004100,$40000040,$FF820000,$FFFF96FF, $00CFB63A,$00001600,$00003D12,$40000040,$00410000,$00004100,$41000041,$00400000, $00004000,$33DFDD6E,$0004A093,$00004017,$40000041,$003A0000,$00003A00,$3B00003B, $003B0000,$00003B00,$3A00003A,$003A0000,$00003A00,$3A00003B,$003A0000,$D0D88800, $47FFFFB6,$0000DBC5,$07000012,$3A00003A,$003A0000,$00003A00,$3A00003A,$003A0000, $00003A00,$32E3E170,$00009F92,$00003B0F,$3B00003B,$00350000,$00003500,$35000035, $00350000,$00003500,$35000035,$00350000,$00003500,$35000035,$00340000,$00003400, $B6CCD383,$AD32FFFF,$0D0000C7,$34050000,$00350000,$00003500,$35000035,$00350000, $00003500,$33E6E573,$0000A293,$0000350C,$35000035,$00320000,$00003200,$32000032, $00320000,$00003200,$32000032,$00320000,$00003200,$2F00002F,$00320000,$00002F00, $7700002F,$FF9FC1C5,$CCB135FF,$0C120000,$002F0000,$00002F00,$32000032,$00320000, $00002F00,$3FE7E675,$0000ADA0,$00002F10,$2F000032,$002C0000,$00002D00,$2D00002D, $002D0000,$00002D00,$2C00002C,$002D0000,$00002D00,$2C00002C,$002C0000,$00002C00, $2C00002D,$C4770000,$FFFFABBE,$15D2BB38,$002D0200,$00002D00,$2D00002D,$002C0000, $00002C00,$46E7E675,$0006B2A7,$00002D19,$2D00002D,$00290000,$00002900,$29000029, $002C0000,$00002C00,$2C00002C,$00290000,$00002900,$29000029,$00290000,$00002900, $29000029,$00290000,$09073200,$3A525140,$00291010,$00002900,$2C00002C,$00290000, $00002900,$46E6E574,$010BB2A7,$0000291B,$29000029,$00260000,$00002700,$27000027, $00270000,$00002700,$27000027,$00260000,$00002600,$26000026,$00270000,$00002700, $27000027,$00270000,$00002700,$26000026,$00260000,$00002600,$27000027,$00260000, $00002600,$47E5E373,$0009B1A8,$00002619,$26000027,$00240000,$00002600,$26000026, $00240000,$00002400,$26000026,$00240000,$00002400,$26000026,$00240000,$00002400, $26000026,$00240000,$00002400,$26000026,$00240000,$00002400,$26000026,$00240000, $00002400,$4FEBEB7D,$0004BAB2,$00002414,$24000026,$00210000,$00002100,$24000024, $00210000,$00002100,$24000024,$00210000,$00002100,$24000024,$00240000,$00002400, $24000024,$00210000,$00002100,$21000021,$00240000,$00002400,$24000024,$00240000, $00002100,$3CD5D564,$0001A79D,$00002110,$24000024,$00210000,$00002100,$21000021, $00200000,$00002000,$20000020,$00210000,$00002100,$21000021,$00210000,$00002100, $21000021,$00200000,$00002000,$20000020,$00200000,$00002000,$21000021,$00210000, $00002000,$39E0E068,$0000A599,$0000200F,$20000021,$00200000,$00002000,$1E00001E, $00200000,$00002000,$1E00001E,$001E0000,$00001E00,$1E00001E,$00200000,$00002000, $20000020,$00200000,$00002000,$1E00001E,$00200000,$00002000,$20000020,$00200000, $00001E00,$38D9D967,$0000AB9C,$0000200C,$20000020,$001B0000,$00001E00,$1E00001E, $001E0000,$00001E00,$1E00001E,$001E0000,$00001E00,$1E00001E,$001E0000,$00001E00, $1E00001E,$001E0000,$00001E00,$1E00001E,$001E0000,$00001E00,$1E00001E,$001B0000, $00001B00,$2BD6D667,$0000867A,$00001E09,$1E00001E,$00000000,$00000000); {$ENDIF} implementation end. adlibtracker2-2.4.24/font/0000755000000000000000000000000013414571002013755 5ustar rootrootadlibtracker2-2.4.24/font/dumpfont.pas0000644000000000000000000001225313411003760016317 0ustar rootroot// 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 . uses DOS,AdT2data; const _font_file_header_data: array[0..9] of Dword = ( $0CD0083B8,$01110B810,$0B91000BB,$0D2330100,$0CD0128BD,$04C00B810,$0754C21CD,$073276550, $061686320,$074657372); 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 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 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; var f: File; t: Text; temp,temp2,temp3: Longint; offset: Longint; temps: String; buf: array[0..PRED(4096+40)] of Byte; procedure _invoke_error_1; begin WriteLn('Error writing FONT.COM'); HALT(1); end; procedure _invoke_error_2; begin WriteLn('Error reading FONT.COM'); HALT(2); end; procedure _invoke_error_3; begin WriteLn('Error writing FONT.DAT'); HALT(3); end; begin If (Upper(ParamStr(1)) = '/FONT') then begin {$i-} Assign(f,'font.com'); SetFAttr(f,ARCHIVE); Rewrite(f,1); {$i+} If (IOresult <> 0) then _invoke_error_1; BlockWrite(f,_font_file_header_data,40,temp); If (temp <> 40) then _invoke_error_1; BlockWrite(f,font8x16,4096,temp); If (temp <> 4096) then _invoke_error_1; {$i-} Close(f); {$i+} If (IOresult <> 0) then _invoke_error_1; HALT(0); end; If (Upper(ParamStr(1)) = '/DATA') then begin {$i-} Assign(f,'font.com'); Reset(f,1); {$i+} If (IOresult <> 0) then _invoke_error_2; BlockRead(f,buf,SizeOf(buf),temp); If (FileSize(f) > 4096+40) or (temp < 4096+40) then _invoke_error_2; {$i-} Close(f); {$i+} If (IOresult <> 0) then _invoke_error_2; {$i-} Assign(t,'font.dat'); Rewrite(t); {$i+} If (IOresult <> 0) then _invoke_error_3; WriteLn(t,'const'); WriteLn(t,' font8x16: array[0..1023] of Dword = ('); offset := 40; For temp3 := 1 to 128 do begin Write(t,' '); For temp2 := 1 to 8 do begin temps := ''; For temp := 1 to 4 do begin temps := ExpStrL(Num2str(buf[offset],16),2,'0')+temps; Inc(offset); end; If (offset < 4096+40) then Write(t,'$'+temps+',') else Write(t,'$'+temps+');') end; WriteLn(t); end; {$i-} Close(t); {$i+} If (IOresult <> 0) then _invoke_error_3; HALT(0); end; WriteLn('Usage: DUMPFONT [/font] | [/data]'); end. adlibtracker2-2.4.24/font/FONT.DAT0000644000000000000000000002546113411003760015063 0ustar rootrootconst font8x16: array[0..1023] of Dword = ( $00000000,$00000000,$00000000,$00000000,$71300000,$313131F1,$FC313131,$00000000, $CD780000,$31190DCD,$FCCDC161,$00000000,$29CE0000,$2E292929,$C8282828,$00000000, $19080000,$FDD97939,$3C191919,$00000000,$00000000,$06361C00,$BE32180C,$00000000, $00000000,$18181F00,$9E33031E,$00000000,$00000000,$28440000,$44281010,$00000000, $E7E70000,$E7E7E7E7,$E7E7E7E7,$000000E7,$FFFF0000,$C3C7CFDF,$FFDFCFC7,$000000FF, $38100000,$1010107C,$10387C10,$00000000,$00000000,$7E7E7E3C,$00003C7E,$00000000, $991F0000,$1818385F,$70793A1C,$00000000,$191F0000,$1818181F,$70783818,$00000000, $55555500,$55555555,$55555555,$00000055,$7F7F7F00,$7F7F7F7F,$7F7F7F7F,$0000007F, $60400000,$7E7C7870,$6070787C,$00000040,$06020000,$7E3E1E0E,$060E1E3E,$00000002, $38100000,$1010107C,$10001000,$00000000,$82FE0000,$32128282,$3070FE72,$00000010, $00000000,$AA000000,$00000000,$00000000,$28140000,$50505050,$14285050,$00000000, $14280000,$0A0A0A0A,$28140A0A,$00000000,$00100000,$10100010,$10387C10,$00000000, $38100000,$1010107C,$10101010,$00000000,$10100000,$10101010,$10387C10,$00000000, $00000000,$FF0E0C08,$00080C0E,$00000000,$00000000,$FF703010,$00103070,$00000000, $00000000,$3C3C1800,$00000018,$00000000,$F3FE0000,$81FFF3F3,$FF81FF81,$00000000, $00000000,$7C383810,$00FEFE7C,$00000000,$00000000,$7C7CFEFE,$00103838,$00000000, $00000000,$00000000,$00000000,$00000000,$3C180000,$18183C3C,$18180018,$00000000, $28282800,$00002828,$00000000,$00000000,$28000000,$28287C28,$28287C28,$00000000, $D67C1010,$167CD0D2,$7CD69616,$00001010,$00000000,$08C4C200,$86462010,$00000000, $6C380000,$DC76386C,$76CCCCCC,$00000000,$10101000,$00000020,$00000000,$00000000, $10080000,$20202020,$08102020,$00000000,$08100000,$04040404,$10080404,$00000000, $00000000,$FE385410,$00105438,$00000000,$00000000,$7C101000,$00001010,$00000000, $00000000,$00000000,$10101000,$00000020,$00000000,$7C000000,$00000000,$00000000, $00000000,$00000000,$10000000,$00000000,$00000000,$08040200,$80402010,$00000000, $6C380000,$D6D6C6C6,$386CC6C6,$00000000,$38180000,$18181878,$7E181818,$00000000, $C67C0000,$30180C06,$FEC6C060,$00000000,$C67C0000,$063C0606,$7CC60606,$00000000, $1C0C0000,$FECC6C3C,$1E0C0C0C,$00000000,$C0FE0000,$06FCC0C0,$7CC60606,$00000000, $60380000,$C6FCC0C0,$7CC6C6C6,$00000000,$C6FE0000,$180C0606,$30303030,$00000000, $C67C0000,$C67CC6C6,$7CC6C6C6,$00000000,$C67C0000,$067EC6C6,$780C0606,$00000000, $00000000,$00001000,$00001000,$00000000,$00000000,$00001000,$20101000,$00000000, $04000000,$40201008,$04081020,$00000000,$00000000,$00003C00,$0000003C,$00000000, $20000000,$02040810,$20100804,$00000000,$C67C0000,$18180CC6,$18180018,$00000000, $7C000000,$DEDEC6C6,$7CC0DCDE,$00000000,$38100000,$FEC6C66C,$C6C6C6C6,$00000000, $66FC0000,$667C6666,$FC666666,$00000000,$663C0000,$C0C0C0C2,$3C66C2C0,$00000000, $6CF80000,$66666666,$F86C6666,$00000000,$66FE0000,$68786862,$FE666260,$00000000, $66FE0000,$68786862,$F0606060,$00000000,$663C0000,$DEC0C0C2,$3A66C6C6,$00000000, $C6C60000,$C6FEC6C6,$C6C6C6C6,$00000000,$183C0000,$18181818,$3C181818,$00000000, $0C1E0000,$0C0C0C0C,$78CCCCCC,$00000000,$66E60000,$78786C66,$E666666C,$00000000, $60F00000,$60606060,$FE666260,$00000000,$EEC60000,$C6D6FEFE,$C6C6C6C6,$00000000, $E6C60000,$CEDEFEF6,$C6C6C6C6,$00000000,$C67C0000,$C6C6C6C6,$7CC6C6C6,$00000000, $66FC0000,$607C6666,$F0606060,$00000000,$C67C0000,$C6C6C6C6,$7CDED6C6,$00000E0C, $66FC0000,$6C7C6666,$E6666666,$00000000,$C67C0000,$0C3860C6,$7CC6C606,$00000000, $7E7E0000,$1818185A,$3C181818,$00000000,$C6C60000,$C6C6C6C6,$7CC6C6C6,$00000000, $C6C60000,$C6C6C6C6,$10386CC6,$00000000,$C6C60000,$D6D6C6C6,$6CEEFED6,$00000000, $C6C60000,$38387C6C,$C6C66C7C,$00000000,$66660000,$183C6666,$3C181818,$00000000, $C6FE0000,$30180C86,$FEC6C260,$00000000,$20380000,$20202020,$38202020,$00000000, $00000000,$20408000,$02040810,$00000000,$041C0000,$04040404,$1C040404,$00000000, $6C381000,$000000C6,$00000000,$00000000,$00000000,$00000000,$00000000,$0000FF00, $00081010,$00000000,$00000000,$00000000,$00000000,$7C0C7800,$76CCCCCC,$00000000, $60E00000,$666C7860,$7C666666,$00000000,$00000000,$C0C67C00,$7CC6C0C0,$00000000, $0C1C0000,$CC6C3C0C,$76CCCCCC,$00000000,$00000000,$FEC67C00,$7CC6C0C0,$00000000, $6C380000,$60F06064,$F0606060,$00000000,$00000000,$CCCC7600,$7CCCCCCC,$0078CC0C, $60E00000,$66766C60,$E6666666,$00000000,$18000000,$18183800,$3C181818,$00000000, $06000000,$06060E00,$06060606,$003C6666,$60E00000,$786C6660,$E6666C78,$00000000, $18380000,$18181818,$3C181818,$00000000,$00000000,$D6FEEC00,$C6D6D6D6,$00000000, $00000000,$6666DC00,$66666666,$00000000,$00000000,$C6C67C00,$7CC6C6C6,$00000000, $00000000,$6666DC00,$7C666666,$00F06060,$00000000,$CCCC7600,$7CCCCCCC,$001E0C0C, $00000000,$6676DC00,$F0606060,$00000000,$00000000,$60C67C00,$7CC60C38,$00000000, $30100000,$3030FC30,$1C363030,$00000000,$00000000,$CCCCCC00,$76CCCCCC,$00000000, $00000000,$66666600,$183C6666,$00000000,$00000000,$D6C6C600,$6CFED6D6,$00000000, $00000000,$386CC600,$C66C3838,$00000000,$00000000,$C6C6C600,$7EC6C6C6,$00F80C06, $00000000,$18CCFE00,$FEC66030,$00000000,$100C0000,$10601010,$0C101010,$00000000, $10100000,$10001010,$10101010,$00000000,$08300000,$08060808,$30080808,$00000000, $DC760000,$00000000,$00000000,$00000000,$023E0000,$12020202,$10307E32,$00000000, $00000000,$00000000,$00000000,$FF000000,$00000000,$00000000,$00000000,$FFFF0000, $00000000,$00000000,$00000000,$FFFFFF00,$00000000,$00000000,$00000000,$FFFFFFFF, $00000000,$00000000,$FF000000,$FFFFFFFF,$00000000,$00000000,$FFFF0000,$FFFFFFFF, $00000000,$00000000,$FFFFFF00,$FFFFFFFF,$00000000,$00000000,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFF0000,$FFFFFFFF,$FFFFFFFF, $00000000,$FFFFFF00,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FF000000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFF0000,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FFFFFF00,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$00FFFFFF, $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$0000FFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$000000FF, $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$00FFFFFF,$00000000, $FFFFFFFF,$FFFFFFFF,$0000FFFF,$00000000,$FFFFFFFF,$FFFFFFFF,$000000FF,$00000000, $FFFFFFFF,$FFFFFFFF,$00000000,$00000000,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $FFFFFFFF,$0000FFFF,$00000000,$00000000,$FFFFFFFF,$000000FF,$00000000,$00000000, $FFFFFFFF,$00000000,$00000000,$00000000,$00FFFFFF,$00000000,$00000000,$00000000, $0000FFFF,$00000000,$00000000,$00000000,$000000FF,$00000000,$00000000,$00000000, $10101010,$10101010,$10101010,$7C101010,$00000000,$0A110000,$110A0404,$00000000, $AACC0000,$AACAAAAA,$CCAAAAAA,$00000000,$AA4C0000,$4A8A8AAA,$4CAA2A2A,$00000000, $44EE0000,$44444444,$44444444,$00000000,$4AE40000,$4848484A,$444A4848,$00000000, $AAAA0000,$AAEEAAAA,$AAAAAAAA,$00000000,$00000000,$FFFFFF00,$80808000,$00808080, $00000000,$FFFFFF00,$A0A0A000,$00A0A0A0,$00000000,$FFFFFF00,$A8A8A800,$00A8A8A8, $00000000,$FFFFFF00,$AAAAAA00,$00AAAAAA,$10101010,$FFFFFF10,$AAAAAA00,$00AAAAAA, $00000000,$60606000,$7E606060,$00000000,$00000000,$C6C6FC00,$C6C6CCFC,$00000000, $00100015,$1C0C0010,$0C7E6C3C,$001E0C0C,$96959566,$10006494,$10001000,$00001500, $90900000,$F7F09090,$97949291,$00000000,$00100010,$38000010,$00003838,$00000000, $44114411,$44114411,$44114411,$44114411,$AA55AA55,$AA55AA55,$AA55AA55,$AA55AA55, $77DD77DD,$77DD77DD,$77DD77DD,$77DD77DD,$10101010,$10101010,$10101010,$10101010, $10101010,$F0101010,$10101010,$10101010,$10101010,$F0F0F010,$10101010,$10101010, $3C3C3C3C,$FC3C3C3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FC000000,$3C3C3C3C,$3C3C3C3C, $00000000,$F0F0F000,$10101010,$10101010,$3C3C3C3C,$FCFCFC3C,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FCFCFC00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$FCFCFC3C,$00000000,$00000000,$3C3C3C3C,$FC3C3C3C,$00000000,$00000000, $10101010,$F0F0F010,$00000000,$00000000,$00000000,$F0000000,$10101010,$10101010, $10101010,$1F101010,$00000000,$00000000,$10101010,$FF101010,$00000000,$00000000, $00000000,$FF000000,$10101010,$10101010,$10101010,$1F101010,$10101010,$10101010, $00000000,$FF000000,$00000000,$00000000,$10101010,$FF101010,$10101010,$10101010, $10101010,$1F1F1F10,$10101010,$10101010,$3C3C3C3C,$3F3C3C3C,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3F3F3F3C,$00000000,$00000000,$00000000,$3F3F3F00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$FFFFFF3C,$00000000,$00000000,$00000000,$FFFFFF00,$3C3C3C3C,$3C3C3C3C, $3C3C3C3C,$3F3F3F3C,$3C3C3C3C,$3C3C3C3C,$00000000,$FFFFFF00,$00000000,$00000000, $3C3C3C3C,$FFFFFF3C,$3C3C3C3C,$3C3C3C3C,$10101010,$FFFFFF10,$00000000,$00000000, $3C3C3C3C,$FF3C3C3C,$00000000,$00000000,$00000000,$FFFFFF00,$10101010,$10101010, $00000000,$FF000000,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$3F3C3C3C,$00000000,$00000000, $10101010,$1F1F1F10,$00000000,$00000000,$00000000,$1F1F1F00,$10101010,$10101010, $00000000,$3F000000,$3C3C3C3C,$3C3C3C3C,$3C3C3C3C,$FF3C3C3C,$3C3C3C3C,$3C3C3C3C, $10101010,$FFFFFF10,$10101010,$10101010,$10101010,$F0101010,$00000000,$00000000, $00000000,$1F000000,$10101010,$10101010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $00000000,$FF000000,$FFFFFFFF,$FFFFFFFF,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0,$F0F0F0F0, $0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$0F0F0F0F,$FFFFFFFF,$00FFFFFF,$00000000,$00000000, $00100010,$00920010,$00100010,$00920010,$00100010,$00920010,$00100010,$FF100010, $00100010,$00920010,$00100010,$FFFF0010,$00100010,$00920010,$00100010,$FFFFFF10, $00100010,$00920010,$00100010,$FFFFFFFF,$00100010,$00920010,$FF100010,$FFFFFFFF, $00100010,$00920010,$FFFF0010,$FFFFFFFF,$00100010,$00920010,$FFFFFF10,$FFFFFFFF, $00100010,$00920010,$FFFFFFFF,$FFFFFFFF,$00100010,$FF920010,$FFFFFFFF,$FFFFFFFF, $00100010,$FFFF0010,$FFFFFFFF,$FFFFFFFF,$00100010,$FFFFFF10,$FFFFFFFF,$FFFFFFFF, $00100010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FF100010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $FFFF0010,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFF10,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF, $01010101,$01010101,$01010101,$01010101,$10000000,$10101010,$10101010,$00000000, $00000000,$FF000000,$00100010,$00920010,$00100010,$FF100010,$00000000,$00000000, $18783818,$10081C1A,$00000020,$00000000,$186C6C38,$10087C32,$00000020,$00000000, $00100010,$00100010,$00100010,$00100010,$00010001,$00010001,$00010001,$00010001, $00100015,$00100010,$00100010,$00100010,$00000000,$28281000,$00001028,$00000000, $00000000,$10000000,$00000000,$00000000,$03010000,$CC040602,$307058C8,$00000000, $3E1C0800,$FFFFFF7F,$00000000,$00000000,$00000000,$FFFFFF00,$081C3E7F,$00000000, $00000000,$7C7C7C7C,$007C7C7C,$00000000,$00000000,$00000000,$00000000,$00000000); adlibtracker2-2.4.24/font/font.com0000644000000000000000000001005013411003760015415 0ustar rootroot¸Í¸»¹3Ò½(͸LÍ!LuPe's charset0qñ111111üxÍÍ 1aÁÍüÎ)))).(((È9yÙý<6 2¾3žD((DçççççççççççÿÿßÏÇÃÇÏßÿÿ8||8<~~~~<™_8:yp8xpUUUUUUUUUUUU@`px|~|xp`@>~>8|þ‚‚‚2rþp0ª(PPPPPP(( (|88||8 ÿ 0pÿp0<<þóóóÿÿÿ88||þþþþ||88<<<(((((((|(((|((|ÖÒÐ|–Ö|ÂÄ F†8ll8vÜÌÌÌv  T8þ8T| | @€8lÆÆÖÖÆÆl88x~|Æ 0`ÀÆþ|Æ<Æ| 2~0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ|  ̪ªªÊªªªªÌLªªŠŠJ**ªLîDDDDDDDDDäJJHHHHHJDªªªªîªªªªªÿÿÿ€€€€€€ÿÿÿ      ÿÿÿ¨¨¨¨¨¨ÿÿÿªªªªªªÿÿÿªªªªªª``````~üÆÆüÌÆÆ ÿÿÿÿÿÿ>|||||||adlibtracker2-2.4.24/iloadins.inc0000644000000000000000000014451013411003760015307 0ustar rootroot// 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_standard_instrument_alt(var data); procedure import_fin_instrument_alt(var data); procedure import_hsc_instrument_alt(var data); procedure import_sat_instrument_alt(var data); procedure a2i_file_loader_alt(fname: String); procedure a2f_file_loader_alt(fname: String); procedure cif_file_loader_alt(fname: String); procedure fin_file_loader_alt(fname: String); procedure ins_file_loader_alt(fname: String); procedure sbi_file_loader_alt(fname: String); procedure sgi_file_loader_alt(fname: String); procedure import_instrument_from_data_record; procedure import_sbi_instrument_alt(var data); procedure test_instrument_alt(chan: Byte; fkey: Word; loadMacros: Boolean; bankSelector: Boolean; loadArpVib: Boolean; test_ins1,test_ins2: Byte); procedure test_instrument_alt2(chan: Byte; fkey: Word); procedure fselect_external_proc; } procedure import_standard_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_standard_instrument_alt'; {$ENDIF} With temp_instrument 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; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure import_fin_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_fin_instrument_alt'; {$ENDIF} With temp_instrument 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; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure import_hsc_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_hsc_instrument_alt'; {$ENDIF} With temp_instrument 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; temp_instrument.panning := 0; temp_instrument.fine_tune := pBYTE(@data)[11] SHR 4; end; procedure import_sat_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_sat_instrument_alt'; {$ENDIF} With temp_instrument 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; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure a2i_file_loader_alt(fname: String); type tOLD_HEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Byte; end; type tHEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Word; end; const id = '_A2ins_'; var f: File; header: tOLD_HEADER; header2: tHEADER; temp,temp2: Longint; crc: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:a2i_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); 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.ffver in [1..FFVER_A2I]) then begin CloseF(f); EXIT; end; If (header.ffver in [1..4]) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf2,header.b0len,crc); If (crc <> header.crc16) then begin CloseF(f); EXIT; end; Case header.ffver of 4: Move(buf2,buf3,header.b0len); 3: LZSS_decompress(buf2,buf3,header.b0len); 2: LZW_decompress(buf2,buf3); 1: SIXPACK_decompress(buf2,buf3,header.b0len); end; Move(buf3,temp_instrument,SizeOf(temp_instrument)); temp_instrument.panning := 0; end; If (header.ffver in [5..8]) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf2,header.b0len,crc); If (crc <> header.crc16) then begin CloseF(f); EXIT; end; Case header.ffver of 8: Move(buf2,buf3,header.b0len); 7: LZSS_decompress(buf2,buf3,header.b0len); 6: LZW_decompress(buf2,buf3); 5: SIXPACK_decompress(buf2,buf3,header.b0len); end; Move(buf3,temp_instrument,SizeOf(temp_instrument)); end; If (header.ffver = 9) 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; BlockReadF(f,buf2,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; crc := WORD_NULL; crc := Update16(header2.b0len,1,crc); crc := Update16(buf2,header2.b0len,crc); If (crc <> header2.crc16) then begin CloseF(f); EXIT; end; APACK_decompress(buf2,buf3); Move(buf3,temp_instrument,SizeOf(temp_instrument)); end; If (header.ffver = FFVER_A2I) 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; BlockReadF(f,buf2,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); EXIT; end; crc := WORD_NULL; crc := Update16(header2.b0len,1,crc); crc := Update16(buf2,header2.b0len,crc); If (crc <> header2.crc16) then begin CloseF(f); EXIT; end; progress_num_steps := 0; temp := 0; temp2 := LZH_decompress(buf2,buf3,header2.b0len); Move(buf3[temp],temp_instrument,SizeOf(temp_instrument)); Inc(temp,SizeOf(temp_instrument)); // instrument data Inc(temp,SUCC(buf3[temp])); // instrument name If (temp < temp2) then // more data present => 4op instrument begin Move(temp_instrument,temp_instrument2,SizeOf(temp_instrument2)); Move(buf3[temp],temp_instrument,SizeOf(temp_instrument)); Inc(temp,SizeOf(temp_instrument)); end; end; CloseF(f); load_flag_alt := 1; end; procedure a2f_file_loader_alt(fname: String); type tHEADER = Record ident: array[1..18] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; const id = '_a2ins_w/fm-macro_'; var f: File; header: tHEADER; crc,temp,temp2: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:a2f_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); FillChar(temp_instrument_macro,SizeOf(temp_instrument_macro),0); FillChar(temp_instrument_dis_fmreg_col,SizeOf(temp_instrument_dis_fmreg_col),0); {$i-} Assign(f,fname); 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.ffver in [1..FFVER_A2F]) then begin CloseF(f); EXIT; end; If (header.ffver = 1) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,1,crc); crc := Update32(buf2,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); EXIT; end; APACK_decompress(buf2,buf3); Move(buf3,temp_instrument,SizeOf(temp_instrument)); Move(buf3[SizeOf(songdata.instr_data[current_inst])+ buf3[SizeOf(songdata.instr_data[current_inst])]+1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(buf3[SizeOf(songdata.instr_data[current_inst])+ buf3[SizeOf(songdata.instr_data[current_inst])]+1+ SizeOf(songdata.instr_macros[current_inst])], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); end; If (header.ffver = FFVER_A2F) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,1,crc); crc := Update32(buf2,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); EXIT; end; progress_num_steps := 0; temp := 0; temp2 := LZH_decompress(buf2,buf3,header.b0len); Move(buf3[temp],temp_instrument,SizeOf(temp_instrument)); Inc(temp,SizeOf(temp_instrument)); // instrument data Inc(temp,SUCC(buf3[temp])); // instrument name Move(buf3[temp],temp_instrument_macro, SizeOf(temp_instrument_macro)); Inc(temp,SizeOf(temp_instrument_macro)); // instrument macro Move(buf3[temp],temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); Inc(temp,SizeOf(temp_instrument_dis_fmreg_col)); // disabled FM-macro columns If (temp < temp2) then // more data present => 4op instrument begin Move(temp_instrument,temp_instrument2,SizeOf(temp_instrument2)); Move(temp_instrument_macro,temp_instrument_macro2,SizeOf(temp_instrument_macro2)); Move(temp_instrument_dis_fmreg_col,temp_instrument_dis_fmreg_col2,SizeOf(temp_instrument_dis_fmreg_col2)); Move(buf3[temp],temp_instrument,SizeOf(temp_instrument)); Inc(temp,SizeOf(temp_instrument)); Inc(temp,SUCC(buf3[temp])); Move(buf3[temp],temp_instrument_macro, SizeOf(temp_instrument_macro)); Inc(temp,SizeOf(temp_instrument_macro)); Move(buf3[temp],temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); end; end; CloseF(f); load_flag_alt := 1; end; procedure cif_file_loader_alt(fname: String); const id = ''+#26; type tCIF_DATA = Record ident: array[1..20] of Char; idata: tFM_INST_DATA; resrv: Byte; iname: array[1..20] of Char; end; var f: File; buffer: tCIF_DATA; temp: Longint; const MIN_CIF_SIZE = SizeOf(buffer.ident)+ SizeOf(buffer.idata)+ SizeOf(buffer.resrv); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:cif_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If NOT ((temp >= MIN_CIF_SIZE) and (buffer.ident = id)) then begin CloseF(f); EXIT; end; import_hsc_instrument_alt(buffer.idata); temp_instrument.fine_tune := 0; CloseF(f); load_flag_alt := 1; end; type tFIN_DATA = Record dname: array[1..12] of Char; iname: array[1..27] of Char; idata: tFM_INST_DATA; end; procedure fin_file_loader_alt(fname: String); var f: File; buffer: tFIN_DATA; temp: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:fin_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If (temp <> SizeOf(buffer)) then begin CloseF(f); EXIT; end; import_fin_instrument_alt(buffer.idata); CloseF(f); load_flag_alt := 1; end; procedure ins_file_loader_alt(fname: String); type tINS_DATA = Record idata: tFM_INST_DATA; slide: Byte; _SAdT: array[0..18] of Byte; end; var f: File; buffer: tINS_DATA; temp: Longint; function correct_ins(var data): Boolean; var result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:ins_file_loader_alt:correct_ins'; {$ENDIF} result := TRUE; If NOT (tADTRACK2_INS(data).fm_data.WAVEFORM_modulator in [0..3]) then result := FALSE; If NOT (tADTRACK2_INS(data).fm_data.WAVEFORM_carrier in [0..3]) then result := FALSE; If NOT (tADTRACK2_INS(data).fm_data.FEEDBACK_FM in [0..15]) then result := FALSE; correct_ins := result; end; begin { ins_file_loader_alt } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:ins_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; If (FileSize(f) > SizeOf(buffer)) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,FileSize(f),temp); If (temp <> FileSize(f)) then begin CloseF(f); EXIT; end; Case force_ins of 0: begin If (temp = 12) then import_standard_instrument_alt(buffer.idata); If (temp = 12) and NOT correct_ins(buffer.idata) then import_hsc_instrument_alt(buffer.idata) else If (temp > 12) then import_sat_instrument_alt(buffer.idata); end; 1: import_hsc_instrument_alt(buffer.idata); 2: import_sat_instrument_alt(buffer.idata); 3: import_standard_instrument_alt(buffer.idata); end; CloseF(f); load_flag_alt := 1; end; procedure sbi_file_loader_alt(fname: String); const id = 'SBI'+#26; type tSBI_DATA = Record ident: array[1..4] of Char; iname: array[1..32] of Char; idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; var f: File; buffer: tSBI_DATA; temp: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:sbi_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If NOT ((temp = SizeOf(buffer)) and (buffer.ident = id)) then begin CloseF(f); EXIT; end; import_standard_instrument_alt(buffer.idata); CloseF(f); load_flag_alt := 1; end; procedure sgi_file_loader_alt(fname: String); type tSGI_DATA = Record { 0} attack_m, { 1} decay_m, { 2} sustain_m, { 3} release_m, { 4} waveform_m, { 5} mfmult_m, { 6} ksl_m, { 7} volume_m, { 8} ksr_m, { 9} tremolo_m, {10} vibrato_m, {11} eg_type_m, {12} attack_c, {13} decay_c, {14} sustain_c, {15} release_c, {16} waveform_c, {17} mfmult_c, {18} ksl_c, {19} volume_c, {20} ksr_c, {21} tremolo_c, {22} vibrato_c, {23} eg_type_c, {24} feedback, {25} fm: Byte; end; var f: File; buffer: tSGI_DATA; temp: Longint; procedure import_sgi_instrument(inst: Byte; var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:sgi_file_loader_alt:import_sgi_instrument'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); With temp_instrument do begin fm_data.ATTCK_DEC_modulator := (pBYTE(@data)[1] AND $0f)+ (pBYTE(@data)[0] AND $0f) SHL 4; fm_data.SUSTN_REL_modulator := (pBYTE(@data)[3] AND $0f)+ (pBYTE(@data)[2] AND $0f) SHL 4; fm_data.WAVEFORM_modulator := (pBYTE(@data)[4] AND 3); fm_data.KSL_VOLUM_modulator := (pBYTE(@data)[7] AND $3f)+ (pBYTE(@data)[6] AND 3) SHL 6; fm_data.AM_VIB_EG_modulator := (pBYTE(@data)[5] AND $0f)+ (pBYTE(@data)[8] AND 1) SHL 4+ (pBYTE(@data)[11] AND 1) SHL 5+ (pBYTE(@data)[10] AND 1) SHL 6+ (pBYTE(@data)[9] AND 1) SHL 7; fm_data.ATTCK_DEC_carrier := (pBYTE(@data)[13] AND $0f)+ (pBYTE(@data)[12] AND $0f) SHL 4; fm_data.SUSTN_REL_carrier := (pBYTE(@data)[15] AND $0f)+ (pBYTE(@data)[14] AND $0f) SHL 4; fm_data.WAVEFORM_carrier := (pBYTE(@data)[16] AND 3); fm_data.KSL_VOLUM_carrier := (pBYTE(@data)[19] AND $3f)+ (pBYTE(@data)[18] AND 3) SHL 6; fm_data.AM_VIB_EG_carrier := (pBYTE(@data)[17] AND $0f)+ (pBYTE(@data)[20] AND 1) SHL 4+ (pBYTE(@data)[23] AND 1) SHL 5+ (pBYTE(@data)[22] AND 1) SHL 6+ (pBYTE(@data)[21] AND 1) SHL 7; fm_data.FEEDBACK_FM := (pBYTE(@data)[25] AND 1)+ (pBYTE(@data)[24] AND 7) SHL 1; end; end; begin { sgi_file_loader_alt } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:sgi_file_loader_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); {$i-} Assign(f,fname); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If (temp <> SizeOf(buffer)) then begin CloseF(f); EXIT; end; import_sgi_instrument(current_inst,buffer); CloseF(f); load_flag_alt := 1; end; procedure import_sbi_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:import_sbi_instrument_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); With temp_instrument 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; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure ibk_file_loader_alt(instr: Word); const id = 'IBK'+#26; var f: File; header: array[1..4] of Char; temp: Longint; instrument_data: Record idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:ibk_file_loader_alt'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header <> id) then begin CloseF(f); EXIT; end; SeekF(f,$004+PRED(instr)*SizeOf(instrument_data)); If (IOresult <> 0) then EXIT; BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); EXIT; end; import_sbi_instrument_alt(instrument_data); CloseF(f); load_flag_alt := 1; end; var ins__fmreg_table_backup: tREGISTER_TABLE; ins__fmreg_table_backup2: tREGISTER_TABLE; ins__dis_fmreg_col_backup: tDIS_FMREG_COL; ins__dis_fmreg_col_backup2: tDIS_FMREG_COL; arp_vib_macro_table_backup: tARP_VIB_MACRO_TABLE; chan_handle: array[1..20] of Byte; procedure test_instrument_alt(chan: Byte; fkey: Word; loadMacros: Boolean; bankSelector: Boolean; loadArpVib: Boolean; test_ins1,test_ins2: Byte); var temp,temp2,temp3,temp5: Byte; valid_key,temp4: Boolean; temps: String; channels: Byte; function output_note(chan,board_pos: Byte): Boolean; var note: Byte; freq: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:test_instrument_alt:output_note'; {$ENDIF} note := board_pos+12*(current_octave-1); If NOT (note in [0..12*8+1]) then begin output_note := FALSE; EXIT; end; chan_handle[chan] := board_scancodes[board_pos]; If (test_ins2 <> 0) then chan := _4op_main_chan[chan]; load_instrument(temp_instrument,chan); If percussion_mode and (temp_instrument.perc_voice in [4,5]) then load_instrument(temp_instrument,_perc_sim_chan[chan]); If (test_ins2 <> 0) then load_instrument(temp_instrument2,PRED(chan)); macro_speedup := songdata.macro_speedup; If (play_status = isStopped) then update_timer(songdata.tempo); freq := nFreq(note-1)+$2000+ SHORTINT(pBYTE(@Addr(temp_instrument)^)[12]); event_table[chan].note := note; freq_table[chan] := freq; freqtable2[chan] := freq; key_on(chan); change_freq(chan,freq); If (test_ins2 = 0) then init_macro_table(chan,note,test_ins1,freq) else begin init_macro_table(chan,note,test_ins1,freq); freq_table[PRED(chan)] := freq; freqtable2[PRED(chan)] := freq; init_macro_table(PRED(chan),note,test_ins2,freq); end; end; begin { test_instrument_alt } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:test_instrument_alt'; {$ENDIF} valid_key := FALSE; For temp := 1 to 29 do If NOT shift_pressed then If (board_scancodes[temp] = HI(fkey)) then begin valid_key := TRUE; BREAK; end; If scankey(SC_F7) then For temp := 1 to 20 do reset_chan_data(temp); If NOT valid_key or NOT (temp+12*(current_octave-1)-1 in [0..12*8+1]) then EXIT; If NOT percussion_mode then channels := 18 else channels := 15; FillChar(temp_instrument,SizeOf(temp_instrument),0); FillChar(temp_instrument2,SizeOf(temp_instrument2),0); temp2 := temp; If bankSelector or loadArpVib then If NOT loadArpVib then begin temps := ''; load_flag_alt := BYTE_NULL; If (test_ins2 = 0) then begin Move(temp_songdata.instr_data[test_ins1], temp_instrument, SizeOf(temp_instrument)); Move(temp_songdata.instr_macros[test_ins1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(temp_songdata.dis_fmreg_col[test_ins1], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); end else begin Move(temp_songdata.instr_data[test_ins1], temp_instrument, SizeOf(temp_instrument)); Move(temp_songdata.instr_macros[test_ins1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(temp_songdata.dis_fmreg_col[test_ins1], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); Move(temp_songdata.instr_data[test_ins2], temp_instrument2, SizeOf(temp_instrument2)); Move(temp_songdata.instr_macros[test_ins2], temp_instrument_macro2, SizeOf(temp_instrument_macro2)); Move(temp_songdata.dis_fmreg_col[test_ins2], temp_instrument_dis_fmreg_col2, SizeOf(temp_instrument_dis_fmreg_col2)); end; end else begin load_flag_alt := BYTE_NULL; If (test_ins2 = 0) then begin Move(songdata.instr_data[test_ins1], temp_instrument, SizeOf(temp_instrument)); Move(songdata.instr_macros[test_ins1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(songdata.dis_fmreg_col[test_ins1], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); end else begin Move(songdata.instr_data[test_ins1], temp_instrument, SizeOf(temp_instrument)); Move(songdata.instr_macros[test_ins1], temp_instrument_macro, SizeOf(temp_instrument_macro)); Move(songdata.dis_fmreg_col[test_ins1], temp_instrument_dis_fmreg_col, SizeOf(temp_instrument_dis_fmreg_col)); Move(songdata.instr_data[test_ins2], temp_instrument2, SizeOf(temp_instrument2)); Move(songdata.instr_macros[test_ins2], temp_instrument_macro2, SizeOf(temp_instrument_macro2)); Move(songdata.dis_fmreg_col[test_ins2], temp_instrument_dis_fmreg_col2, SizeOf(temp_instrument_dis_fmreg_col2)); end; end else begin temps := mn_environment.curr_item; load_flag_alt := BYTE_NULL; {$IFDEF GO32V2} keyboard_toggle_sleep; {$ENDIF} If (Lower(ExtOnly(temps)) = 'a2i') then a2i_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'a2f') then a2f_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'cif') then cif_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'fin') then fin_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'ins') then ins_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'sbi') then sbi_file_loader_alt(temps) else If (Lower(ExtOnly(temps)) = 'sgi') then sgi_file_loader_alt(temps); {$IFDEF GO32V2} keyboard_toggle_sleep; {$ENDIF} If (load_flag_alt = BYTE_NULL) then EXIT; end; If (test_ins2 <> 0) and Empty(temp_instrument2,SizeOf(temp_instrument2)) and Empty(temp_instrument_macro2,SizeOf(temp_instrument_macro2)) then test_ins2 := 0; Move(songdata.macro_table, arp_vib_macro_table_backup, SizeOf(arp_vib_macro_table_backup)); If loadArpVib then begin If arp_tab_selected then begin temp_instrument_macro.arpeggio_table := arpvib_arpeggio_table; Move(temp_songdata.macro_table[arpvib_arpeggio_table].arpeggio, songdata.macro_table[arpvib_arpeggio_table].arpeggio, SizeOf(songdata.macro_table[arpvib_arpeggio_table])); end else temp_instrument_macro.arpeggio_table := 0; If vib_tab_selected then begin temp_instrument_macro.vibrato_table := arpvib_vibrato_table; Move(temp_songdata.macro_table[arpvib_vibrato_table].vibrato, songdata.macro_table[arpvib_vibrato_table].vibrato, SizeOf(songdata.macro_table[arpvib_vibrato_table])); end else temp_instrument_macro.vibrato_table := 0; If (test_ins2 = 0) then Move(temp_instrument_macro, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])) else begin Move(temp_instrument_macro, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(temp_instrument_macro2, songdata.instr_macros[test_ins2], SizeOf(songdata.instr_macros[test_ins2])); end; end else If bankSelector and loadMacros then begin If (temp_instrument_macro.arpeggio_table <> 0) then Move(temp_songdata.macro_table[temp_instrument_macro.arpeggio_table].arpeggio, songdata.macro_table[temp_instrument_macro.arpeggio_table].arpeggio, SizeOf(songdata.macro_table[temp_instrument_macro.arpeggio_table])); If (temp_instrument_macro.vibrato_table <> 0) then Move(temp_songdata.macro_table[temp_instrument_macro.vibrato_table].vibrato, songdata.macro_table[temp_instrument_macro.vibrato_table].vibrato, SizeOf(songdata.macro_table[temp_instrument_macro.vibrato_table])); end; If (Empty(temp_instrument,SizeOf(temp_instrument)) and Empty(temp_instrument_macro,SizeOf(temp_instrument_macro))) or ((test_ins2 <> 0) and Empty(temp_instrument2,SizeOf(temp_instrument2)) and Empty(temp_instrument_macro2,SizeOf(temp_instrument_macro2))) then EXIT; ins_trailing_flag := TRUE; status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; really_no_status_refresh := TRUE; reset_player; If (Lower(ExtOnly(temps)) = 'a2f') or loadMacros or loadArpVib then If (test_ins2 = 0) then begin Move(songdata.instr_macros[test_ins1], ins__fmreg_table_backup, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins1], ins__dis_fmreg_col_backup, SizeOf(ins__dis_fmreg_col_backup)); Move(temp_instrument_macro, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(temp_instrument_dis_fmreg_col, songdata.dis_fmreg_col[test_ins1], SizeOf(songdata.dis_fmreg_col[test_ins1])); end else begin Move(songdata.instr_macros[test_ins1], ins__fmreg_table_backup, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins1], ins__dis_fmreg_col_backup, SizeOf(ins__dis_fmreg_col_backup)); Move(temp_instrument_macro, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(temp_instrument_dis_fmreg_col, songdata.dis_fmreg_col[test_ins1], SizeOf(songdata.dis_fmreg_col[test_ins1])); Move(songdata.instr_macros[test_ins2], ins__fmreg_table_backup2, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins2], ins__dis_fmreg_col_backup2, SizeOf(ins__dis_fmreg_col_backup)); Move(temp_instrument_macro2, songdata.instr_macros[test_ins2], SizeOf(songdata.instr_macros[test_ins2])); Move(temp_instrument_dis_fmreg_col2, songdata.dis_fmreg_col[test_ins2], SizeOf(songdata.dis_fmreg_col[test_ins2])); end else begin Move(songdata.instr_macros[test_ins1], ins__fmreg_table_backup, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins1], ins__dis_fmreg_col_backup, SizeOf(ins__dis_fmreg_col_backup)); FillChar(songdata.instr_macros[test_ins1],SizeOf(songdata.instr_macros[test_ins1]),0); FillChar(songdata.dis_fmreg_col[test_ins1],SizeOf(songdata.dis_fmreg_col[test_ins1]),0); If (test_ins2 <> 0) then begin Move(songdata.instr_macros[test_ins2], ins__fmreg_table_backup2, SizeOf(ins__fmreg_table_backup)); Move(songdata.dis_fmreg_col[test_ins2], ins__dis_fmreg_col_backup2, SizeOf(ins__dis_fmreg_col_backup)); FillChar(songdata.instr_macros[test_ins2],SizeOf(songdata.instr_macros[test_ins2]),0); FillChar(songdata.dis_fmreg_col[test_ins2],SizeOf(songdata.dis_fmreg_col[test_ins2]),0); end; end; Move(channel_flag,channel_flag_backup,SizeOf(channel_flag_backup)); Move(event_table,event_table_backup,SizeOf(event_table_backup)); common_flag_backup := songdata.common_flag; volume_scaling_backup := volume_scaling; songdata.common_flag := songdata.common_flag AND NOT $80; volume_scaling := FALSE; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); Move(pan_lock,pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); flag_4op_backup := songdata.flag_4op; If NOT percussion_mode and NOT (songdata.flag_4op <> 0) then channels := 18 else If NOT (songdata.flag_4op <> 0) then channels := 15 else If (test_ins2 <> 0) then begin songdata.flag_4op := $3f; channels := 6; end else begin songdata.flag_4op := 0; If NOT percussion_mode then channels := 18 else channels := 15; end; reset_player; FillChar(chan_handle,SizeOf(chan_handle),0); Move(fmpar_table,fmpar_table_backup,SizeOf(fmpar_table_backup)); Move(volume_table,volume_table_backup,SizeOf(volume_table_backup)); Move(freq_table,freq_table_backup,SizeOf(freq_table)); Move(freqtable2,freqtable2_backup,SizeOf(freqtable2)); Move(keyoff_loop,keyoff_loop_backup,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); misc_register := current_tremolo_depth SHL 7+ current_vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; key_off(17); key_off(18); opl2out(_instr[11],misc_register); If percussion_mode and (temp_instrument.perc_voice in [1..5]) then begin output_note(temp_instrument.perc_voice+15,temp2); While scankey(board_scancodes[temp2]) do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; end else Repeat valid_key := FALSE; For temp := 1 to 29 do begin temp2 := board_scancodes[temp]; temp4 := scankey(temp2); If NOT ((songdata.flag_4op <> 0) and (test_ins2 <> 0)) then begin temp3 := get_chanpos(chan_handle,channels,temp2); temp5 := get_chanpos(chan_handle,channels,0); end else begin temp3 := get_chanpos2(chan_handle,channels,temp2); temp5 := get_chanpos2(chan_handle,channels,0); end; If temp4 then valid_key := TRUE; If temp4 and (temp3 = 0) and (temp5 <> 0) then output_note(temp5,temp); If NOT temp4 and (temp3 <> 0) then begin chan_handle[temp3] := 0; key_off(temp3); If alt_pressed then keyoff_loop[temp3] := TRUE; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; until NOT valid_key; While ctrl_pressed do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; For temp := 1 to 20 do key_off(temp); Move(ins__fmreg_table_backup, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(ins__dis_fmreg_col_backup, songdata.dis_fmreg_col[test_ins1], SizeOf(songdata.dis_fmreg_col[test_ins1])); If (test_ins2 <> 0) then begin Move(ins__fmreg_table_backup, songdata.instr_macros[test_ins1], SizeOf(songdata.instr_macros[test_ins1])); Move(ins__dis_fmreg_col_backup, songdata.dis_fmreg_col[test_ins1], SizeOf(songdata.dis_fmreg_col[test_ins1])); Move(ins__fmreg_table_backup2, songdata.instr_macros[test_ins2], SizeOf(songdata.instr_macros[test_ins2])); Move(ins__dis_fmreg_col_backup2, songdata.dis_fmreg_col[test_ins2], SizeOf(songdata.dis_fmreg_col[test_ins2])); end; Move(arp_vib_macro_table_backup, songdata.macro_table, SizeOf(songdata.macro_table)); songdata.flag_4op := flag_4op_backup; Move(fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(volume_table_backup,volume_table,SizeOf(volume_table)); Move(panning_table_backup,panning_table,SizeOf(panning_table)); songdata.common_flag := common_flag_backup; volume_scaling := volume_scaling_backup; If (status_backup.play_status = isPlaying) then reset_player; Move(channel_flag_backup,channel_flag,SizeOf(channel_flag)); Move(event_table_backup,event_table,SizeOf(event_table)); Move(pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(peak_lock_backup,peak_lock,SizeOf(volume_lock)); really_no_status_refresh := FALSE; Move(freq_table_backup,freq_table,SizeOf(freq_table)); Move(freqtable2_backup,freqtable2,SizeOf(freqtable2)); Move(keyoff_loop_backup,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; ins_trailing_flag := FALSE; keyboard_reset_buffer; end; procedure test_instrument_alt2(chan: Byte; fkey: Word); var temp,temp2,temp3,temp5: Byte; valid_key,temp4: Boolean; temps: String; channels: Byte; function output_note(chan,board_pos: Byte): Boolean; var note: Byte; freq: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:test_instrument_alt2:output_note'; {$ENDIF} note := board_pos+12*(current_octave-1); If NOT (note in [0..12*8+1]) then begin output_note := FALSE; EXIT; end; chan_handle[chan] := board_scancodes[board_pos]; load_instrument(temp_instrument,chan); If percussion_mode and (temp_instrument.perc_voice in [4,5]) then load_instrument(temp_instrument,_perc_sim_chan[chan]); freq := nFreq(note-1)+$2000+ SHORTINT(pBYTE(@Addr(temp_instrument)^)[12]); event_table[chan].note := note; freq_table[chan] := freq; freqtable2[chan] := freq; key_on(chan); change_freq(chan,freq); macro_speedup := songdata.macro_speedup; If (play_status = isStopped) then update_timer(songdata.tempo); freq_table[chan] := freq; freqtable2[chan] := freq; init_macro_table(chan,note,current_inst,freq); end; begin { test_instrument_alt2 } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:test_instrument_alt2'; {$ENDIF} valid_key := FALSE; For temp := 1 to 29 do If NOT shift_pressed then If (board_scancodes[temp] = HI(fkey)) then begin valid_key := TRUE; BREAK; end; If scankey(SC_F7) then For temp := 1 to 20 do reset_chan_data(temp); If NOT valid_key or NOT (temp+12*(current_octave-1)-1 in [0..12*8+1]) then EXIT; If NOT percussion_mode then channels := 18 else channels := 15; temp2 := temp; temps := mn_environment.curr_item; load_flag_alt := BYTE_NULL; If Empty(temp_instrument,SizeOf(temp_instrument)) then EXIT; {$IFDEF GO32V2} keyboard_toggle_sleep; {$ENDIF} If (Lower(ExtOnly(temps)) = 'bnk') then bnk_file_loader_alt(Str2num(BaseNameOnly(mn_environment.curr_item),10)) else If (Lower(ExtOnly(temps)) = 'fib') then fib_file_loader_alt(Str2num(BaseNameOnly(mn_environment.curr_item),10)) else If (Lower(ExtOnly(temps)) = 'ibk') then ibk_file_loader_alt(Str2num(BaseNameOnly(mn_environment.curr_item),10)); {$IFDEF GO32V2} keyboard_toggle_sleep; {$ENDIF} If (load_flag_alt = BYTE_NULL) then EXIT; ins_trailing_flag := TRUE; status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; really_no_status_refresh := TRUE; reset_player; Move(channel_flag,channel_flag_backup,SizeOf(channel_flag_backup)); Move(event_table,event_table_backup,SizeOf(event_table_backup)); common_flag_backup := songdata.common_flag; volume_scaling_backup := volume_scaling; songdata.common_flag := songdata.common_flag AND NOT $80; volume_scaling := FALSE; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); flag_4op_backup := songdata.flag_4op; If NOT percussion_mode and NOT (songdata.flag_4op <> 0) then channels := 18 else If NOT (songdata.flag_4op <> 0) then channels := 15 else begin songdata.flag_4op := 0; If NOT percussion_mode then channels := 18 else channels := 15; end; reset_player; FillChar(chan_handle,SizeOf(chan_handle),0); Move(pan_lock,pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); Move(fmpar_table,fmpar_table_backup,SizeOf(fmpar_table_backup)); Move(volume_table,volume_table_backup,SizeOf(volume_table_backup)); Move(freq_table,freq_table_backup,SizeOf(freq_table)); Move(freqtable2,freqtable2_backup,SizeOf(freqtable2)); Move(keyoff_loop,keyoff_loop_backup,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); misc_register := current_tremolo_depth SHL 7+ current_vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; key_off(17); key_off(18); opl2out(_instr[11],misc_register); If percussion_mode and (temp_instrument.perc_voice in [1..5]) then begin output_note(temp_instrument.perc_voice+15,temp2); While scankey(board_scancodes[temp2]) do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; end else Repeat valid_key := FALSE; For temp := 1 to 29 do begin temp2 := board_scancodes[temp]; temp3 := get_chanpos(chan_handle,channels,temp2); temp4 := scankey(temp2); temp5 := get_chanpos(chan_handle,channels,0); If temp4 then valid_key := TRUE; If temp4 and (temp3 = 0) and (temp5 <> 0) then output_note(temp5,temp); If NOT temp4 and (temp3 <> 0) then begin chan_handle[temp3] := 0; key_off(temp3); If alt_pressed then keyoff_loop[temp3] := TRUE; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; until NOT valid_key; While ctrl_pressed do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; For temp := 1 to 20 do key_off(temp); songdata.flag_4op := flag_4op_backup; Move(fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(volume_table_backup,volume_table,SizeOf(volume_table)); Move(panning_table_backup,panning_table,SizeOf(panning_table)); songdata.common_flag := common_flag_backup; volume_scaling := volume_scaling_backup; If (status_backup.play_status = isPlaying) then reset_player; Move(channel_flag_backup,channel_flag,SizeOf(channel_flag)); Move(event_table_backup,event_table,SizeOf(event_table)); Move(pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(peak_lock_backup,peak_lock,SizeOf(volume_lock)); really_no_status_refresh := FALSE; Move(freq_table_backup,freq_table,SizeOf(freq_table)); Move(freqtable2_backup,freqtable2,SizeOf(freqtable2)); Move(keyoff_loop_backup,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; ins_trailing_flag := FALSE; keyboard_reset_buffer; end; procedure fselect_external_proc; var test_ins1: Byte; test_ins2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADINS.INC:fselect_external_proc'; {$ENDIF} If (songdata.flag_4op <> 0) then begin If (current_inst < 255) then test_ins1 := current_inst else test_ins1 := PRED(current_inst); test_ins2 := SUCC(test_ins1); end else begin test_ins1 := current_inst; test_ins2 := 0; end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt(count_channel(pattern_hpos), mn_environment.keystroke, FALSE,FALSE,FALSE, test_ins1,test_ins2); end; adlibtracker2-2.4.24/adtrack2.pas0000644000000000000000000005126413411003760015215 0ustar rootroot// 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 AdLib_Tracker_II; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} {$IFDEF WINDOWS} {$APPTYPE GUI} {$R adtrack2.res} {$ENDIF} {$IFDEF GO32V2} uses CRT,GO32, AdT2opl3,AdT2unit,AdT2sys,AdT2extn,AdT2ext2,AdT2text,AdT2keyb,AdT2data,AdT2vesa, TxtScrIO,StringIO,DialogIO,ParserIO,MenuLib1,MenuLib2; const scan_addresses: array[1..7] of Word = ($388,$210,$220,$230,$240,$250,$260); var fade_buf,fade_buf2: tFADE_BUF; temp,index: Word; mem_info: tMemInfo; free_mem: Longint; opl3detected: Boolean; dos_dir: String; mouse_sx,mouse_sy,mouse_sd: Word; procedure LoadFont(var font_data); var regs: tRealRegs; dos_sel,dos_seg: Word; dos_mem_adr: Dword; begin dos_mem_adr := global_dos_alloc(4096); dos_sel := WORD(dos_mem_adr); dos_seg := WORD(dos_mem_adr SHR 16); dosmemput(dos_seg,0,font_data,4096); FillChar(regs,SizeOf(regs),0); regs.ax := $1100; regs.bh := 16; regs.bl := 0; regs.es := dos_seg; regs.ds := dos_seg; regs.bp := 0; regs.cx := 256; regs.dx := 0; RealIntr($10,regs); global_dos_free(dos_sel); end; function mouse_driver_installed: Boolean; const iret = $0cf; var driver_ofs,driver_seg: Word; begin driver_ofs := MEMW[0:$0cc]; driver_seg := MEMW[0:$0ce]; If (driver_seg <> 0) and (driver_ofs <> 0) and (MEM[driver_seg:driver_ofs] <> iret) then mouse_driver_installed := TRUE else mouse_driver_installed := FALSE; end; var old_exit_proc: procedure; procedure new_exit_proc; begin ExitProc := @old_exit_proc; If mouse_active then asm mov ax,1ah mov bx,mouse_sx mov cx,mouse_sy mov dx,mouse_sd int 33h end; If (ExitCode <> 0) then begin asm mov ax,03h; xor bh,bh; int 10h end; WriteLn(prog_exception_title); WriteLn('PROGRAM VERSION: ',at2ver,' from ',at2date,', ',at2link); WriteLn('ERROR_ID #'+Num2str(ExitCode,10)+' at '+ExpStrL(Num2str(LONGINT(ErrorAddr),16),8,'0')); WriteLn('STEP #1 -> ',_last_debug_str_); WriteLn('STEP #2 -> ',_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! :-)'); WriteLn; WriteLn; reset_player; sys_done; If (pattdata <> NIL) then FreeMem(pattdata,PATTERN_SIZE*max_patterns); ErrorAddr := NIL; HALT(ExitCode); end; end; procedure halt_startup(exitcode: Byte); begin sys_done; If (pattdata <> NIL) then FreeMem(pattdata,PATTERN_SIZE*max_patterns); ExitProc := @old_exit_proc; If (dos_dir <> '') then ChDir(dos_dir); HALT(exitcode); end; {$ELSE} uses SDL_Timer, AdT2sys,AdT2keyb,AdT2opl3,AdT2unit,AdT2extn,AdT2ext2,AdT2ext3,AdT2text,AdT2data, StringIO,DialogIO,ParserIO,TxtScrIO,MenuLib1,MenuLib2; var temp: Longint; {$ENDIF} begin { MAIN } {$IFDEF GO32V2} @old_exit_proc := ExitProc; ExitProc := @new_exit_proc; {$i-} GetDir(0,dos_dir); {$i+} If (IOresult <> 0) then dos_dir := ''; ShowStartMessage; { init system things } sys_init; For index := 1 to ParamCount do If (Lower(ParamStr(index)) = '/debug') then _debug_ := TRUE; If _debug_ then WriteLn('-------- DEBUG --------'); If _debug_ then WriteLn('--- detecting available dos memory'); asm mov bx,0ffffh mov ah,48h int 21h mov dos_memavail,bx end; If (dos_memavail*16 DIV 1024 < 120) then begin WriteLn('ERROR(1) - Insufficient DOS memory!'); halt_startup(1); end; If _debug_ then WriteLn('--- detecting total available memory'); Get_MemInfo(mem_info); free_mem := mem_info.available_memory; If _debug_ then WriteLn('--- ## ',free_mem/1024/1000:0:2,'MB found'); If NOT (free_mem DIV 1024 > 5*1024) then begin WriteLn('ERROR(1) - Insufficient memory!'); halt_startup(1); end; temp := 128; Repeat If (free_mem > PATTERN_SIZE*temp) then begin max_patterns := temp; BREAK; end else If (temp-16 >= 16) then Dec(temp,16) else begin WriteLn('ERROR(1) - Insufficient memory!'); halt_startup(1); end; until FALSE; { allocate memory for patterns } If _debug_ then WriteLn('--- allocating frame buffer for patterns'); GetMem(pattdata,PATTERN_SIZE*max_patterns); If NOT iVGA then begin WriteLn('ERROR(2) - Insufficient video equipment!'); halt_startup(2); end; If (max_patterns <> $80) then WriteLn('WARNING: Maximum number of patterns is ',max_patterns,'!'); { read and process adtrack2.ini file } If _debug_ then WriteLn('--- updating user configuration'); process_config_file; { detect mouse } If _debug_ then WriteLn('--- detecting mouse'); If NOT mouse_disabled then mouse_active := mouse_driver_installed; If NOT mouse_disabled and NOT mouse_active then If is_scrollable_screen_mode then WriteLn('WARNING: Mouse driver not installed!'); {$ELSE} screen_ptr := ptr_screen_emulator; ShowStartMessage; { init system things } sys_init; { read and process adtrack2.ini file } If _debug_ then WriteLn('--- updating user configuration'); process_config_file; program_screen_mode := sdl_screen_mode; { allocate memory for patterns } If _debug_ then WriteLn('--- allocating frame buffer for patterns'); max_patterns := 128; GetMem(pattdata,PATTERN_SIZE*max_patterns); {$ENDIF} {$IFDEF GO32V2} { detect opl3 } If _debug_ then WriteLn('--- processing opl3 detection'); index := 1; If (opl3port <> 0) then If (opl3port < $100) then WriteLn('OPL3 interface base address forced to ',ExpStrL(Num2str(opl3port,16),2,'0'),'h') else If (opl3port < $1000) then WriteLn('OPL3 interface base address forced to ',ExpStrL(Num2str(opl3port,16),3,'0'),'h') else WriteLn('OPL3 interface base address forced to ',ExpStrL(Num2str(opl3port,16),4,'0'),'h') else begin opl3detected := FALSE; Repeat opl3port := scan_addresses[index]; Inc(index); Write('Autodetecting OPL3 interface at ', Num2str(opl3port,16),'h ... '); If NOT detect_OPL3 then begin If (index < 8) then Write(#13) else begin WriteLn('not responding!'); WriteLn; WriteLn('Force base address in configuration file (section TROUBLESHOOTiNG)'); WriteLn('or directly from command-line using "/cfg:adlib_port=XXXX" option;'); WriteLn('XXXX range is 1-FFFFh'); halt_startup(3); end; end else begin opl3detected := TRUE; WriteLn('ok'); BREAK; end; until opl3detected or (index > 7); end; {$ENDIF} { intialize player routine } If _debug_ then WriteLn('--- initializing player routine'); {$IFDEF GO32V2} If (opl_latency <> 0) then opl3out := opl2out; {$ENDIF} init_player; { initialize unit data } DialogIO_Init; StringIO_Init; TxtScrIO_Init; MenuLib1_Init; MenuLib2_Init; If _debug_ then WriteLn('--- initializing songdata'); tempo := init_tempo; speed := init_speed; init_songdata; songdata_source := ''; instdata_source := ''; songdata_title := 'noname.'; bank_position_list_size := 0; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); play_status := isStopped; current_octave := default_octave; If use_h_for_b then b_note := 'h'; For temp := 1 to 12*8+1 do If (note_layout[temp][1] = '%') then If NOT use_h_for_b then note_layout[temp][1] := 'B' else note_layout[temp][1] := 'H'; If _debug_ then WriteLn('--- executing program core'); {$IFDEF GO32V2} WriteLn('Available memory: ',free_mem DIV 1024,'k (DOS: ',dos_memavail*16 DIV 1024,'k)'); For temp := 1 to 50 do WaitRetrace; fade_speed := 16; fade_buf.action := first; VgaFade(fade_buf,fadeOut,delayed); For temp := 1 to 31 do If NOT _custom_svga_cfg[temp].flag or (_custom_svga_cfg[temp].value = -1) then begin custom_svga_mode := FALSE; BREAK; end; { initializing interface (phase:1) } If NOT is_VESA_emulated_mode then Case program_screen_mode of 0: SetCustomVideoMode(36); // 90x30 1: If NOT custom_svga_mode then set_svga_txtmode_100x38 // 100x38 else begin svga_txtmode_cols := _custom_svga_cfg[1].value; svga_txtmode_rows := _custom_svga_cfg[2].value; For temp := 1 to 29 do svga_txtmode_regs[temp].val := _custom_svga_cfg[2+temp].value; set_custom_svga_txtmode; end; 2: If NOT custom_svga_mode then set_svga_txtmode_128x48 // 100x48 else begin svga_txtmode_cols := _custom_svga_cfg[1].value; svga_txtmode_rows := _custom_svga_cfg[2].value; For temp := 1 to 29 do svga_txtmode_regs[temp].val := _custom_svga_cfg[2+temp].value; set_custom_svga_txtmode; end; 3: Case comp_text_mode of 0: SetCustomVideoMode(34); // 80x30 1: SetCustomVideoMode(25); // 80x25 end; 4: set_svga_txtmode_100x38; // 100x38 5: set_svga_txtmode_128x48; // 100x48 end else Case get_VESA_emulated_mode_idx of 0: begin VESA_Init; VESA_SetMode(VESA_800x600); VESA_SegLFB := Allocate_LDT_Descriptors(1); Set_Segment_Base_Address(VESA_SegLFB, Get_Linear_Addr(DWORD(VESA_FrameBuffer), VESA_VideoMemory*64*1024)); Set_Segment_Limit(VESA_SegLFB,VESA_VideoMemory*64*1024-1); For temp := 0 to 15 do SetRGBitem(temp,rgb_color[temp].r, rgb_color[temp].g, rgb_color[temp].b); end; 1: begin VESA_Init; VESA_SetMode(VESA_800x600); VESA_SegLFB := Allocate_LDT_Descriptors(1); Set_Segment_Base_Address(VESA_SegLFB, Get_Linear_Addr(DWORD(VESA_FrameBuffer), VESA_VideoMemory*64*1024)); Set_Segment_Limit(VESA_SegLFB,VESA_VideoMemory*64*1024-1); For temp := 0 to 15 do SetRGBitem(temp,rgb_color[temp].r, rgb_color[temp].g, rgb_color[temp].b); end; 2: begin VESA_Init; VESA_SetMode(VESA_1024x768); VESA_SegLFB := Allocate_LDT_Descriptors(1); Set_Segment_Base_Address(VESA_SegLFB, Get_Linear_Addr(DWORD(VESA_FrameBuffer), VESA_VideoMemory*64*1024)); Set_Segment_Limit(VESA_SegLFB,VESA_VideoMemory*64*1024-1); For temp := 0 to 15 do SetRGBitem(temp,rgb_color[temp].r, rgb_color[temp].g, rgb_color[temp].b); end; end; For temp := 0 to 15 do Case temp of 0..5, 7: SetRGBitem(temp, rgb_color[temp].r,rgb_color[temp].g,rgb_color[temp].b); 6: SetRGBitem(temp+14,rgb_color[temp].r,rgb_color[temp].g,rgb_color[temp].b); 8..15: SetRGBitem(temp+48,rgb_color[temp].r,rgb_color[temp].g,rgb_color[temp].b); end; If is_VESA_emulated_mode then begin VESA_GetPalette(fade_buf); FillChar(fade_buf2,SizeOf(fade_buf2),0); VESA_InitStepFade(fade_buf,fade_buf2,1); VESA_StepFade; end; { initializing interface (phase:2) } If NOT is_VESA_emulated_mode then begin HideCursor; LoadFont(font8x16); TXTSCRIO.initialize; hard_maxcol := MaxCol; hard_maxln := MaxLn; If NOT (program_screen_mode in [4,5]) then SetSize(MAX_COLUMNS,MAX_ROWS) else SetSize(SCREEN_RES_X DIV scr_font_width,MAX_ROWS); TXTSCRIO.initialize; do_synchronize := FALSE; end else begin v_seg := 0; v_ofs := Ofs(screen_emulator); screen_ptr := ptr_screen_emulator; mn_environment.v_dest := screen_ptr; TxtScrIO_Init; end; { initializing interface (phase:3) } work_MaxCol := MAX_COLUMNS; If (program_screen_mode in [4,5]) or ((program_screen_mode = 3) and (comp_text_mode = 4)) then work_MaxLn := MAX_ROWS else work_MaxLn := MAX_ROWS-10; If NOT is_VESA_emulated_mode then begin fade_buf.action := first; fade_speed := 1; VgaFade(fade_buf,fadeOut,fast); fade_speed := 32; end; asm mov ah,03h mov al,05h mov bl,typematic_rate mov bh,typematic_delay int 16h mov ax,1003h xor bl,bl int 10h end; If mouse_active then asm xor ax,ax int 33h mov ax,1bh int 33h mov mouse_sx,bx mov mouse_sy,cx mov mouse_sd,dx mov ax,04h xor cx,cx xor dx,dx int 33h mov ax,1ah mov bx,mouse_hspeed mov cx,mouse_vspeed mov dx,mouse_threshold int 33h mov ax,07h mov cx,0 mov dx,SCREEN_RES_x int 33h mov ax,08h mov cx,0 mov dx,SCREEN_RES_y int 33h end; {$ELSE} vid_SetVideoMode(TRUE); {$ENDIF} { initializing interface (phase:4) } PROGRAM_SCREEN_init; POSITIONS_reset; decay_bars_refresh; status_refresh; If (command_typing <> 0) then GotoXY(08+pos4[pattern_hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)) else GotoXY(08+pos3[pattern_hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)); ThinCursor; { initializing timer } init_timer_proc; { initializing keyboard } keyboard_init; stop_playing; {$IFDEF GO32V2} { initializing interface (phase:5) } realtime_gfx_poll_proc; _draw_screen_without_vsync := TRUE; draw_screen; WaitRetrace; If NOT is_VESA_emulated_mode then begin For temp := 1 to 10 do WaitRetrace; VgaFade(fade_buf,fadeIn,delayed); end else begin VESA_InitStepFade(fade_buf2,fade_buf,20); For temp := 1 to 20 do begin VESA_StepFade; If keypressed then keyboard_reset_buffer; end; end; {$ENDIF} { main loop } _debug_str_ := 'redirecting to main loop'; do_synchronize := TRUE; fkey := kENTER; Repeat If (fkey = kENTER) then PATTERN_edit(pattern_patt,pattern_page,pattern_hpos); If (fkey = kENTER) then PATTERN_ORDER_edit(pattord_page,pattord_hpos,pattord_vpos); until (fkey = kESC) or (fkey = kF10) or _force_program_quit; { terminating program (phase:1) } If NOT tracing then ThinCursor; do_synchronize := FALSE; {$IFDEF GO32V2} draw_screen; If NOT is_VESA_emulated_mode then fade_out_playback(TRUE) else begin VESA_InitStepFade(fade_buf,fade_buf2,20); For temp := 1 to 20 do begin VESA_StepFade; If (overall_volume > 3) then Dec(overall_volume,3) else overall_volume := 0; set_global_volume; If keypressed then keyboard_reset_buffer; end end; {$ELSE} fade_out_playback(TRUE); {$ENDIF} stop_playing; FillChar(decay_bar,SizeOf(decay_bar),0); FillChar(volum_bar,SizeOf(volum_bar),0); done_timer_proc; keyboard_done; {$IFDEF GO32V2} opl3exp($0004); opl3exp($0005); {$ELSE} opl3_done; {$ENDIF} { terminating program (phase:2) } _realtime_gfx_no_update := TRUE; {$IFDEF GO32V2} set_vga_txtmode_80x25; HideCursor; fade_buf.action := first; fade_speed := 1; VgaFade(fade_buf,fadeOut,fast); fade_speed := 32; GOTOXY_xshift := 0; GotoXY(1,1); C3WriteLn(ascii_line_01,$08,$09,$01); C3WriteLn(ascii_line_02,$08,$09,$01); C3WriteLn(ascii_line_03,$08,$09,$01); C3WriteLn(ascii_line_04,$08,$09,$01); C3WriteLn(ascii_line_05,$08,$09,$01); C3WriteLn(ascii_line_06,$08,$09,$01); C3WriteLn(ascii_line_07,$08,$09,$01); C3WriteLn(ascii_line_08,$08,$09,$01); C3WriteLn(ascii_line_09,$08,$09,$01); C3WriteLn(ascii_line_10,$08,$09,$01); C3WriteLn(ascii_line_11,$08,$09,$01); C3WriteLn(ascii_line_12,$08,$09,$01); C3WriteLn(ascii_line_13,$08,$07,$01); C3WriteLn(ascii_line_14,$08,$09,$03); C3WriteLn(ascii_line_15,$08,$09,$01); C3WriteLn(ascii_line_16,$08,$09,$01); C3WriteLn(ascii_line_17,$08,$09,$01); C3WriteLn(ascii_line_18,$08,$09,$01); C3WriteLn(ascii_line_19,$08,$09,$01); C3WriteLn(ascii_line_20,$08,$09,$01); C3WriteLn(ascii_line_21,$08,$09,$01); C3WriteLn(ascii_line_22,$08,$09,$01); C3WriteLn(ascii_line_23,$08,$09,$01); Move(vga_font8x16,font8x16,SizeOf(font8x16)); dosmemput(v_seg,v_ofs,screen_ptr^,(SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2); For temp := 1 to 50 do WaitRetrace; VgaFade(fade_buf,fadeIn,delayed); ThinCursor; For temp := 1 to 50 do WaitRetrace; { terminating program (phase:3) } sys_done; FreeMem(pattdata,PATTERN_SIZE*max_patterns); ExitProc := @old_exit_proc; If (dos_dir <> '') then ChDir(dos_dir); {$ELSE} program_screen_mode := 0; TxtScrIO_Init; vid_SetVideoMode(FALSE); vid_SetRGBPalette(Addr(vga_rgb_color)^); temp := screen_scroll_offset DIV 16 + 3; HideCursor; C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+01,ascii_line_01,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+02,ascii_line_02,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+03,ascii_line_03,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+04,ascii_line_04,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+05,ascii_line_05,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+06,ascii_line_06,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+07,ascii_line_07,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+08,ascii_line_08,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+09,ascii_line_09,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+10,ascii_line_10,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+11,ascii_line_11,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+12,ascii_line_12,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+13,ascii_line_13,$08,$07,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+14,ascii_line_14,$08,$09,$03); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+15,ascii_line_15,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+16,ascii_line_16,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+17,ascii_line_17,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+18,ascii_line_18,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+19,ascii_line_19,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+20,ascii_line_20,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+21,ascii_line_21,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+22,ascii_line_22,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+23,ascii_line_23,$08,$09,$01); C3WriteLn(02+(MAX_COLUMNS-57) DIV 2,temp+24,ascii_line_24,$08,$09,$01); Move(vga_font8x16,font8x16,SizeOf(font8x16)); draw_screen; SDL_Delay(3000); { terminating program (phase:3) } sys_done; snd_done; FreeMem(pattdata,PATTERN_SIZE*max_patterns); {$ENDIF} end. adlibtracker2-2.4.24/cleanup.bat0000644000000000000000000000302413411003760015123 0ustar rootroot@echo off echo. echo ************************************ echo ** ** echo ** Deleting file garbage ** echo ** ** echo ************************************ echo. if not exist *.exe goto :no_exe_file del *.exe >nul :no_exe_file if not exist *.ppu goto :no_ppu_file del *.ppu :no_ppu_file if not exist *.o goto :no_o_file del *.o :no_o_file if not exist !log goto :no_log_file del !log :no_log_file if not exist adt2help.* goto :no_help_file del adt2help.* >nul :no_help_file if not exist adt2play\*.exe goto :no_exe_file2 del adt2play\*.exe >nul :no_exe_file2 if not exist adt2play\*.fpd goto :no_fpd_file2 del adt2play\*.fpd >nul :no_fpd_file2 if not exist adt2play\*.map goto :no_map_file2 del adt2play\*.map :no_map_file2 if not exist adt2play\*.obj goto :no_obj_file2 del adt2play\*.obj :no_obj_file2 if not exist adt2play\*.sym goto :no_sym_file2 del adt2play\*.sym :no_sym_file2 if not exist adt2play\!log goto :no_log_file2 del adt2play\!log :no_log_file2 if not exist *.ppu goto :no_ppu_file del /F /Q *.ppu :no_ppu_file if not exist *.o goto :no_o_file del /F /Q *.o :no_o_file if not exist *.or goto :no_or_file del /F /Q *.or :no_or_file if not exist *.res goto :no_res_file del /F /Q *.res :no_res_file if not exist sdl\*.ppu goto :no_ppu_file2 del /F /Q sdl\*.ppu :no_ppu_file2 if not exist sdl\*.o goto :no_o_file2 del /F /Q sdl\*.o :no_o_file2 if not exist sdl\*.a goto :no_a_file del /F /Q sdl\*.a :no_a_file adlibtracker2-2.4.24/dialogio.pas0000644000000000000000000017517213411003760015316 0ustar rootroot// 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 DialogIO; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface uses DOS, {$IFDEF GO32V2} GO32, {$ENDIF} {$IFDEF WINDOWS} WINDOWS, {$ENDIF} StrUtils, AdT2unit,AdT2sys,AdT2keyb,AdT2text, TxtScrIO,StringIO,ParserIO; type tDIALOG_SETTING = Record frame_type: String; shadow_enabled: Boolean; title_attr: Byte; box_attr: Byte; text_attr: Byte; text2_attr: Byte; keys_attr: Byte; keys2_attr: Byte; short_attr: Byte; short2_attr: Byte; disbld_attr: Byte; contxt_attr: Byte; contxt2_attr: Byte; xstart: Byte; ystart: Byte; center_box: Boolean; center_text: Boolean; cycle_moves: Boolean; all_enabled: Boolean; terminate_keys: array[1..50] of Word; end; type tMENU_SETTING = Record frame_type: String; frame_enabled: Boolean; shadow_enabled: Boolean; posbar_enabled: Boolean; title_attr: Byte; menu_attr: Byte; text_attr: Byte; text2_attr: Byte; default_attr: Byte; short_attr: Byte; short2_attr: Byte; disbld_attr: Byte; contxt_attr: Byte; contxt2_attr: Byte; topic_attr: Byte; hi_topic_attr: Byte; topic_mask_chr: Set of Char; center_box: Boolean; cycle_moves: Boolean; edit_contents: Boolean; reverse_use: Boolean; show_scrollbar: Boolean; topic_len: Byte; fixed_len: Byte; homing_pos: Longint; terminate_keys: array[1..50] of Word; end; type tDIALOG_ENVIRONMENT = Record keystroke: Word; context: String; input_str: String; xpos,ypos: Byte; xsize,ysize: Byte; cur_item: Byte; ext_proc: procedure; end; type tMENU_ENVIRONMENT = Record v_dest: tSCREEN_MEM_PTR; keystroke: Word; context: String; unpolite: Boolean; winshade: Boolean; intact_area: Boolean; edit_pos: Byte; curr_page: Word; curr_pos: Word; curr_item: String; ext_proc: procedure; ext_proc_rt: procedure; refresh: procedure; do_refresh: Boolean; own_refresh: Boolean; preview: Boolean; fixed_start: Byte; descr_len: Byte; descr: Pointer; is_editing: Boolean; xpos,ypos: Byte; xsize,ysize: Byte; desc_pos: Byte; hlight_chrs: Byte; end; const {$IFDEF GO32V2} FILENAME_SIZE = 12; DIR_SIZE = 80; PATH_SIZE = 80; {$ELSE} FILENAME_SIZE = 255; DIR_SIZE = 170; PATH_SIZE = 255; {$ENDIF} type tFSELECT_ENVIRONMENT = Record last_file: String[FILENAME_SIZE]; last_dir: String[DIR_SIZE]; end; const dl_setting: tDIALOG_SETTING = (frame_type: frame_single; shadow_enabled: TRUE; title_attr: $0f; box_attr: $07; text_attr: $07; text2_attr: $0f; keys_attr: $07; keys2_attr: $70; short_attr: $0f; short2_attr: $70; disbld_attr: $07; contxt_attr: $0f; contxt2_attr: $07; xstart: 01; ystart: 01; center_box: TRUE; center_text: TRUE; cycle_moves: TRUE; all_enabled: FALSE; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); const mn_setting: tMENU_SETTING = (frame_type: frame_single; frame_enabled: TRUE; shadow_enabled: TRUE; posbar_enabled: TRUE; title_attr: $0f; menu_attr: $07; text_attr: $07; text2_attr: $70; default_attr: $0f; short_attr: $0f; short2_attr: $70; disbld_attr: $07; contxt_attr: $0f; contxt2_attr: $07; topic_attr: $07; hi_topic_attr: $0f; topic_mask_chr: []; center_box: TRUE; cycle_moves: TRUE; edit_contents: FALSE; reverse_use: FALSE; show_scrollbar: TRUE; topic_len: 0; fixed_len: 0; homing_pos: 0; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); var dl_environment: tDIALOG_ENVIRONMENT; mn_environment: tMENU_ENVIRONMENT; fs_environment: tFSELECT_ENVIRONMENT; function Dialog(text,keys,title: String; spos: Byte): Byte; function Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; function Fselect(mask: String): String; function HScrollBar(dest: tSCREEN_MEM_PTR; x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Word; function VScrollBar(dest: tSCREEN_MEM_PTR; x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Word; procedure DialogIO_Init; implementation type tDBUFFR = array[1.. 100] of Record str: String; pos: Byte; key: Char; use: Boolean; end; type tMBUFFR = array[1..16384] of Record key: Char; use: Boolean; end; var idx,idx2,idx3,pos,max,mx2,num,nm2, xstart,ystart,count, ln,ln1,len2b,atr1,atr2, page,first,last,temp,temp2,opage,opos: Word; old_fr_shadow_enabled: Boolean; key: Word; str: String; solid: Boolean; qflg: Boolean; dbuf: tDBUFFR; mbuf: tMBUFFR; contxt: String; function OutKey(str: String): Char; var result: Char; begin If (SYSTEM.Pos('~',str) = 0) then result := '~' else If (str[SYSTEM.Pos('~',str)+2] <> '~') then result := '~' else result := str[SYSTEM.Pos('~',str)+1]; OutKey := result; end; function ReadChunk(str: String; pos: Byte): String; var result: String; begin Delete(str,1,pos-1); If (SYSTEM.Pos('$',str) = 0) then result := '' else result := Copy(str,1,SYSTEM.Pos('$',str)-1); ReadChunk := result; end; function Dialog(text,keys,title: String; spos: Byte): Byte; procedure SubPos(var p: Word); var temp: Word; begin temp := p; If (temp > 1) and dbuf[temp-1].use then Dec(temp) else If (temp > 1) then begin Dec(temp); SubPos(temp); end; If dbuf[temp].use then p := temp; end; procedure AddPos(var p: Word); var temp: Word; begin temp := p; If (temp < nm2) and dbuf[temp+1].use then Inc(temp) else If (temp < nm2) then begin Inc(temp); AddPos(temp); end; If dbuf[temp].use then p := temp; end; procedure ShowItem; begin If (idx2 = 0) then EXIT; If (idx2 <> idx3) then ShowCStr(screen_ptr,dbuf[idx3].pos,ystart+num+1,dbuf[idx3].str, dl_setting.keys_attr,dl_setting.short_attr); ShowCStr(screen_ptr,dbuf[idx2].pos,ystart+num+1,dbuf[idx2].str, dl_setting.keys2_attr,dl_setting.short2_attr); idx3 := idx2; end; function RetKey(code: Byte): Word; var temp: Byte; begin RetKey := 0; For temp := 1 to nm2 do If (UpCase(dbuf[temp].key) = UpCase(CHR(code))) then begin RetKey := temp; BREAK; end; end; function CurrentKey(pos: Byte): Byte; var idx,temp: Byte; begin temp := 0; For idx := 1 to nm2 do If (pos in [dbuf[idx].pos,dbuf[idx].pos+CStrLen(dbuf[idx].str)-1]) then temp := idx; CurrentKey := temp; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:Dialog'; {$ENDIF} pos := 1; max := Length(title); num := 0; ScreenMemCopy(screen_ptr,ptr_scr_backup); HideCursor; Repeat str := ReadChunk(text,pos); Inc(pos,Length(str)+1); If (CStrLen(str) > max) then max := CStrLen(str); If (str <> '') then Inc(num); until (pos >= Length(text)) or (str = ''); pos := 1; mx2 := 0; nm2 := 0; If (Copy(keys,1,14) = '%string_input%') then begin Inc(pos,14); str := ReadChunk(keys,pos); ln := Str2num(str,10); If (str = '') then EXIT; Inc(pos,Length(str)+1); str := ReadChunk(keys,pos); ln1 := Str2num(str,10); mx2 := ln1; If (str = '') then EXIT; Inc(pos,Length(str)+1); str := ReadChunk(keys,pos); atr1 := Str2num(str,16); If (str = '') then EXIT; Inc(pos,Length(str)+1); str := ReadChunk(keys,pos); atr2 := Str2num(str,16); If (str = '') then EXIT; Inc(pos,Length(str)+1); end else begin Repeat str := ReadChunk(keys,pos); Inc(pos,Length(str)+1); If (str <> '') then begin Inc(nm2); dbuf[nm2].str := ' '+str+' '; dbuf[nm2].key := OutKey(str); If NOT dl_setting.all_enabled then dbuf[nm2].use := dbuf[nm2].key <> '~' else dbuf[nm2].use := TRUE; If (nm2 > 1) then begin dbuf[nm2].pos := dbuf[nm2-1].pos+CStrLen(dbuf[nm2-1].str)+1; Inc(mx2,CStrLen(dbuf[nm2].str)+1); end else begin dbuf[nm2].pos := 1; Inc(mx2,CStrLen(dbuf[nm2].str)); end; end; until (pos >= Length(keys)) or (str = ''); end; If (max < mx2) then max := mx2 else begin ln1 := max; If (ln < max) then ln := max; end; If dl_setting.center_box then begin xstart := (work_MaxCol-(max+4)) DIV 2+(work_MaxCol-(max+4)) MOD 2; ystart := (work_MaxLn -(num+2)) DIV 2+(work_MaxLn -(num+2)) MOD 2; end else begin xstart := dl_setting.xstart; ystart := dl_setting.ystart; end; old_fr_shadow_enabled := fr_setting.shadow_enabled; fr_setting.shadow_enabled := dl_setting.shadow_enabled; Frame(screen_ptr,xstart,ystart,xstart+max+3,ystart+num+2, dl_setting.box_attr,title,dl_setting.title_attr, dl_setting.frame_type); fr_setting.shadow_enabled := old_fr_shadow_enabled; dl_environment.xpos := xstart; dl_environment.ypos := ystart; dl_environment.xsize := max+3; dl_environment.ysize := num+2; pos := 1; contxt := DietStr(dl_environment.context,max+ (Length(dl_environment.context)-CStrLen(dl_environment.context))); ShowCStr(screen_ptr,xstart+max+3-CStrLen(contxt),ystart+num+2, contxt,dl_setting.contxt_attr,dl_setting.contxt2_attr); For idx := 1 to num do begin str := ReadChunk(text,pos); Inc(pos,Length(str)+1); If dl_setting.center_text then ShowCStr(screen_ptr,xstart+2,ystart+idx, ExpStrL(str,Length(str)+(max-CStrLen(str)) DIV 2,' '), dl_setting.text_attr,dl_setting.text2_attr) else ShowCStr(screen_ptr,xstart+2,ystart+idx, str,dl_setting.text_attr,dl_setting.text2_attr); end; If (Copy(keys,1,14) = '%string_input%') then begin ThinCursor; str := InputStr(dl_environment.input_str, xstart+2,ystart+num+1,ln,ln1,atr1,atr2); If is_environment.keystroke = kENTER then dl_environment.input_str := str; dl_environment.keystroke := is_environment.keystroke; HideCursor; end else begin For idx := 1 to nm2 do begin Inc(dbuf[idx].pos,xstart+(max-mx2) DIV 2+1); If dbuf[idx].use then ShowCStr(screen_ptr,dbuf[idx].pos,ystart+num+1, dbuf[idx].str,dl_setting.keys_attr,dl_setting.short_attr) else ShowCStr(screen_ptr,dbuf[idx].pos,ystart+num+1, dbuf[idx].str,dl_setting.disbld_attr,dl_setting.disbld_attr); end; If (spos < 1) then spos := 1; If (spos > nm2) then spos := nm2; idx2 := spos; idx3 := 1; If NOT dbuf[idx2].use then begin SubPos(idx2); If NOT dbuf[idx2].use then AddPos(idx2); end; ShowItem; ShowItem; qflg := FALSE; If (keys = '$') then EXIT; Repeat dl_environment.cur_item := idx2; If (Addr(dl_environment.ext_proc) <> NIL) then dl_environment.ext_proc; key := getkey; If LookUpKey(key,dl_setting.terminate_keys,50) then qflg := TRUE; If NOT qflg then If (LO(key) in [$20..$0ff]) then begin idx := RetKey(LO(key)); If (idx <> 0) then begin qflg := TRUE; idx2 := idx; end; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then Case key of kLEFT: If (idx2 > 1) or NOT dl_setting.cycle_moves then SubPos(idx2) else begin idx2 := nm2; If NOT dbuf[idx2].use then SubPos(idx2); end; kRIGHT: If (idx2 < nm2) or NOT dl_setting.cycle_moves then begin temp := idx2; AddPos(idx2); If (idx2 = temp) then begin idx2 := 1; If NOT dbuf[idx2].use then AddPos(idx2); end; end else begin idx2 := 1; If NOT dbuf[idx2].use then AddPos(idx2); end; kHOME: begin idx2 := 1; If NOT dbuf[idx2].use then AddPos(idx2); end; kEND: begin idx2 := nm2; If NOT dbuf[idx2].use then SubPos(idx2); end; end; ShowItem; {$IFNDEF GO32V2} draw_screen; {$ENDIF} until qflg or _force_program_quit; Dialog := idx2; dl_environment.keystroke := key; end; If Addr(move_to_screen_routine) <> NIL then begin move_to_screen_data := ptr_scr_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+max+3+2; move_to_screen_area[4] := ystart+num+2+1; move_to_screen_routine; end else ScreenMemCopy(ptr_scr_backup,screen_ptr); end; var mnu_x,mnu_y,mnu_len,mnu_len2,mnu_topic_len: Byte; mnu_data: Pointer; mnu_count: Word; var vscrollbar_pos: Word; function pstr(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:pstr'; {$ENDIF} If (item <= mnu_count) then Move(pBYTE(mnu_data)[(item-1)*(mnu_len+1)],temp,mnu_len+1) else temp := ''; If NOT solid then pstr := ExpStrR(temp,mnu_len-2,' ') else pstr := ExpStrR(temp,mnu_len,' '); end; function pstr2(item: Word): String; var idx: Byte; temp,result: String; begin If (item <= mnu_count) then Move(pBYTE(mnu_data)[(item-1)*(mnu_len+1)],temp,mnu_len+1) else temp := ''; If NOT solid then temp := ExpStrR(temp,mnu_len-2,' ') else temp := ExpStrR(temp,mnu_len,' '); If (mn_setting.fixed_len <> 0) then result := temp else begin result := ''; For idx := 1 to Length(temp) do If (temp[idx] in mn_setting.topic_mask_chr) then result := result+'`'+temp[idx]+'`' else result := result+temp[idx]; end; pstr2 := result; end; function pdes(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:pdes'; {$ENDIF} If (mn_environment.descr <> NIL) and (item <= mnu_count) then Move(pBYTE(mn_environment.descr)[(item-1)*(mn_environment.descr_len+1)],temp,mn_environment.descr_len+1) else temp := ''; pdes := ExpStrR(temp,mn_environment.descr_len,' '); end; procedure refresh; procedure ShowCStr_clone(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); var temp, len,len2: Byte; highlighted: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:refresh:ShowCStr_clone'; {$ENDIF} If NOT (mn_setting.fixed_len <> 0) then begin ShowC3Str(dest,x,y,str,atr1,atr2,atr1 AND $0f0+mn_setting.topic_attr AND $0f); EXIT; end; highlighted := FALSE; len := 0; len2 := 0; For temp := 1 to Length(str) do If (str[temp] = '~') then highlighted := NOT highlighted else begin If (temp >= mn_environment.fixed_start) and (len < mn_setting.fixed_len) then begin If NOT highlighted then ShowStr(dest,x+len2,y,str[temp],atr1) else ShowStr(dest,x+len2,y,str[temp],atr2); Inc(len); Inc(len2); end else begin If NOT highlighted then ShowStr(dest,x+len2,y,str[temp],atr3) else ShowStr(dest,x+len2,y,str[temp],atr4); If (temp >= mn_environment.fixed_start) then Inc(len); Inc(len2); end end; end; var item_str,item_str_alt, item_str2,item_str2_alt: String; desc_str,desc_str2,desc_str3: String; begin { refresh } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:refresh'; {$ENDIF} If (page = opage) and (idx2 = opos) and NOT mn_environment.do_refresh then EXIT else begin opage := page; opos := idx2; mn_environment.do_refresh := FALSE; end; If NOT mn_environment.own_refresh then For idx := page to mnu_len2+page-1 do begin item_str := pstr(idx-page+1); item_str_alt := pstr(idx); item_str2 := pstr2(idx2+page-1); item_str2_alt := pstr2(idx); desc_str := pdes(idx-page+1); desc_str2 := pdes(idx); desc_str3 := pdes(idx2+page-1); If (mn_environment.hlight_chrs <> 0) and (item_str <> '') then item_str := '~'+Copy(item_str,1,mn_environment.hlight_chrs)+ '~'+Copy(item_str,mn_environment.hlight_chrs+1,Length(item_str)-mn_environment.hlight_chrs); If (mn_environment.hlight_chrs <> 0) and (item_str_alt <> '') then item_str_alt := '~'+Copy(item_str_alt,1,mn_environment.hlight_chrs)+ '~'+Copy(item_str_alt,mn_environment.hlight_chrs+1,Length(item_str_alt)-mn_environment.hlight_chrs); If (mn_environment.hlight_chrs <> 0) and (item_str2 <> '') then item_str2 := '~'+Copy(item_str2,1,mn_environment.hlight_chrs)+ '~'+Copy(item_str2,mn_environment.hlight_chrs+1,Length(item_str2)-mn_environment.hlight_chrs); If (mn_environment.hlight_chrs <> 0) and (item_str2_alt <> '') then item_str2_alt := '~'+Copy(item_str2_alt,1,mn_environment.hlight_chrs)+ '~'+Copy(item_str2_alt,mn_environment.hlight_chrs+1,Length(item_str2_alt)-mn_environment.hlight_chrs); If (idx = idx2+page-1) then ShowCStr_clone(mn_environment.v_dest,mnu_x+1,mnu_y+idx2, ExpStrR(item_str2+desc_str3, max+(Length(item_str2)+Length(desc_str3)- (C3StrLen(item_str2)+CStrLen(desc_str3))),' '), mn_setting.text2_attr, mn_setting.short2_attr, mn_setting.text_attr, mn_setting.short_attr) else If (idx-page+1 <= mnu_topic_len) then ShowCStr(mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(item_str+desc_str, max+(Length(item_str)+Length(desc_str3)- CStrLen(item_str+desc_str)),' '), mn_setting.topic_attr, mn_setting.hi_topic_attr) else If mbuf[idx].use then ShowC3Str(mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(item_str2_alt+desc_str2, max+(Length(item_str2_alt)+Length(desc_str3)- (C3StrLen(item_str2_alt)+CStrLen(desc_str2))),' '), mn_setting.text_attr, mn_setting.short_attr, mn_setting.topic_attr) else ShowCStr(mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(item_str_alt+desc_str2, max+(Length(item_str_alt)+Length(desc_str3)- CStrLen(item_str_alt+desc_str2)),' '), mn_setting.disbld_attr, mn_setting.disbld_attr); end; If mn_setting.show_scrollbar then vscrollbar_pos := VScrollBar(mn_environment.v_dest,mnu_x+max+1,mnu_y+1-mn_setting.topic_len, temp2,mnu_count,idx2+page-1, vscrollbar_pos,mn_setting.menu_attr,mn_setting.menu_attr); end; function Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure SubPos(var p: Word); var temp: Word; begin temp := p; If (temp > 1) and mbuf[temp+page-2].use then Dec(temp) else If (temp > 1) then begin Dec(temp); SubPos(temp); end else If (page > first) then Dec(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 > first) then SubPos(temp); end; procedure AddPos(var p: Word); var temp: Word; begin temp := p; If (temp < len2) and (temp < last) and mbuf[temp+page].use then Inc(temp) else If (temp < len2) and (temp < last) then begin Inc(temp); AddPos(temp); end else If (page+temp <= last) then Inc(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 < last) then AddPos(temp); end; function RetKey(code: Byte): Word; var temp: Byte; begin RetKey := 0; For temp := 1 to count do If (UpCase(mbuf[temp].key) = UpCase(CHR(code))) then begin RetKey := temp; BREAK; end; end; procedure edit_contents(item: Word); var item_str,temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:Menu:edit_contents'; {$ENDIF} is_setting.append_enabled := TRUE; is_setting.character_set := [' '..'_','a'..'}',#128..#255]; // exclude ` and ~ characters is_environment.locate_pos := 1; item_str := pstr(item); If (mn_environment.edit_pos > 0) and (mn_environment.edit_pos < max-2) then temp := Copy(item_str,mn_environment.edit_pos+1, Length(item_str)-mn_environment.edit_pos+1) else temp := CutStr(item_str); mn_environment.is_editing := TRUE; While (temp <> '') and (temp[Length(temp)] = ' ') do Delete(temp,Length(temp),1); temp := InputStr(temp,x+1+mn_environment.edit_pos,y+idx2, max-2-mn_environment.edit_pos+1, max-2-mn_environment.edit_pos+1, mn_setting.text2_attr,mn_setting.default_attr); mn_environment.is_editing := FALSE; HideCursor; If (is_environment.keystroke = kENTER) then begin If (mn_environment.edit_pos > 0) and (mn_environment.edit_pos < max-2) then temp := Copy(item_str,1,mn_environment.edit_pos)+temp else temp := CutStr(temp); Move(temp,pBYTE(mnu_data)[(item-1)*(len+1)],len+1); end; mn_environment.do_refresh := TRUE; refresh; end; begin { Menu } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:Menu'; {$ENDIF} If (count = 0) then begin Menu := 0; EXIT; end; max := Length(title); mnu_data := Addr(data); mnu_count := count; mnu_len := len; If NOT mn_environment.unpolite then ScreenMemCopy(mn_environment.v_dest,ptr_scr_backup2); If (count < 1) then EXIT; vscrollbar_pos := WORD_NULL; If NOT mn_environment.preview then HideCursor; temp := 0; For idx := 1 to count do begin mbuf[idx].key := OutKey(pstr(idx)); If NOT mn_setting.reverse_use then mbuf[idx].use := mbuf[idx].key <> '~' else mbuf[idx].use := NOT (mbuf[idx].key <> '~'); If mbuf[idx].use then temp := 1; end; solid := FALSE; If (temp = 0) then begin For temp := 1 to count do mbuf[temp].use := TRUE; solid := TRUE; end; For idx := 1 to count do If (max < CStrLen(pstr(idx))+mn_environment.descr_len) then max := CStrLen(pstr(idx))+mn_environment.descr_len; If mn_setting.center_box then begin x := (work_MaxCol-max-2) DIV 2+(work_MaxCol-max-2) MOD 2; y := (work_MaxLn-len2-1) DIV 2+(work_MaxLn-len2-1) MOD 2; end; mnu_x := x; mnu_y := y; len2b := len2; mn_environment.xpos := x; mn_environment.ypos := y; mn_environment.xsize := max+1; mn_environment.ysize := len2+1; mn_environment.desc_pos := y+len2+1; If NOT mn_environment.unpolite then begin old_fr_shadow_enabled := fr_setting.shadow_enabled; fr_setting.shadow_enabled := mn_setting.shadow_enabled; If mn_environment.intact_area then fr_setting.update_area := FALSE; If mn_setting.frame_enabled then Frame(mn_environment.v_dest,x,y,x+max+1,y+len2+1,mn_setting.menu_attr, title,mn_setting.title_attr,mn_setting.frame_type); If mn_environment.intact_area then fr_setting.update_area := TRUE; fr_setting.shadow_enabled := old_fr_shadow_enabled; contxt := DietStr(mn_environment.context,max+ (Length(mn_environment.context)-CStrLen(mn_environment.context))); If mn_setting.frame_enabled then ShowC3Str(mn_environment.v_dest,x+1,y+len2+1, '`'+ExpStrL('',max-CStrLen(contxt), mn_setting.frame_type[2])+'`'+ contxt, mn_setting.contxt_attr, mn_setting.contxt2_attr, mn_setting.menu_attr); temp2 := len2; mnu_len2 := len2; If (len2 > count) then len2 := count; If (len2 < 1) then len2 := 1; If (spos < 1) then spos := 1; If (spos > count) then spos := count; mn_environment.refresh := refresh; first := 1; last := count; While NOT mbuf[first].use do Inc(first); While NOT mbuf[last].use do Dec(last); If (first <= mn_setting.topic_len) then first := SUCC(mn_setting.topic_len); If (spos < first) or (spos > last) then spos := first; idx2 := 1; page := 1; opage := WORD_NULL; opos := WORD_NULL; While (idx2+page-1 < spos) do AddPos(idx2); end; mnu_topic_len := mn_setting.topic_len; If (mnu_topic_len <> 0) then begin mn_setting.topic_len := 0; refresh; mn_setting.topic_len := mnu_topic_len; mnu_topic_len := 0; mnu_data := mnu_data+SUCC(len)*mn_setting.topic_len; Inc(mnu_y,mn_setting.topic_len); Dec(len2,mn_setting.topic_len); Dec(mnu_len2,mn_setting.topic_len); Move(mbuf[SUCC(mn_setting.topic_len)],mbuf[1], (count-mn_setting.topic_len)*SizeOf(mbuf[1])); For temp := 1 to mn_setting.topic_len do SubPos(idx2); Dec(count,mn_setting.topic_len); Dec(mnu_count,mn_setting.topic_len); Dec(first,mn_setting.topic_len); Dec(last,mn_setting.topic_len); refresh; end else refresh; mn_environment.curr_page := page; mn_environment.curr_pos := idx2+page-1; mn_environment.curr_item := CutStr(pstr(idx2+page-1)); mn_environment.keystroke := WORD_NULL; If (Addr(mn_environment.ext_proc) <> NIL) then mn_environment.ext_proc; qflg := FALSE; If mn_environment.preview then begin mn_environment.preview := FALSE; mn_environment.unpolite := TRUE; end else begin Repeat mn_environment.keystroke := key; key := getkey; If NOT qflg then If (LO(key) in [$20..$0ff]) then begin idx := RetKey(LO(key)); If (idx <> 0) then begin refresh; idx2 := idx; If NOT ((key = mn_setting.terminate_keys[2]) and mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx); end; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then Case key of kUP: If (page+idx2-1 > first) or NOT mn_setting.cycle_moves then SubPos(idx2) else begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kDOWN: If (page+idx2-1 < last) or NOT mn_setting.cycle_moves then AddPos(idx2) else begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kHOME: begin If (mn_setting.homing_pos = 0) then begin idx2 := 1; page := 1; end else If (idx2+page-1 > mn_setting.homing_pos) and (mn_setting.homing_pos < count) then Repeat SubPos(idx2) until (idx2+page-1 <= mn_setting.homing_pos) else begin idx2 := 1; page := 1; end; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kEND: begin If (mn_setting.homing_pos = 0) then begin idx2 := len2; page := count-len2+1; end else If (idx2+page-1 < mn_setting.homing_pos) and (mn_setting.homing_pos < count) then Repeat AddPos(idx2); until (idx2+page-1 >= mn_setting.homing_pos) else begin idx2 := len2; page := count-len2+1; end; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kPgUP: If (idx2+page-1-(len2-1) > mn_setting.homing_pos) or (idx2+page-1 <= mn_setting.homing_pos) or (mn_setting.homing_pos = 0) or NOT (mn_setting.homing_pos < count) then For temp := 1 to len2-1 do SubPos(idx2) else Repeat SubPos(idx2); until (idx2+page-1 <= mn_setting.homing_pos); kPgDOWN: If (idx2+page-1+(len2-1) < mn_setting.homing_pos) or (idx2+page-1 >= mn_setting.homing_pos) or (mn_setting.homing_pos = 0) or NOT (mn_setting.homing_pos < count) then For temp := 1 to len2-1 do AddPos(idx2) else Repeat AddPos(idx2); until (idx2+page-1 >= mn_setting.homing_pos); end; If LookUpKey(key,mn_setting.terminate_keys,50) then If NOT ((key = mn_setting.terminate_keys[2]) and mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx2+page-1); mn_environment.curr_page := page; mn_environment.curr_pos := idx2+page-1; mn_environment.curr_item := CutStr(pstr(idx2+page-1)); refresh; mn_environment.keystroke := key; If (Addr(mn_environment.ext_proc) <> NIL) then mn_environment.ext_proc; {$IFNDEF GO32V2} draw_screen; {$ENDIF} until qflg or _force_program_quit; end; If mn_environment.winshade and NOT mn_environment.unpolite then begin If (Addr(move_to_screen_routine) <> NIL) then begin move_to_screen_data := ptr_scr_backup2; move_to_screen_area[1] := x; move_to_screen_area[2] := y; move_to_screen_area[3] := x+max+1+2; move_to_screen_area[4] := y+len2b+1+1; move_to_screen_routine; end else ScreenMemCopy(ptr_scr_backup2,mn_environment.v_dest); end; Menu := idx2+page-1; end; const MAX_FILES = 4096; UPDIR_STR = #19'updir'; {$IFDEF UNIX} DRIVE_DIVIDER = 0; {$ELSE} DRIVE_DIVIDER = 1; {$ENDIF} type tSEARCH = Record name: String[FILENAME_SIZE]; attr: Word; info: String; size: Longint; end; type tSTREAM = Record stuff: array[1..MAX_FILES] of tSEARCH; count: Word; drive_count: Word; match_count: Word; end; type {$IFDEF GO32V2} tMNUDAT = array[1..MAX_FILES] of String[1+12+1]; {$ELSE} tMNUDAT = array[1..MAX_FILES] of String[1+23+1]; {$ENDIF} type tDSCDAT = array[1..MAX_FILES] of String[20]; var menudat: tMNUDAT; descr: tDSCDAT; masks: array[1..20] of String; fstream: tSTREAM; {$IFNDEF GO32V2} drive_list: array[0..128] of Char; {$ENDIF} function LookUpMask(filename: String): Boolean; var temp: Byte; okay: Boolean; begin okay := FALSE; For temp := 1 to count do {$IFDEF GO32V2} If SameName(Upper(masks[temp]),Upper(filename)) then {$ELSE} If (Upper(Copy(masks[temp],3,Length(masks[temp]))) = Upper(ExtOnly(filename))) then {$ENDIF} begin okay := TRUE; BREAK; end; LookUpMask := okay; end; {$IFDEF GO32V2} function valid_drive(drive: Char): Boolean; function phantom_drive(drive: Char): Boolean; var regs: tRealRegs; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:phantom_drive'; regs.ax := $440e; regs.bl := BYTE(UpCase(drive))-$40; RealIntr($21,regs); If Odd(regs.flags) then phantom_drive := FALSE else If (regs.al = 0) then phantom_drive := FALSE else phantom_drive := (regs.al <> BYTE(UpCase(drive))-$40); end; var regs: tRealRegs; dos_sel,dos_seg: Word; dos_mem_adr: Dword; dos_data: array[0..PRED(40)] of Byte; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:valid_drive'; dos_mem_adr := global_dos_alloc(40); dos_sel := WORD(dos_mem_adr); dos_seg := WORD(dos_mem_adr SHR 16); dos_data[0] := BYTE(UpCase(drive)); dos_data[1] := BYTE(':'); dos_data[2] := 0; dosmemput(dos_seg,0,dos_data,40); regs.ax := $2906; regs.si := 0; regs.di := 3; regs.ds := dos_seg; regs.es := dos_seg; RealIntr($21,regs); global_dos_free(dos_sel); valid_drive := (regs.al <> BYTE_NULL) and NOT phantom_drive(drive); end; {$ELSE} function valid_drive(drive: Char; var info: String): Boolean; var idx: Byte; begin valid_drive := FALSE; info := ''; {$IFNDEF UNIX} idx := 0; For idx := 0 to 128 do If (drive_list[idx] = drive) then begin info := 'DRiVE'; BREAK; end; {$ENDIF} If (info <> '') then valid_drive := TRUE; end; {$ENDIF} procedure make_stream(path,mask: String; var stream: tSTREAM); var search: SearchRec; count1,count2: Word; drive: Char; {$IFNDEF GO32V2} type tCOMPARE_STR_RESULT = (isLess,isMore,isEqual); function CompareStr(str1,str2: String): tCOMPARE_STR_RESULT; var idx,len: Byte; result: tCOMPARE_STR_RESULT; begin If (str1 = UPDIR_STR) then result := isLess else If (str2 = UPDIR_STR) then result := isMore else result := isEqual; If (result <> isEqual) then begin CompareStr := result; EXIT; end; str1 := Upper(FilterStr2(str1,_valid_characters_fname,'_')); str2 := Upper(FilterStr2(str2,_valid_characters_fname,'_')); If (Length(str1) > Length(str2)) then len := Length(str1) else len := Length(str2); For idx := 1 to len do If (FilterStr2(str1[idx],_valid_characters,#01) > FilterStr2(str2[idx],_valid_characters,#01)) then begin result := isMore; BREAK; end else If (str1[idx] < str2[idx]) then begin result := isLess; BREAK; end; If (result = isEqual) then If (Length(str1) < Length(str2)) then result := isLess else If (Length(str1) > Length(str2)) then result := isMore; CompareStr := result; end; {$ENDIF} procedure QuickSort(l,r: Word); var i,j: Word; cmp: String; tmp: tSEARCH; begin If (l >= r) then EXIT; cmp := stream.stuff[(l+r) DIV 2].name; i := l; j := r; Repeat {$IFDEF GO32V2} While (i < r) and (stream.stuff[i].name < cmp) do Inc(i); While (j > l) and (stream.stuff[j].name > cmp) do Dec(j); {$ELSE} While (i < r) and (CompareStr(stream.stuff[i].name,cmp) = isLess) do Inc(i); While (j > l) and (CompareStr(stream.stuff[j].name,cmp) = isMore) do Dec(j); {$ENDIF} If (i <= j) then begin tmp := stream.stuff[i]; stream.stuff[i] := stream.stuff[j]; stream.stuff[j] := tmp; Inc(i); Dec(j); end; until (i > j); If (l < j) then QuickSort(l,j); If (i < r) then QuickSort(i,r); end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:make_stream'; {$ELSE} {$IFNDEF UNIX} GetLogicalDriveStrings(SizeOf(drive_list),drive_list); {$ENDIF} {$ENDIF} count1 := 0; For drive := 'A' to 'Z' do {$IFDEF GO32V2} If valid_drive(drive) then {$ELSE} If valid_drive(drive,stream.stuff[SUCC(count1)].info) then {$ENDIF} begin Inc(count1); stream.stuff[count1].name := drive; stream.stuff[count1].attr := volumeid; stream.stuff[count1].size := 0; end; Inc(count1); stream.stuff[count1].name := '~'+#255+'~'; stream.stuff[count1].attr := volumeid; count2 := 0; stream.drive_count := count1; {$IFDEF GO32V2} If (DiskSize(ORD(UpCase(path[1]))-ORD('A')+1) > 0) then begin {$ENDIF} FindFirst(path+WILDCARD_ASTERISK,anyfile-volumeid,search); While (DOSerror = 0) and (count1 < MAX_FILES) do begin If (search.attr AND directory <> 0) and (search.name = '.') then begin FindNext(search); CONTINUE; end else If (search.attr AND directory <> 0) and NOT ((search.name = '..') and (Length(path) = 3)) then begin If (search.name <> '..') then search.name := search.name else search.name := UPDIR_STR; Inc(count1); stream.stuff[count1].name := search.name; stream.stuff[count1].attr := search.attr; end; FindNext(search); end; {$IFNDEF GO32V2} If (Length(path) > 3) and (count1 = stream.drive_count) then begin Inc(count1); stream.stuff[count1].name := UPDIR_STR; stream.stuff[count1].attr := search.attr; end; {$ENDIF} FindFirst(path+WILDCARD_ASTERISK,anyfile-volumeid-directory,search); While (DOSerror = 0) and (count1+count2 < MAX_FILES) do begin If LookUpMask(search.name) then begin search.name := Lower_filename(search.name); Inc(count2); stream.stuff[count1+count2].name := search.name; stream.stuff[count1+count2].attr := search.attr; stream.stuff[count1+count2].size := search.size; end; FindNext(search); end; {$IFDEF GO32V2} end; {$ENDIF} QuickSort(stream.drive_count+DRIVE_DIVIDER,count1); QuickSort(count1+DRIVE_DIVIDER,count1+count2); stream.count := count1+count2; stream.match_count := count2; end; var path: array[1..26] of String[PATH_SIZE]; old_fselect_external_proc: Procedure; procedure new_fselect_external_proc; begin mn_environment.curr_item := fstream.stuff[mn_environment.curr_pos].name; If (@old_fselect_external_proc <> NIL) then old_fselect_external_proc; end; function Fselect(mask: String): String; var {$IFNDEF GO32V2} temp1: Longint; {$ENDIF} temp2: Longint; temp3,temp4: String; temp5: Longint; temp6,temp7: String; temps: String; temp8: Longint; lastp: Longint; idx: Byte; function path_filter(path: String): String; begin If (Length(path) > 3) and (path[Length(path)] = PATHSEP) then Delete(path,Length(path),1); path_filter := Upper_filename(path); end; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:Fselect'; {$ENDIF} _jmp1: idx := 1; count := 0; Repeat temp6 := Upper(ReadChunk(mask,idx)); Inc(idx,Length(temp6)+1); If NOT (temp6 = '') then begin Inc(count); masks[count] := temp6; end; until (idx >= Length(mask)) or (temp6 = ''); {$i-} GetDir(0,temp6); {$i+} If (IOresult <> 0) then temp6 := fs_environment.last_dir; If (fs_environment.last_dir <> '') then begin {$i-} ChDir(fs_environment.last_dir); {$i+} If (IOresult <> 0) then begin {$i-} ChDir(temp6); {$i+} If (IOresult <> 0) then ; fs_environment.last_file := 'FNAME:EXT'; end; end; {$i-} GetDir(0,temp3); {$i+} If (IOresult <> 0) then temp3 := temp6; If (temp3[Length(temp3)] <> PATHSEP) then temp3 := temp3+PATHSEP; mn_setting.cycle_moves := FALSE; temp4 := ''; mn_environment.descr_len := 20; mn_environment.descr := Addr(descr); mn_environment.winshade := FALSE; ScreenMemCopy(screen_ptr,ptr_scr_backup); Repeat path[SUCC(ORD(UpCase(temp3[1]))-ORD('A'))] := path_filter(temp3); make_stream(temp3,mask,fstream); {$IFDEF GO32V2} For temp2 := 1 to fstream.count do If (fstream.stuff[temp2].name <> UPDIR_STR) then begin menudat[temp2] := ' '+ExpStrR(BaseNameOnly( FilterStr2(fstream.stuff[temp2].name,_valid_characters,'_')),8,' ')+' '+ ExpStrR(ExtOnly( fstream.stuff[temp2].name),3,' ')+' '; If (fstream.stuff[temp2].attr AND directory <> 0) then menudat[temp2] := iCASE(menudat[temp2]); end else begin menudat[temp2] := ExpStrR(' ..',mn_environment.descr_len,' '); fstream.stuff[temp2].name := '..'; end; For temp2 := 1 to fstream.count do If (fstream.stuff[temp2].attr = volumeid) then begin If (fstream.stuff[temp2].name = '~'+#255+'~') then descr[temp2] := '' else descr[temp2] := '[~DRiVE~]'; end else If (fstream.stuff[temp2].attr AND directory <> 0) then begin If fstream.stuff[temp2].name = '..' then descr[temp2] := ExpStrL('[UP-DiR]',mn_environment.descr_len-1,' ') else descr[temp2] := ExpStrL('[DiR]',mn_environment.descr_len-1,' ') end else begin temp7 := Num2str(fstream.stuff[temp2].size,10); descr[temp2] := ''; For temp8 := 1 to Length(temp7) do If (temp8 MOD 3 <> 0) or (temp8 = Length(temp7)) then descr[temp2] := temp7[Length(temp7)-temp8+1]+descr[temp2] else descr[temp2] := ','+temp7[Length(temp7)-temp8+1]+descr[temp2]; descr[temp2] := ExpStrL(descr[temp2],mn_environment.descr_len-1,' '); end; {$ELSE} For temp2 := 1 to fstream.count do If (fstream.stuff[temp2].attr AND directory <> 0) then If (fstream.stuff[temp2].name = UPDIR_STR) then begin menudat[temp2] := ' '+ExpStrR('..',24,' ')+' '; descr[temp2] := ExpStrL('[UP-DiR]',mn_environment.descr_len-1,' '); fstream.stuff[temp2].name := '..'; end else begin temp1 := 24+(mn_environment.descr_len-1-10); temp7 := iCASE_filename(DietStr(FilterStr2(fstream.stuff[temp2].name,_valid_characters_fname,'_'),temp1)); If (Length(temp7) < 24) then begin menudat[temp2] := ' '+ExpStrR(temp7,24,' ')+' '; descr[temp2] := ExpStrR('',mn_environment.descr_len-1-10,' '); end else begin menudat[temp2] := ' '+iCASE_filename(ExpStrR(Copy(temp7,1,24),24,' ')); descr[temp2] := ExpStrR(Copy(temp7,25,Length(temp7)-23),mn_environment.descr_len-1-10,' '); end; descr[temp2] := descr[temp2]+ExpStrL('[DiR]',10,' '); end else menudat[temp2] := ' '+ExpStrR(DietStr(BaseNameOnly( FilterStr2(fstream.stuff[temp2].name,_valid_characters_fname,'_')),23),23,' ')+' '; For temp2 := 1 to fstream.count do If (fstream.stuff[temp2].attr = volumeid) then begin If (fstream.stuff[temp2].name = '~'+#255+'~') then descr[temp2] := '' else descr[temp2] := '[~'+fstream.stuff[temp2].info+'~]'; end else If NOT (fstream.stuff[temp2].attr AND directory <> 0) then begin temp7 := Num2str(fstream.stuff[temp2].size,10); descr[temp2] := ''; For temp8 := 1 to Length(temp7) do If (temp8 MOD 3 <> 0) or (temp8 = Length(temp7)) then descr[temp2] := temp7[Length(temp7)-temp8+1]+descr[temp2] else descr[temp2] := ','+temp7[Length(temp7)-temp8+1]+descr[temp2]; descr[temp2] := ExpStrR(Copy(ExtOnly( fstream.stuff[temp2].name),1,3),3,' ')+' '+ ExpStrL(DietStr(descr[temp2],mn_environment.descr_len-1-4), mn_environment.descr_len-1-4,' '); end; {$ENDIF} For temp2 := 1 to fstream.count do If (SYSTEM.Pos('~',fstream.stuff[temp2].name) <> 0) and (fstream.stuff[temp2].name <> '~'+#255+'~') then While (SYSTEM.Pos('~',menudat[temp2]) <> 0) do menudat[temp2][SYSTEM.Pos('~',menudat[temp2])] := PATHSEP; temp5 := fstream.drive_count+DRIVE_DIVIDER; While (temp5 <= fstream.count) and (temp4 <> '') and (temp4 <> fstream.stuff[temp5].name) do Inc(temp5); If (temp5 > fstream.count) then temp5 := 1; For temp2 := 1 to fstream.count do If (Lower_filename(fstream.stuff[temp2].name) = fs_environment.last_file) and NOT (fstream.stuff[temp2].attr AND volumeid <> 0) then begin lastp := temp2; BREAK; end; If (Lower_filename(fstream.stuff[temp2].name) <> fs_environment.last_file) then lastp := 0; If (lastp = 0) or (lastp > MAX_FILES) then lastp := temp5; mn_setting.reverse_use := TRUE; mn_environment.context := ' ~'+Num2str(fstream.match_count,10)+' FiLES FOUND~ '; mn_setting.terminate_keys[3] := kBkSPC; {$IFDEF UNIX} mn_setting.terminate_keys[4] := kSlash; {$ELSE} mn_setting.terminate_keys[4] := kSlashR; {$ENDIF} mn_setting.terminate_keys[5] := kF1; old_fselect_external_proc := mn_environment.ext_proc; mn_environment.ext_proc := new_fselect_external_proc; temp := 1; While (temp < fstream.count) and (SYSTEM.Pos('[UP-DiR]',descr[temp]) = 0) do Inc(temp); If (temp < fstream.count) then mn_setting.homing_pos := temp else mn_setting.homing_pos := fstream.drive_count+DRIVE_DIVIDER; {$IFDEF UNIX} Dec(fstream.count); {$ENDIF} {$IFDEF GO32V2} temp2 := Menu(menudat,01,01,lastp, 1+12+1,AdT2unit.max(work_MaxLn-7,30),fstream.count,' '+ iCASE(DietStr(path_filter(temp3),28)+' ')); {$ELSE} temp2 := Menu(menudat,01,01,lastp, 1+23+1,AdT2unit.max(work_MaxLn-5,30),fstream.count,' '+ iCASE(DietStr(FilterStr2(path_filter(temp3),_valid_characters_fname,'_'),38))+' '); {$ENDIF} mn_environment.ext_proc := old_fselect_external_proc; mn_setting.reverse_use := FALSE; mn_environment.context := ''; mn_setting.terminate_keys[3] := 0; mn_setting.terminate_keys[4] := 0; mn_setting.terminate_keys[5] := 0; If (mn_environment.keystroke = kENTER) and (fstream.stuff[temp2].attr AND directory <> 0) then begin fs_environment.last_file := 'FNAME:EXT'; mn_environment.keystroke := WORD_NULL; If (fstream.stuff[temp2].name = '..') then begin Delete(temp3,Length(temp3),1); temp4 := NameOnly(temp3); While (temp3[Length(temp3)] <> PATHSEP) do Delete(temp3,Length(temp3),1); fs_environment.last_file := Lower_filename(temp4); end else begin temp3 := temp3+fstream.stuff[temp2].name+PATHSEP; temp4 := ''; fs_environment.last_file := temp4; end; {$i-} ChDir(Copy(temp3,1,Length(temp3)-1)); {$i+} If (IOresult <> 0) then ; end else If (mn_environment.keystroke = kENTER) and (fstream.stuff[temp2].attr AND volumeid <> 0) then begin fs_environment.last_file := 'FNAME:EXT'; mn_environment.keystroke := WORD_NULL; {$i-} ChDir(path[SUCC(ORD(UpCase(fstream.stuff[temp2].name[1]))-ORD('A'))]); {$i+} If (IOresult <> 0) then temp3 := path[SUCC(ORD(UpCase(fstream.stuff[temp2].name[1]))-ORD('A'))] else begin {$i-} GetDir(0,temp3); {$i+} If (IOresult <> 0) then temp3 := temp6; end; If (temp3[Length(temp3)] <> PATHSEP) then temp3 := temp3+PATHSEP; temp4 := ''; fs_environment.last_file := temp4; end else If (mn_environment.keystroke = kBkSPC) then If shift_pressed then begin If (home_dir_path <> '') then temps := home_dir_path else temps := PathOnly(ParamStr(0)); If (temps[Length(temps)] <> PATHSEP) then temps := temps+'\'; {$i-} ChDir(Copy(temps,1,Length(temps)-1)); {$i+} If (IOresult = 0) then begin temp3 := temps; temp4 := '..'; end else begin {$i-} ChDir(temp3); {$i+} If (IOresult <> 0) then ; end; end else If (SYSTEM.Pos(PATHSEP,Copy(temp3,3,Length(temp3)-3)) <> 0) then begin Delete(temp3,Length(temp3),1); temp4 := NameOnly(temp3); While (temp3[Length(temp3)] <> PATHSEP) do Delete(temp3,Length(temp3),1); fs_environment.last_file := Lower_filename(temp4); {$i-} ChDir(Copy(temp3,1,Length(temp3)-1)); {$i+} If (IOresult <> 0) then ; end else {$IFDEF UNIX} else If (mn_environment.keystroke = kSlash) then {$ELSE} else If (mn_environment.keystroke = kSlashR) then {$ENDIF} begin temp3 := Copy(temp3,1,3); temp4 := ''; fs_environment.last_file := temp4; {$i-} ChDir(Copy(temp3,1,Length(temp3)-1)); {$i+} If (IOresult <> 0) then ; end else fs_environment.last_file := Lower_filename(fstream.stuff[temp2].name); until (mn_environment.keystroke = kENTER) or (mn_environment.keystroke = kESC) or (mn_environment.keystroke = kF1); mn_environment.descr_len := 0; mn_environment.descr := NIL; mn_environment.winshade := TRUE; mn_setting.frame_enabled := TRUE; mn_setting.shadow_enabled := TRUE; mn_setting.homing_pos := 0; move_to_screen_data := ptr_scr_backup; move_to_screen_area[1] := mn_environment.xpos; move_to_screen_area[2] := mn_environment.ypos; move_to_screen_area[3] := mn_environment.xpos+mn_environment.xsize+2+1; move_to_screen_area[4] := mn_environment.ypos+mn_environment.ysize+1; move2screen; If (mn_environment.keystroke = kF1) then begin HELP('file_browser'); GOTO _jmp1; end; Fselect := temp3+fstream.stuff[temp2].name; fs_environment.last_dir := path[SUCC(ORD(UpCase(temp3[1]))-ORD('A'))]; {$i-} ChDir(temp6); {$i+} If (IOresult <> 0) then ; If (mn_environment.keystroke = kESC) then Fselect := ''; end; function _partial(max,val: Word; base: Byte): Word; var temp1,temp2: Real; temp3: Word; 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 HScrollBar(dest: tSCREEN_MEM_PTR; x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Word; var temp: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:HScrollBar'; {$ENDIF} 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) then begin HScrollBar := temp; EXIT; end; If (size < len1) then begin pos := temp; ShowStr(dest,x,y,#17+ExpStrL('',size-2,#176)+#16,atr1); If (size-2-1 < 10) then ShowStr(dest,x+1+temp,y,#178,atr2) else ShowStr(dest,x+1+temp,y,#178#178#178,atr2); end else ShowCStr(dest,x,y,'~'#17'~'+ExpStrL('',size-2,#177)+'~'#16'~',atr2,atr1); HScrollBar := pos; end; function VScrollBar(dest: tSCREEN_MEM_PTR; x,y: Byte; size: Byte; len1,len2,pos: Word; atr1,atr2: Byte): Word; var temp: Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:VScrollBar'; {$ENDIF} 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) then begin VScrollBar := temp; EXIT; end; If (size < len1) then begin pos := temp; ShowVStr(dest,x,y,#30+ExpStrL('',size-2,#176)+#31,atr1); If (size-2-1 < 10) then ShowStr(dest,x,y+1+temp,#178,atr2) else ShowVStr(dest,x,y+1+temp,#178#178#178,atr2); end else ShowVCStr(dest,x,y,'~'#30'~'+ExpStrL('',size-2,#177)+'~'#31'~',atr2,atr1); VScrollBar := pos; end; procedure DialogIO_Init; var index: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'DIALOGIO.PAS:DialogIO_Init'; {$ENDIF} dl_setting.frame_type := frame_double; dl_setting.title_attr := dialog_background+dialog_title; dl_setting.box_attr := dialog_background+dialog_border; dl_setting.text_attr := dialog_background+dialog_text; dl_setting.text2_attr := dialog_background+dialog_hi_text; dl_setting.keys_attr := dialog_background+dialog_item; dl_setting.keys2_attr := dialog_sel_itm_bck+dialog_sel_itm; dl_setting.short_attr := dialog_background+dialog_short; dl_setting.short2_attr := dialog_sel_itm_bck+dialog_sel_short; dl_setting.disbld_attr := dialog_background+dialog_item_dis; dl_setting.contxt_attr := dialog_background+dialog_context; dl_setting.contxt2_attr := dialog_background+dialog_context_dis; mn_setting.frame_type := frame_double; mn_setting.title_attr := dialog_background+dialog_title; mn_setting.menu_attr := dialog_background+dialog_border; mn_setting.text_attr := dialog_background+dialog_item; mn_setting.text2_attr := dialog_sel_itm_bck+dialog_sel_itm; mn_setting.default_attr := dialog_def_bckg+dialog_def; mn_setting.short_attr := dialog_background+dialog_short; mn_setting.short2_attr := dialog_sel_itm_bck+dialog_sel_short; mn_setting.disbld_attr := dialog_background+dialog_item_dis; mn_setting.contxt_attr := dialog_background+dialog_context; mn_setting.contxt2_attr := dialog_background+dialog_context_dis; mn_setting.topic_attr := dialog_background+dialog_topic; mn_setting.hi_topic_attr := dialog_background+dialog_hi_topic; mn_setting.topic_mask_chr := []; mn_environment.v_dest := screen_ptr; dl_environment.keystroke := $0000; mn_environment.keystroke := $0000; dl_environment.context := ''; mn_environment.context := ''; mn_environment.unpolite := FALSE; dl_environment.input_str := ''; mn_environment.winshade := TRUE; mn_environment.intact_area := FALSE; mn_environment.ext_proc := NIL; mn_environment.ext_proc_rt := NIL; mn_environment.refresh := NIL; mn_environment.do_refresh := FALSE; mn_environment.own_refresh := FALSE; mn_environment.preview := FALSE; mn_environment.fixed_start := 0; mn_environment.descr_len := 0; mn_environment.descr := NIL; mn_environment.is_editing := FALSE; fs_environment.last_file := 'FNAME:EXT'; fs_environment.last_dir := ''; mn_environment.xpos := 0; mn_environment.xpos := 0; mn_environment.xsize := 0; mn_environment.ysize := 0; mn_environment.desc_pos := 0; mn_environment.hlight_chrs := 0; dl_environment.xpos := 0; dl_environment.ypos := 0; dl_environment.xsize := 0; dl_environment.ysize := 0; dl_environment.cur_item := 1; dl_environment.ext_proc := NIL; For index := 1 to 26 do path[index] := CHR(ORD('a')+PRED(index))+':'+PATHSEP; end; end. adlibtracker2-2.4.24/adtrack2.rc0000644000000000000000000000003713411003760015026 0ustar rootrootAdT2_icon ICON "progicon.ico" adlibtracker2-2.4.24/parserio.pas0000644000000000000000000002007613411003760015343 0ustar rootroot// 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 Scan(var buf; skip,size: Longint; str: String): Longint; function SensitiveScan(var buf; skip,size: Longint; str: String): Longint; function Compare(var buf1,buf2; size: Longint): Boolean; function Empty(var buf; size: Longint): Boolean; function CountLines(var buf; size: Longint): Longint; function Update16(var buf; size: Longint; crc: Word): Word; function Update32(var buf; size: Longint; crc: Longint): Longint; implementation uses StringIO; var CRC16_table: array[BYTE] of Word; CRC32_table: array[BYTE] of Longint; function Scan(var buf; skip,size: Longint; str: String): Longint; var result: Longint; begin asm lea edi,[str] mov esi,edi xor eax,eax lodsb stosb xor ecx,ecx mov ecx,eax xor ebx,ebx mov ebx,eax jecxz @@9 @@1: lodsb cmp al,'a' jb @@2 cmp al,'z' ja @@2 sub al,20h @@2: stosb loop @@1 sub edi,ebx mov esi,[buf] add esi,skip mov ecx,size sub ecx,skip jecxz @@8 cld sub ecx,ebx jb @@8 inc ecx @@4: mov ah,[edi] and ah,NOT 20h @@5: lodsb and al,NOT 20h cmp al,ah loopne @@5 jne @@8 dec esi mov edx,ecx mov ecx,ebx @@6: repe cmpsb je @@10 mov al,[esi-1] cmp al,'a' jb @@7 cmp al,'z' ja @@7 sub al,20h @@7: cmp al,[edi-1] je @@6 sub ecx,ebx add esi,ecx add edi,ecx inc esi mov ecx,edx jne @@4 @@8: xor eax,eax jmp @@11 @@9: mov eax,1 jmp @@11 @@10: sub esi,ebx mov eax,esi sub eax,dword ptr [buf] inc eax @@11: dec eax mov result,eax end; Scan := result; end; 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; function Compare(var buf1,buf2; 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 esi,[buf1] mov edi,[buf2] cld repz cmpsd jnz @@2 mov ecx,edx jecxz @@1 repz cmpsb jnz @@2 @@1: mov result,TRUE jmp @@6 @@2: mov result,FALSE jmp @@6 @@3: mov ecx,size jecxz @@4 mov esi,[buf1] mov edi,[buf2] cld repz cmpsb jnz @@5 @@4: mov result,TRUE jmp @@6 @@5: mov result,FALSE @@6: end; Compare := result; end; function 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; Empty := result; end; function CountLines(var buf; size: Longint): Longint; var result: Longint; begin asm mov edi,[buf] mov ecx,size mov edx,edi add edx,ecx xor ebx,ebx jecxz @@3 @@1: mov al,0dh repnz scasb jnz @@3 cmp byte ptr [edi],0ah jnz @@2 inc edi inc ebx @@2: cmp edi,edx jb @@1 @@3: mov eax,ebx mov result,eax end; CountLines := result; end; 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/adt2ext5.pas0000644000000000000000000051537613411003760015173 0ustar rootroot// 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 AdT2ext5; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const arp_tab_selected: Boolean = FALSE; vib_tab_selected: Boolean = FALSE; var ptr_arpeggio_table: Byte; ptr_vibrato_table: Byte; procedure bnk_file_loader; procedure fib_file_loader; procedure ibk_file_loader; procedure bnk_file_loader_alt(instr: Word); procedure fib_file_loader_alt(instr: Word); procedure ibk_file_loader_alt(instr: Word); procedure a2b_file_loader(bankSelector: Boolean; loadBankPossible: Boolean); procedure a2w_file_loader(loadFromFile: Boolean; loadMacros: Boolean; bankSelector: Boolean; loadBankPossible: Boolean; updateCurInstr: Boolean); implementation uses {$IFNDEF UNIX} CRT, {$ENDIF} {$IFDEF GO32V2} GO32, {$ELSE} SDL_Timer, {$ENDIF} DOS, AdT2opl3,AdT2sys,AdT2keyb,AdT2unit,AdT2extn,AdT2ext2,AdT2ext3,AdT2ext4,AdT2text,AdT2pack, StringIO,DialogIO,ParserIO,TxtScrIO,DepackIO; procedure a2b_lister_external_proc; forward; procedure a2w_lister_external_proc_callback; forward; procedure a2w_macro_lister_external_proc_callback; forward; procedure bnk_lister_external_proc; forward; procedure fib_lister_external_proc; forward; procedure ibk_lister_external_proc; forward; var xstart,ystart: Byte; window_xsize,window_ysize: Byte; context_str,context_str2,context_str3: String; var temp_marks: array[1..255] of Char; a2b_queue: array[1..255+3] of String[74]; a2b_queue_more: array[1..255+3] of String[104]; a2w_queue: array[1..255+3] of String[72]; a2w_queue_more: array[1..255+3] of String[102]; a2w_queue_more2: array[1..255+3] of String[121]; a2w_queue_m: array[1..255+5] of String[72]; a2w_institle_pos: Byte; update_current_inst: Boolean; var xstart_arp,ystart_arp,xstart_vib,ystart_vib: Byte; scrollbar_xstart,scrollbar_ystart,scrollbar_size: Byte; macro_table_size: Byte; arpeggio_table_idx,vibrato_table_idx: Byte; arpeggio_table_pos,vibrato_table_pos: Byte; procedure import_old_instruments(old_songdata: pOLD_FIXED_SONGDATA; new_songdata: pFIXED_SONGDATA; instr,count: Byte); var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:import_old_instruments'; {$ENDIF} For temp := instr to instr+PRED(count) do begin new_songdata^.instr_names[temp] := Copy(new_songdata^.instr_names[temp],1,9)+ Copy(old_songdata^.instr_names[temp],10,22); new_songdata^.instr_data[temp].fm_data := old_songdata^.instr_data[temp].fm_data; new_songdata^.instr_data[temp].panning := old_songdata^.instr_data[temp].panning; new_songdata^.instr_data[temp].fine_tune := old_songdata^.instr_data[temp].fine_tune; new_songdata^.instr_data[temp].perc_voice := 0; end; end; function count_instruments: Byte; var result: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:count_instruments'; {$ENDIF} result := 255; While (result > 0) and Empty(temp_songdata.instr_data[result],INSTRUMENT_SIZE) and (CutStr(Copy(temp_songdata.instr_names[result],10,32)) = '') do Dec(result); count_instruments := result; end; function count_macros: Byte; var result: Byte; begin result := 255; While (result > 0) and Empty(temp_songdata.macro_table[result].arpeggio, SizeOf(tARPEGGIO_TABLE)) and Empty(temp_songdata.macro_table[result].vibrato, SizeOf(tVIBRATO_TABLE)) do Dec(result); count_macros := result; end; function get_free_arpeggio_table_idx(data: tARPEGGIO_TABLE): Byte; var result: Byte; free_flag: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:get_free_arpeggio_table_idx'; {$ENDIF} result := 0; free_flag := FALSE; // first try to find empty space or same macro for overwriting Repeat Inc(result); If Empty(songdata.macro_table[result].arpeggio, SizeOf(tARPEGGIO_TABLE)) or Compare(songdata.macro_table[result].arpeggio,data, SizeOf(tARPEGGIO_TABLE)) then free_flag := TRUE; until free_flag or (result = 255); // next to find dummy macro (length=0) for overwriting If NOT free_flag then Repeat If (temp_songdata.macro_table[result].arpeggio.length = 0) then free_flag := TRUE else Dec(result); until free_flag or (result = 0); get_free_arpeggio_table_idx := result; end; function get_free_vibrato_table_idx(data: tVIBRATO_TABLE): Byte; var result: Byte; free_flag: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:get_free_vibrato_table_idx'; {$ENDIF} result := 0; free_flag := FALSE; // first try to find empty space or same macro for overwriting Repeat Inc(result); If Empty(songdata.macro_table[result].vibrato, SizeOf(tViBRATO_TABLE)) or Compare(songdata.macro_table[result].vibrato,data, SizeOf(tVIBRATO_TABLE)) then free_flag := TRUE; until free_flag or (result = 255); // next to find dummy macro (length=0) for overwriting If NOT free_flag then Repeat If (temp_songdata.macro_table[result].vibrato.length = 0) then free_flag := TRUE else Dec(result); until free_flag or (result = 0); get_free_vibrato_table_idx := result; end; function _gfx_bar_str(value: Byte; neg: Boolean): String; var result: String; begin result := ''; If NOT neg then Repeat If (value > 15) then begin result := result+#219; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := result+CHR(127+value) until (value <= 15) else Repeat If (value > 15) then begin result := #219+result; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := CHR(158-value)+result; until (value <= 15); _gfx_bar_str := flipstr(result); end; const _4op_flag_chr_beg = #172; _4op_flag_chr_end = #173; _4op_flag_chars: Set of Char = [_4op_flag_chr_beg,_4op_flag_chr_end]; _4op_flag_column: array[1..255] of Char = ''; _a2b_lister_count: Byte = 0; _a2w_lister_count: Byte = 0; var _4op_idx11,_4op_idx12, _4op_idx21,_4op_idx22: Byte; _4op_ins_flag: Boolean; function check_4op_flag_temp(ins: Byte): Boolean; var result: Boolean; idx: Byte; begin result := FALSE; For idx := 1 to temp_songdata.ins_4op_flags.num_4op do If (temp_songdata.ins_4op_flags.idx_4op[idx] = ins) then begin result := TRUE; BREAK; end; check_4op_flag_temp := result; end; function get_4op_to_test_temp: Word; var result: Word; curr_inst: Byte; begin result := 0; curr_inst := mn_environment.curr_pos; If (curr_inst in [1..255]) and (songdata.flag_4op <> 0) then If (_4op_flag_column[curr_inst] = _4op_flag_chr_beg) then result := SUCC(curr_inst)+curr_inst SHL 8 else If (curr_inst > 1) and (_4op_flag_column[curr_inst] = _4op_flag_chr_end) then result := curr_inst+PRED(curr_inst) SHL 8; get_4op_to_test_temp := result; end; procedure a2b_lister_external_proc_callback; forward; procedure a2b_lister_external_proc; var temp: Byte; attr: Byte; begin For temp := 1 to _a2b_lister_count do begin If (mn_environment.curr_pos = mn_environment.curr_page+temp-1) then attr := mn_setting.text2_attr else attr := mn_setting.text_attr; ShowStr(mn_environment.v_dest,mn_environment.xpos+1,mn_environment.ypos+3+temp, _4op_flag_column[mn_environment.curr_page+temp-1], attr); end; a2b_lister_external_proc_callback; end; procedure a2b_file_loader(bankSelector: Boolean; loadBankPossible: Boolean); type tOLD_HEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; type tHEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; const id = '_A2insbank_'; var f: File; header: tOLD_HEADER; header2: tHEADER; crc,temp: Longint; old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; idx,index,nm_valid: Byte; temp_str: String; ysize: Byte; const new_keys: array[1..3] of Word = (kESC,kENTER,kCtENTR); var old_keys: array[1..3] of Word; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2b_file_loader'; {$ENDIF} progress_num_steps := 0; progress_step := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; temp_songdata := songdata; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2B]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; init_old_songdata; If (header.ffver in [1..4]) then begin FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,2,crc); crc := Update32(buf1,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; Case header.ffver of 4: Move(buf1,old_songdata.instr_names,header.b0len); 3: LZSS_decompress(buf1,old_songdata.instr_names,header.b0len); 2: LZW_decompress(buf1,old_songdata.instr_names); 1: SIXPACK_decompress(buf1,old_songdata.instr_names,header.b0len); end; For temp := 1 to 250 do old_songdata.instr_data[temp].panning := 0; import_old_instruments(Addr(old_songdata),Addr(temp_songdata),1,250); end; If (header.ffver in [5..8]) then begin FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,2,crc); crc := Update32(buf1,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; Case header.ffver of 8: Move(buf1,old_songdata.instr_names,header.b0len); 7: LZSS_decompress(buf1,old_songdata.instr_names,header.b0len); 6: LZW_decompress(buf1,old_songdata.instr_names); 5: SIXPACK_decompress(buf1,old_songdata.instr_names,header.b0len); end; import_old_instruments(Addr(old_songdata),Addr(temp_songdata),1,250); end; If (header.ffver = 9) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header2.b0len,2,crc); crc := Update32(buf1,header2.b0len,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; APACK_decompress(buf1,temp_songdata.instr_names); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); end; If (header.ffver = FFVER_A2B) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header2.b0len,2,crc); crc := Update32(buf1,header2.b0len,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2B LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; progress_num_steps := 0; LZH_decompress(buf1,buf2,header2.b0len); Move(buf2,temp_songdata.instr_names,SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)); Move(buf2[SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)],temp_songdata.ins_4op_flags, SizeOf(songdata.ins_4op_flags)); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); end; FillChar(temp_songdata.dis_fmreg_col,SizeOf(temp_songdata.dis_fmreg_col),FALSE); CloseF(f); If NOT bankSelector then begin songdata.instr_names := temp_songdata.instr_names; songdata.instr_data := temp_songdata.instr_data; load_flag := 1; EXIT; end; // init 4OP flags FillChar(_4op_flag_column,SizeOf(_4op_flag_column),0); For temp := 1 to PRED(255) do If check_4op_flag_temp(temp) then begin If NOT (_4op_flag_column[temp] in _4op_flag_chars) then _4op_flag_column[temp] := _4op_flag_chr_beg; If NOT (_4op_flag_column[SUCC(temp)] in _4op_flag_chars) then _4op_flag_column[SUCC(temp)] := _4op_flag_chr_end; end; a2b_queue[1] := a2b_header_str[1]; a2b_queue[2] := a2b_header_str[2]; a2b_queue[3] := a2b_header_str[3]; a2b_queue_more[1] := a2b_header_hires_str[1]; a2b_queue_more[2] := a2b_header_hires_str[2]; a2b_queue_more[3] := a2b_header_hires_str[3]; nm_valid := count_instruments; If (nm_valid = 0) then nm_valid := 1; For idx := 1 to nm_valid do begin a2b_queue[3+idx] := '~'+ExpStrR(Copy(temp_songdata.instr_names[idx],1,9)+'~'+ Copy(temp_songdata.instr_names[idx],10,32),45,' '); a2b_queue_more[3+idx] := a2b_queue[3+idx]; With temp_songdata.instr_data[idx].fm_data do begin a2b_queue_more[3+idx] := a2b_queue_more[3+idx]+ byte2hex(AM_VIB_EG_carrier)+ byte2hex(AM_VIB_EG_modulator)+' '+ byte2hex(KSL_VOLUM_carrier)+ byte2hex(KSL_VOLUM_modulator)+' '+ byte2hex(ATTCK_DEC_carrier)+ byte2hex(ATTCK_DEC_modulator)+' '+ byte2hex(SUSTN_REL_carrier)+ byte2hex(SUSTN_REL_modulator)+' '+ byte2hex(WAVEFORM_carrier)+ byte2hex(WAVEFORM_modulator)+' '+ byte2hex(FEEDBACK_FM)+' '; end; Case temp_songdata.instr_data[idx].panning of 0..2: temp_str := ins_pan_str2[temp_songdata.instr_data[idx].panning]; else temp_str := ExpStrL('',7,#250); end; a2b_queue[3+idx] := a2b_queue[3+idx]+temp_str+' '; a2b_queue_more[3+idx] := a2b_queue_more[3+idx]+temp_str+' '; If (temp_songdata.instr_data[idx].fine_tune > 0) then temp_str := '+'+ExpStrR(Num2str(temp_songdata.instr_data[idx].fine_tune,16),5,' ') else If (temp_songdata.instr_data[idx].fine_tune < 0) then temp_str := '-'+ExpStrR(Num2str(0-temp_songdata.instr_data[idx].fine_tune,16),5,' ') else temp_str := ExpStrR('',6,' '); a2b_queue[3+idx] := a2b_queue[3+idx]+temp_str+' '; a2b_queue_more[3+idx] := a2b_queue_more[3+idx]+temp_str+' '; Case temp_songdata.instr_data[idx].perc_voice of 0..5: temp_str := perc_voice_str[temp_songdata.instr_data[idx].perc_voice]; else temp_str := ExpStrL('',7,' '); end; a2b_queue[3+idx] := a2b_queue[3+idx]+temp_str; a2b_queue_more[3+idx] := a2b_queue_more[3+idx]+temp_str; end; Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); mn_environment.ext_proc := a2b_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; If loadBankPossible then mn_environment.context := ' ~[~'+Num2str(nm_valid,10)+'~/255]~ ^ENTER '#196#16' LOAD COMPLETE BANK ' else mn_environment.context := '~[~'+Num2str(nm_valid,10)+'~/255]~'; keyboard_reset_buffer; If is_default_screen_mode then ysize := 20 else ysize := 30; _a2b_lister_count := ysize-3; If NOT _force_program_quit then If (program_screen_mode in [0,3,4,5]) then index := Menu(a2b_queue,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 74,ysize,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' ') else index := Menu(a2b_queue_more,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 104,30,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' '); add_bank_position(instdata_source,nm_valid,index+3); Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; If (mn_environment.keystroke = kENTER) or (loadBankPossible and (mn_environment.keystroke = kCtENTR)) then begin If (mn_environment.keystroke = kENTER) then begin If shift_pressed then begin // put 4op instrument (alternate) _4op_ins_flag := FALSE; If (_4op_flag_column[index] = _4op_flag_chr_beg) then If check_4op_flag(current_inst) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else If check_4op_flag(PRED(current_inst)) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else else If (_4op_flag_column[index] = _4op_flag_chr_end) then If check_4op_flag(current_inst) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := PRED(index); _4op_idx22 := index; end else If check_4op_flag(PRED(current_inst)) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := PRED(index); _4op_idx22 := index; end; If _4op_ins_flag then begin songdata.instr_data[_4op_idx11] := temp_songdata.instr_data[_4op_idx21]; songdata.instr_names[_4op_idx11] := Copy(songdata.instr_names[_4op_idx11],1,9)+ Copy(temp_songdata.instr_names[_4op_idx21],10,32); songdata.instr_data[_4op_idx12] := temp_songdata.instr_data[_4op_idx22]; songdata.instr_names[_4op_idx12] := Copy(songdata.instr_names[_4op_idx12],1,9)+ Copy(temp_songdata.instr_names[_4op_idx22],10,32); end; end else begin // put 4op instrument (force) _4op_ins_flag := FALSE; If (_4op_flag_column[index] = _4op_flag_chr_beg) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else If (_4op_flag_column[index] = _4op_flag_chr_end) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := PRED(index); _4op_idx22 := index; end; If _4op_ins_flag then begin songdata.instr_data[_4op_idx11] := temp_songdata.instr_data[_4op_idx21]; songdata.instr_names[_4op_idx11] := Copy(songdata.instr_names[_4op_idx11],1,9)+ Copy(temp_songdata.instr_names[_4op_idx21],10,32); songdata.instr_data[_4op_idx12] := temp_songdata.instr_data[_4op_idx22]; songdata.instr_names[_4op_idx12] := Copy(songdata.instr_names[_4op_idx12],1,9)+ Copy(temp_songdata.instr_names[_4op_idx22],10,32); set_4op_flag(_4op_idx11); end; end; // put 2op instrument If NOT _4op_ins_flag then begin songdata.instr_data[current_inst] := temp_songdata.instr_data[index]; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(temp_songdata.instr_names[index],10,32); end; end else begin songdata.instr_data := temp_songdata.instr_data; songdata.ins_4op_flags := temp_songdata.ins_4op_flags; For idx := 1 to 255 do songdata.instr_names[idx] := Copy(songdata.instr_names[idx],1,9)+ Copy(temp_songdata.instr_names[idx],10,32); end; load_flag := 1; load_flag_alt := BYTE_NULL; end; keyboard_reset_buffer; end; procedure _macro_preview_refresh; var temp,max_value: Integer; d_factor: Real; function arpeggio_def_attr(page: Byte): Word; var attr, attr2: Byte; begin If (page <= temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.length) then If (page >= temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_begin) and (page <= temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_begin+ PRED(temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_length)) and (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_begin > 0) and (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.keyoff_pos) and (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; arpeggio_def_attr := attr+attr2 SHL 8; end; function vibrato_def_attr(page: Byte): Word; var attr, attr2: Byte; begin If (page <= temp_songdata.macro_table[vibrato_table_idx]. vibrato.length) then If (page >= temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_begin) and (page <= temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_begin+ PRED(temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_length)) and (temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_begin > 0) and (temp_songdata.macro_table[vibrato_table_idx]. vibrato.loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= temp_songdata.macro_table[vibrato_table_idx]. vibrato.keyoff_pos) and (temp_songdata.macro_table[vibrato_table_idx]. vibrato.keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; vibrato_def_attr := attr+attr2 SHL 8; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_macro_preview_refresh'; {$ENDIF} // arpeggio preview ShowStr(centered_frame_vdest,xstart_arp+15,ystart_arp, #253, macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart_arp+15,ystart_arp+7, #252, macro_background+macro_topic2); ShowVStr(centered_frame_vdest,xstart_arp,ystart_arp+1, #179#179#179#179#179#158, macro_background+macro_text); ShowVStr(centered_frame_vdest,xstart_arp+30,ystart_arp+1, #179#179#179#179#179#158, macro_background+macro_text); max_value := 0; For temp := 1 to 255 do If (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[temp] > max_value) then If (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[temp] < $80) then max_value := Abs(temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[temp]); ShowStr(centered_frame_vdest,xstart_arp+31,ystart_arp+1, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart_arp+31,ystart_arp+2, '+', macro_background+macro_topic); d_factor := 90/min(max_value,1); For temp := -14 to 14 do If (arpeggio_table_pos+temp >= 1) and (arpeggio_table_pos+temp <= 255) then If (temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[arpeggio_table_pos+temp] < $80) then ShowVStr(centered_frame_vdest,xstart_arp+15+temp,ystart_arp+1, ExpStrL(_gfx_bar_str(Round(temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[arpeggio_table_pos+temp]*d_factor),FALSE),6,' '), LO(arpeggio_def_attr(arpeggio_table_pos+temp))) else ShowVStr(centered_frame_vdest,xstart_arp+15+temp,ystart_arp+1, ExpStrL(FilterStr(note_layout[temp_songdata.macro_table[arpeggio_table_idx]. arpeggio.data[arpeggio_table_pos+temp]-$80],'-',#241),6,' '), LO(arpeggio_def_attr(arpeggio_table_pos+temp))) else ShowVStr(centered_frame_vdest,xstart_arp+15+temp,ystart_arp+1, ExpStrL('',6,' '), macro_background+macro_text); // vibrato preview ShowStr(centered_frame_vdest,xstart_vib+15,ystart_vib, #253, macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart_vib+15,ystart_vib+7, #252, macro_background+macro_topic2); ShowVStr(centered_frame_vdest,xstart_vib,ystart_vib+1, #179#179#158#179#179#179, macro_background+macro_text); ShowVStr(centered_frame_vdest,xstart_vib+30,ystart_vib+1, #179#179#158#179#179#179, macro_background+macro_text); max_value := 0; For temp := 1 to 255 do If (Abs(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[temp]) > max_value) then max_value := Abs(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[temp]); ShowStr(centered_frame_vdest,xstart_vib+31,ystart_vib+1, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart_vib+31,ystart_vib+2, '+', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart_vib+31,ystart_vib+5, '-', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart_vib+31,ystart_vib+6, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_topic); d_factor := 45/min(max_value,1); For temp := -14 to 14 do If (vibrato_table_pos+temp >= 1) and (vibrato_table_pos+temp <= 255) then If (Round(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[vibrato_table_pos+temp]*d_factor) >= 0) then ShowVStr(centered_frame_vdest,xstart_vib+15+temp,ystart_vib+1, ExpStrR(ExpStrL(_gfx_bar_str(Round(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[vibrato_table_pos+temp]*d_factor),FALSE),3,' '),6,' '), LO(vibrato_def_attr(vibrato_table_pos+temp))) else ShowVStr(centered_frame_vdest,xstart_vib+15+temp,ystart_vib+1, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(temp_songdata.macro_table[vibrato_table_idx]. vibrato.data[vibrato_table_pos+temp])*d_factor),TRUE),3,' '),6,' '), LO(vibrato_def_attr(vibrato_table_pos+temp))) else ShowVStr(centered_frame_vdest,xstart_vib+15+temp,ystart_vib+1, ExpStrR('',6,' '), macro_background+macro_text); end; procedure a2w_macro_lister_external_proc; const _check_chr: array[BOOLEAN] of Char = (#251,' '); var temp,idx: Byte; attr,attr2,attr3: Byte; temps: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_macro_lister_external_proc'; {$ENDIF} temps := Copy(mn_environment.curr_item,2,2); idx := Str2num(temps,16); If (idx = 0) then idx := 1; VScrollBar(centered_frame_vdest,scrollbar_xstart,scrollbar_ystart, scrollbar_size,macro_table_size,idx,WORD_NULL, macro_background+macro_border, macro_background+macro_border); arpeggio_table_idx := idx; vibrato_table_idx := idx; Case mn_environment.keystroke of kSPACE: begin If shift_pressed then begin arp_tab_selected := NOT arp_tab_selected; If alt_pressed then begin temp_songdata.instr_macros[current_inst].arpeggio_table := 0; arp_tab_selected := FALSE; end; If arp_tab_selected then temp_songdata.instr_macros[current_inst].arpeggio_table := arpeggio_table_idx else If NOT alt_pressed then temp_songdata.instr_macros[current_inst].arpeggio_table := songdata.instr_macros[current_inst].arpeggio_table; end; If ctrl_pressed then begin vib_tab_selected := NOT vib_tab_selected; If alt_pressed then begin temp_songdata.instr_macros[current_inst].vibrato_table := 0; vib_tab_selected := FALSE; end; If vib_tab_selected then temp_songdata.instr_macros[current_inst].vibrato_table := vibrato_table_idx else If NOT alt_pressed then temp_songdata.instr_macros[current_inst].vibrato_table := songdata.instr_macros[current_inst].vibrato_table; end; end; kESC: begin temp_songdata.instr_macros[current_inst].arpeggio_table := songdata.instr_macros[current_inst].arpeggio_table; temp_songdata.instr_macros[current_inst].vibrato_table := songdata.instr_macros[current_inst].vibrato_table; EXIT; end; kENTER: begin If NOT arp_tab_selected and (temp_songdata.instr_macros[current_inst].arpeggio_table = 0) then songdata.instr_macros[current_inst].arpeggio_table := 0; If NOT vib_tab_selected and (temp_songdata.instr_macros[current_inst].vibrato_table = 0) then songdata.instr_macros[current_inst].vibrato_table := 0; EXIT; end; kLEFT, kShLEFT: If shift_pressed then If (arpeggio_table_pos > 1) then Dec(arpeggio_table_pos); kCtLEFT: begin If shift_pressed then If (arpeggio_table_pos > 1) then Dec(arpeggio_table_pos); If (vibrato_table_pos > 1) then Dec(vibrato_table_pos); end; kRIGHT, kShRGHT: If shift_pressed then If (arpeggio_table_pos < 255) then Inc(arpeggio_table_pos); kCtRGHT: begin If shift_pressed then If (arpeggio_table_pos < 255) then Inc(arpeggio_table_pos); If (vibrato_table_pos < 255) then Inc(vibrato_table_pos); end; kPgUP: If shift_pressed then If (arpeggio_table_pos-18 > 1) then Dec(arpeggio_table_pos,18) else arpeggio_table_pos := 1; kCtPgUP: begin If shift_pressed then If (arpeggio_table_pos-18 > 1) then Dec(arpeggio_table_pos,18) else arpeggio_table_pos := 1; If (vibrato_table_pos-18 > 1) then Dec(vibrato_table_pos,18) else vibrato_table_pos := 1; end; kPgDOWN: If shift_pressed then If (arpeggio_table_pos+18 < 255) then Inc(arpeggio_table_pos,18) else arpeggio_table_pos := 255; kCtPgDN: begin If shift_pressed then If (arpeggio_table_pos+18 < 255) then Inc(arpeggio_table_pos,18) else arpeggio_table_pos := 255; If (vibrato_table_pos+18 < 255) then Inc(vibrato_table_pos,18) else vibrato_table_pos := 255; end; kHOME: If shift_pressed then If (arpeggio_table_pos > temp_songdata.macro_table[idx].arpeggio.length) then arpeggio_table_pos := min(1,temp_songdata.macro_table[idx].arpeggio.length) else arpeggio_table_pos := 1; kCtHOME: If (vibrato_table_pos > temp_songdata.macro_table[idx].vibrato.length) then vibrato_table_pos := min(1,temp_songdata.macro_table[idx].vibrato.length) else vibrato_table_pos := 1; kEND: If shift_pressed then If (arpeggio_table_pos < temp_songdata.macro_table[idx].arpeggio.length) then arpeggio_table_pos := temp_songdata.macro_table[idx].arpeggio.length else arpeggio_table_pos := 255; kCtEND: If (vibrato_table_pos < temp_songdata.macro_table[idx].vibrato.length) then vibrato_table_pos := temp_songdata.macro_table[idx].vibrato.length else vibrato_table_pos := 255; kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If update_current_inst and (current_inst > 1) then begin Dec(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; STATUS_LINE_refresh; keyboard_reset_buffer; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If update_current_inst and (current_inst < 255) then begin Inc(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; STATUS_LINE_refresh; keyboard_reset_buffer; end; end; If arp_tab_selected then begin attr := macro_hi_text SHL 4+macro_background SHR 4; attr2 := macro_background+macro_hi_text; attr3 := macro_hi_text SHL 4+macro_background SHR 4; temp := arpeggio_table_idx; end else begin attr := macro_background+macro_hi_text; If (temp_songdata.instr_macros[current_inst].arpeggio_table <> 0) then attr2 := macro_background+macro_hi_text else attr2 := macro_background+macro_text_dis; attr3 := macro_background+macro_text; temp := temp_songdata.instr_macros[current_inst].arpeggio_table; end; ShowC3Str(centered_frame_vdest,xstart_arp-1,ystart_arp+8, '`[`'+_check_chr[NOT arp_tab_selected and (temp_songdata.instr_macros[current_inst].arpeggio_table = 0)]+ '`]`~ '+byte2hex(temp)+'~', attr,attr2,attr3); If vib_tab_selected then begin attr := macro_hi_text SHL 4+macro_background SHR 4; attr2 := macro_background+macro_hi_text; attr3 := macro_hi_text SHL 4+macro_background SHR 4; temp := vibrato_table_idx; end else begin attr := macro_background+macro_hi_text; If (temp_songdata.instr_macros[current_inst].vibrato_table <> 0) then attr2 := macro_background+macro_hi_text else attr2 := macro_background+macro_text_dis; attr3 := macro_background+macro_text; temp := temp_songdata.instr_macros[current_inst].vibrato_table; end; ShowC3Str(centered_frame_vdest,xstart_vib-1,ystart_vib+8, '`[`'+_check_chr[NOT vib_tab_selected and (temp_songdata.instr_macros[current_inst].vibrato_table = 0)]+ '`]`~ '+byte2hex(temp)+'~', attr,attr2,attr3); If (arpeggio_table_pos > 15) then ShowStr(centered_frame_vdest,xstart_arp+6,ystart_arp+8,#17, macro_background+macro_text) else ShowStr(centered_frame_vdest,xstart_arp+6,ystart_arp+8,#17, macro_background+macro_text_dis); If (arpeggio_table_pos < temp_songdata.macro_table[idx].arpeggio.length-15+1) then ShowStr(centered_frame_vdest,xstart_arp+25,ystart_arp+8,#16, macro_background+macro_text) else ShowStr(centered_frame_vdest,xstart_arp+25,ystart_arp+8,#16, macro_background+macro_text_dis); If (vibrato_table_pos > 15) then ShowStr(centered_frame_vdest,xstart_vib+6,ystart_vib+8,#17, macro_background+macro_text) else ShowStr(centered_frame_vdest,xstart_vib+6,ystart_vib+8,#17, macro_background+macro_text_dis); If (vibrato_table_pos < temp_songdata.macro_table[idx].vibrato.length-15+1) then ShowStr(centered_frame_vdest,xstart_vib+24,ystart_vib+8,#16, macro_background+macro_text) else ShowStr(centered_frame_vdest,xstart_vib+24,ystart_vib+8,#16, macro_background+macro_text_dis); ShowCStr(centered_frame_vdest,xstart_arp+10,ystart_vib+8, 'ARPEGGiO (~'+byte2hex(arpeggio_table_pos)+'~)', macro_background+macro_text, macro_background+macro_hi_text); ShowCStr(centered_frame_vdest,xstart_vib+10,ystart_vib+8, 'ViBRATO (~'+byte2hex(vibrato_table_pos)+'~)', macro_background+macro_text, macro_background+macro_hi_text); context_str3 := ''; If update_current_inst and (get_4op_to_test <> 0) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then If (LO(get_4op_to_test) = HI(get_4op_to_test)) then context_str3 := ' ~[~'#244+byte2hex(HI(get_4op_to_test))+'~,~'#245+byte2hex(HI(get_4op_to_test))+'~]~' else If (current_inst = HI(get_4op_to_test)) then context_str3 := ' ~[~'#244+byte2hex(HI(get_4op_to_test))+'~,'#245+byte2hex(LO(get_4op_to_test))+']~' else context_str3 := ' ~['#244+byte2hex(HI(get_4op_to_test))+',~'#245+byte2hex(LO(get_4op_to_test))+'~]~'; temps := '`'+ExpStrL('`'+context_str3+context_str2+context_str+' `[`SPEED:'+Num2str(tempo*songdata.macro_speedup,10)+#174+'`]` ',52,#205); ShowC3Str(centered_frame_vdest,xstart+window_xsize-C3StrLen(temps),ystart+window_ysize, temps, macro_background+macro_context, macro_background+macro_context_dis, macro_background+macro_border); If (a2w_institle_pos <> 0) then ShowStr(centered_frame_vdest,mn_environment.xpos+a2w_institle_pos,mn_environment.ypos, byte2hex(current_inst), macro_background+macro_title); arpvib_arpeggio_table := arpeggio_table_idx; arpvib_vibrato_table := vibrato_table_idx; _macro_preview_refresh; mn_environment.curr_pos := current_inst; a2w_macro_lister_external_proc_callback; end; const _panning: array[0..2] of Char = #241'<>'; _hex: array[0..15] of Char = '0123456789ABCDEF'; _fmreg_add_prev_size: Byte = 0; var fmreg_cursor_pos: Byte; fmreg_left_margin: Byte; fmreg_hpos: Byte; fmreg_vpos: Byte; fmreg_instr: Byte; fmreg_page: Byte; fmreg_str: String; fmreg_scrlbar_size: Byte; fmreg_scrlbar_items: Byte; function min0(number: Integer; flag: Integer): Integer; begin If (number > 0) then min0 := number else min0 := flag; end; function fmreg_def_attr(page: Byte): Word; var attr, attr2: Byte; begin If (page <= temp_songdata.instr_macros[fmreg_instr].length) then If (page >= temp_songdata.instr_macros[fmreg_instr].loop_begin) and (page <= temp_songdata.instr_macros[fmreg_instr].loop_begin+ PRED(temp_songdata.instr_macros[fmreg_instr].loop_length)) and (temp_songdata.instr_macros[fmreg_instr].loop_begin > 0) and (temp_songdata.instr_macros[fmreg_instr].loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= temp_songdata.instr_macros[fmreg_instr].keyoff_pos) and (temp_songdata.instr_macros[fmreg_instr].keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; fmreg_def_attr := attr+attr2 SHL 8; end; function _fmreg_str(page: Byte): String; var fmreg_str: String; begin With temp_songdata.instr_macros[fmreg_instr].data[page].fm_data do begin fmreg_str := _hex[ATTCK_DEC_modulator SHR 4]+' '+ _hex[ATTCK_DEC_modulator AND $0f]+' '+ _hex[SUSTN_REL_modulator SHR 4]+' '+ _hex[SUSTN_REL_modulator AND $0f]+' '+ _hex[WAVEFORM_modulator AND 7]+' '+ byte2hex(KSL_VOLUM_modulator AND $3f)+' '+ _hex[KSL_VOLUM_modulator SHR 6]+' '+ _hex[AM_VIB_EG_modulator AND $0f]+' '; If (AM_VIB_EG_modulator SHR 7 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'T'; If (AM_VIB_EG_modulator SHR 6 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'V'; If (AM_VIB_EG_modulator SHR 4 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'K'; If (AM_VIB_EG_modulator SHR 5 AND 1 = 0) then fmreg_str := fmreg_str+#250' ' else fmreg_str := fmreg_str+'S '; fmreg_str := fmreg_str+ _hex[ATTCK_DEC_carrier SHR 4]+' '+ _hex[ATTCK_DEC_carrier AND $0f]+' '+ _hex[SUSTN_REL_carrier SHR 4]+' '+ _hex[SUSTN_REL_carrier AND $0f]+' '+ _hex[WAVEFORM_carrier AND 7]+' '+ byte2hex(KSL_VOLUM_carrier AND $3f)+' '+ _hex[KSL_VOLUM_carrier SHR 6]+' '+ _hex[AM_VIB_EG_carrier AND $0f]+' '; If (AM_VIB_EG_carrier SHR 7 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'T'; If (AM_VIB_EG_carrier SHR 6 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'V'; If (AM_VIB_EG_carrier SHR 4 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'K'; If (AM_VIB_EG_carrier SHR 5 AND 1 = 0) then fmreg_str := fmreg_str+#250' ' else fmreg_str := fmreg_str+'S '; fmreg_str := fmreg_str+_hex[FEEDBACK_FM AND 1]+' '; fmreg_str := fmreg_str+_hex[FEEDBACK_FM SHR 1 AND 7]+' '; end; With temp_songdata.instr_macros[fmreg_instr].data[page] do begin If (freq_slide < 0) then fmreg_str := fmreg_str+'-'+ExpStrL(Num2str(Abs(freq_slide),16),3,'0')+' ' else fmreg_str := fmreg_str+'+'+ExpStrL(Num2str(Abs(freq_slide),16),3,'0')+' '; fmreg_str := fmreg_str+ _panning[panning]+' '+ byte2hex(duration); end; _fmreg_str := fmreg_str; end; function _dis_fmreg_col(fmreg_col: Byte): Boolean; var result: Boolean; begin result := FALSE; Case fmreg_col of 1,2,3,4, 5: If temp_songdata.dis_fmreg_col[fmreg_instr][fmreg_col-1] then result := TRUE; 6, 7: If temp_songdata.dis_fmreg_col[fmreg_instr][5] then result := TRUE; 8,9,10,11,12,13, 14,15,16,17, 18: If temp_songdata.dis_fmreg_col[fmreg_instr][fmreg_col-2] then result := TRUE; 19, 20: If temp_songdata.dis_fmreg_col[fmreg_instr][17] then result := TRUE; 21,22,23,24, 25,26,27, 28: If temp_songdata.dis_fmreg_col[fmreg_instr][fmreg_col-3] then result := TRUE; 29,30,31, 32: If temp_songdata.dis_fmreg_col[fmreg_instr][26] then result := TRUE; 33: If temp_songdata.dis_fmreg_col[fmreg_instr][27] then result := TRUE; end; If (fmreg_col in [14..28]) and (temp_songdata.instr_data[current_inst].perc_voice in [2..5]) then result := TRUE; _dis_fmreg_col := result; end; function _str1(def_chr: Char): String; const _on_off: array[BOOLEAN] of Char = (#205,#254); var temp: Byte; temp_str: String; begin temp_str := ''; _on_off[FALSE] := def_chr; For temp := 0 to 4 do temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][temp]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][5]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][5]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][6]]+ def_chr+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][7]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][8]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][9]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][10]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][11]]+def_chr; For temp := 12 to 16 do temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][temp]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][17]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][17]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][18]]+def_chr+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][19]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][20]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][21]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][22]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][23]]+def_chr; For temp := 24 to 25 do temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][temp]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][26]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][26]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][26]]+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][26]]+def_chr; temp_str := temp_str+ _on_off[temp_songdata.dis_fmreg_col[fmreg_instr][27]]; _str1 := temp_str; end; {$IFNDEF CPU64} function _str2(str: String; len: Byte): String; begin asm lea esi,[str] mov edi,@RESULT movzx ebx,len xor edx,edx push edi lodsb inc edi xor ecx,ecx mov ecx,ebx jecxz @@3 movzx ecx,al jecxz @@3 @@1: cmp edx,ebx jae @@3 lodsb stosb cmp al,'`' jz @@2 inc edx @@2: loop @@1 @@3: pop edi mov eax,esi lea esi,[str] sub eax,esi dec eax stosb end; end; {$ELSE} function _str2(str: String; len: Byte): String; var idx,len2: Byte; result: String; begin result := ''; len2 := 0; idx := 0; While (idx < Length(str)) and (len > len2) do begin Inc(idx); If (str[idx] <> '`') then Inc(len2); result := result+str[idx]; end; _str2 := result; end; {$ENDIF} procedure fmreg_page_refresh(xpos,ypos: Byte; page: Word); var attr: Byte; temps,fmreg_str2: String; fmreg_col,index, index2: Byte; dummy_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fmreg_page_refresh'; {$ENDIF} attr := LO(fmreg_def_attr(page AND $0fff)); fmreg_str := _fmreg_str(page AND $0fff); fmreg_str2 := fmreg_str; index := 0; index2 := 0; For fmreg_col := 1 to 35-1 do If _dis_fmreg_col(fmreg_col) then begin Insert('`',fmreg_str2,pos5[fmreg_col]+index); Insert('`',fmreg_str2,pos5[fmreg_col]+index+2); If (pos5[fmreg_col] < fmreg_left_margin) then Inc(index2,2); Inc(index,2); end; temps := Copy(fmreg_str2,fmreg_left_margin+index2, Length(fmreg_str2)-fmreg_left_margin-index2+1); dummy_str := macro_retrig_str[temp_songdata.instr_macros[fmreg_instr].data[page AND $0ff].fm_data. FEEDBACK_FM SHR 5]; ShowC3Str(centered_frame_vdest,xpos+3,ypos, #179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_xsize-82-_fmreg_add_prev_size)+'~', macro_background+macro_text, attr, macro_background+macro_text_dis) end; procedure _scroll_cur_left; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_scroll_cur_left'; {$ENDIF} Repeat If (fmreg_cursor_pos > 1) then Dec(fmreg_cursor_pos) else Dec(fmreg_left_margin); until (fmreg_str[PRED(fmreg_left_margin+fmreg_cursor_pos-1)] = ' ') or (fmreg_left_margin+fmreg_cursor_pos-1 = 1); fmreg_cursor_pos := pos5[fmreg_hpos]-fmreg_left_margin+1; end; procedure _scroll_cur_right; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_scroll_cur_right'; {$ENDIF} Repeat If (fmreg_cursor_pos < 31+window_xsize-82-_fmreg_add_prev_size) then Inc(fmreg_cursor_pos) else Inc(fmreg_left_margin); until (fmreg_str[SUCC(fmreg_left_margin+fmreg_cursor_pos-1)] = ' ') or (fmreg_left_margin+fmreg_cursor_pos-1 = 57); fmreg_cursor_pos := pos5[fmreg_hpos]-fmreg_left_margin+1; end; procedure _dec_fmreg_hpos; var old_hpos_idx: Byte; new_hpos_idx: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_dec_fmreg_hpos'; {$ENDIF} old_hpos_idx := pos5vw[fmreg_hpos]; Repeat Dec(fmreg_hpos); new_hpos_idx := pos5vw[fmreg_hpos]; _scroll_cur_left; until (fmreg_hpos = 1) or (old_hpos_idx <> new_hpos_idx); If (fmreg_hpos > 1) then While (pos5vw[PRED(fmreg_hpos)] = pos5vw[fmreg_hpos]) do begin Dec(fmreg_hpos); _scroll_cur_left; end; end; procedure _inc_fmreg_hpos; var old_hpos_idx: Byte; new_hpos_idx: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_inc_fmreg_hpos'; {$ENDIF} old_hpos_idx := pos5vw[fmreg_hpos]; Repeat Inc(fmreg_hpos); new_hpos_idx := pos5vw[fmreg_hpos]; _scroll_cur_right; until (fmreg_hpos = 35-1) or (old_hpos_idx <> new_hpos_idx); end; function _fmreg_param(page,fmreg_hpos: Byte): Integer; var result: Integer; fmreg_str: String; begin fmreg_str := _fmreg_str(page); Case fmreg_hpos of {%n} 1,2,3,4,5,8,9,14,15,16,17, 18,21,22,27,28: result := Str2num(fmreg_str[pos5[fmreg_hpos]],16); {%nn} 6,7: result := Str2num(Copy(fmreg_str,pos5[6],2),16); 19,20: result := Str2num(Copy(fmreg_str,pos5[19],2),16); 34,35: result := Str2num(Copy(fmreg_str,pos5[34],2),16); {sw} 10,11,12,13,23,24, 25,26: If (fmreg_str[pos5[fmreg_hpos]] = #251) then result := 1 else result := 0; {fsl} 29,30,31,32: begin result := Str2num(Copy(fmreg_str,pos5[30],3),16); If (fmreg_str[pos5[29]] = '-') then result := -result; end; {pan} 33: Case SYSTEM.Pos(fmreg_str[pos5[33]],_panning) of 1: result := 0; 2: result := -1; 3: result := 1; end; end; _fmreg_param := result; end; procedure _fmreg_macro_preview_refresh(xstart,ystart: Byte; page: Byte); var temp,max_value: Integer; d_factor: Real; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:_fmreg_macro_preview_refresh'; {$ENDIF} ShowStr(centered_frame_vdest,xstart+10+(_fmreg_add_prev_size DIV 2),ystart, #253, macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart+10+(_fmreg_add_prev_size DIV 2),ystart+7, #252, macro_background+macro_topic2); If NOT (fmreg_hpos in [29..33]) then begin ShowVStr(centered_frame_vdest,xstart,ystart+1, #179#179#179#179#179#158, macro_background+macro_text); ShowVStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size,ystart+1, #179#179#179#179#179#158, macro_background+macro_text); end else begin ShowVStr(centered_frame_vdest,xstart,ystart+1, #179#179#158#179#179#179, macro_background+macro_text); ShowVStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size,ystart+1, #179#179#158#179#179#179, macro_background+macro_text); end; max_value := 0; For temp := 1 to 255 do If (Abs(_fmreg_param(temp,fmreg_hpos)) > max_value) then max_value := Abs(_fmreg_param(temp,fmreg_hpos)); If NOT (fmreg_hpos in [29..33]) then begin ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+1, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+2, '+', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+5, ' ', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+6, ExpStrR('',3,' '), macro_background+macro_topic); end else begin ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+1, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+2, '+', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+5, '-', macro_background+macro_topic); ShowStr(centered_frame_vdest,xstart+20+_fmreg_add_prev_size+1,ystart+6, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); end; If NOT (fmreg_hpos in [29..33]) then d_factor := 90/min(max_value,1) else d_factor := 45/min(max_value,1); If NOT (fmreg_hpos in [29..33]) then For temp := -9-(_fmreg_add_prev_size DIV 2) to 9+(_fmreg_add_prev_size DIV 2) do If (page+temp >= 1) and (page+temp <= 255) then If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL(_gfx_bar_str(Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor),FALSE),6,' '), LO(fmreg_def_attr(page+temp))) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL(_gfx_bar_str(Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor),FALSE),6,' '), macro_background+macro_text_dis) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL('',6,' '), macro_background+macro_text) else For temp := -9-(_fmreg_add_prev_size DIV 2) to 9+(_fmreg_add_prev_size DIV 2) do If (page+temp >= 1) and (page+temp <= 255) then If (Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor) >= 0) then If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrR(ExpStrL(_gfx_bar_str(Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor),FALSE),3,' '),6,' '), LO(fmreg_def_attr(page+temp))) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrR(ExpStrL(_gfx_bar_str(Round(_fmreg_param(page+temp,fmreg_hpos)*d_factor),FALSE),3,' '),6,' '), macro_background+macro_text_dis) else If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(_fmreg_param(page+temp,fmreg_hpos))*d_factor),TRUE),3,' '),6,' '), LO(fmreg_def_attr(page+temp))) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(_fmreg_param(page+temp,fmreg_hpos))*d_factor),TRUE),3,' '),6,' '), macro_background+macro_text_dis) else ShowVStr(centered_frame_vdest,xstart+10+temp+(_fmreg_add_prev_size DIV 2),ystart+1, ExpStrL('',6,' '), macro_background+macro_text); end; procedure a2w_lister_external_proc; var idx,temp: Byte; temps: String; songdata_ptr: Pointer; attr: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_lister_external_proc'; {$ENDIF} Case mn_environment.keystroke of kUP: If shift_pressed then If (fmreg_vpos > 1) then Dec(fmreg_vpos) else If (fmreg_page > 1) then Dec(fmreg_page); kDOWN: If shift_pressed then If (fmreg_vpos < 6) then Inc(fmreg_vpos) else If (fmreg_page < 255-6+1) then Inc(fmreg_page); kPgUP: If shift_pressed then If (fmreg_page > 6) then Dec(fmreg_page,6) else If (fmreg_page > 1) then fmreg_page := 1 else fmreg_vpos := 1; kPgDOWN: If shift_pressed then If (fmreg_page+6 < 255-6+1) then Inc(fmreg_page,6) else If (fmreg_page < 255-6+1) then fmreg_page := 255-6+1 else fmreg_vpos := 6; kHOME: If shift_pressed then begin fmreg_page := 1; fmreg_vpos := 1; end; kEND: If shift_pressed then begin fmreg_page := 255-6+1; fmreg_vpos := 6; end; kCtHOME: begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kCtEND: begin fmreg_hpos := 35-1; fmreg_cursor_pos := max(pos5[fmreg_hpos],31+window_xsize-82-_fmreg_add_prev_size); fmreg_left_margin := min(pos5[35]-(31+window_xsize-82-_fmreg_add_prev_size),1); _dec_fmreg_hpos; _inc_fmreg_hpos; end; kLEFT: If shift_pressed then If (fmreg_hpos > 1) then _dec_fmreg_hpos else If cycle_pattern then begin fmreg_hpos := 35-1; fmreg_cursor_pos := max(pos5[fmreg_hpos],31+window_xsize-82-_fmreg_add_prev_size); fmreg_left_margin := min(pos5[35]-(31+window_xsize-82-_fmreg_add_prev_size),1); _dec_fmreg_hpos; _inc_fmreg_hpos; end; kRIGHT: If shift_pressed then If (fmreg_hpos < 35-1) then _inc_fmreg_hpos else If cycle_pattern then begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end; end; For temp := 1 to _a2w_lister_count do begin If (mn_environment.curr_pos = mn_environment.curr_page+temp-1) then attr := mn_setting.text2_attr else attr := mn_setting.text_attr; ShowStr(mn_environment.v_dest,mn_environment.xpos+1,mn_environment.ypos+3+temp, _4op_flag_column[mn_environment.curr_page+temp-1], attr); end; fmreg_instr := Str2num(Copy(mn_environment.curr_item,7,2),16); songdata_ptr := Addr(temp_songdata); If update_current_inst then begin current_inst := fmreg_instr; instrum_page := fmreg_instr; STATUS_LINE_refresh; songdata_ptr := Addr(songdata); end; If (a2w_institle_pos <> 0) then ShowStr(centered_frame_vdest,mn_environment.xpos+a2w_institle_pos,mn_environment.ypos, byte2hex(current_inst), macro_background+macro_title); context_str3 := ''; If update_current_inst and (get_4op_to_test <> 0) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then If (LO(get_4op_to_test) = HI(get_4op_to_test)) then context_str3 := ' ~[~'#244+byte2hex(HI(get_4op_to_test))+'~,~'#245+byte2hex(HI(get_4op_to_test))+'~]~' else If (current_inst = HI(get_4op_to_test)) then context_str3 := ' ~[~'#244+byte2hex(HI(get_4op_to_test))+'~,'#245+byte2hex(LO(get_4op_to_test))+']~' else context_str3 := ' ~['#244+byte2hex(HI(get_4op_to_test))+',~'#245+byte2hex(LO(get_4op_to_test))+'~]~'; temps := '`'+ExpStrL('`'+context_str3+context_str2+context_str+' `[`SPEED:'+Num2str(tempo*songdata.macro_speedup,10)+#174+'`]` ',52,#205); ShowC3Str(centered_frame_vdest,xstart+window_xsize-C3StrLen(temps),ystart+window_ysize, temps, macro_background+macro_context, macro_background+macro_context_dis, macro_background+macro_border); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+2, 'LENGTH: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].length)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+3, 'LOOP BEG.: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].loop_begin)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+4, 'LOOP LEN.: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].loop_length)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+5, 'KEY-OFF: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].keyoff_pos)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+6, 'ARP.TABLE: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].arpeggio_table)+' ~', macro_background+macro_topic, macro_background+macro_text); ShowCStr(centered_frame_vdest,xstart+2,ystart+window_ysize-10+7, 'ViB.TABLE: ~'+ byte2hex(tFIXED_SONGDATA(songdata_ptr^).instr_macros[fmreg_instr].vibrato_table)+' ~', macro_background+macro_topic, macro_background+macro_text); VScrollBar(centered_frame_vdest,xstart+window_xsize,ystart+3, fmreg_scrlbar_size,fmreg_scrlbar_items,mn_environment.curr_pos,WORD_NULL, macro_background+macro_border, macro_background+macro_border); VScrollBar(centered_frame_vdest,xstart+window_xsize,ystart+window_ysize-10+1, 8,255-6,fmreg_page,WORD_NULL, macro_background+macro_border, macro_background+macro_border); _fmreg_macro_preview_refresh(xstart+17,ystart+window_ysize-10+1,fmreg_page+fmreg_vpos-1); ShowCStr(centered_frame_vdest,xstart+49+_fmreg_add_prev_size,ystart+window_ysize-10+1, ExpStrL('',fmreg_cursor_pos,#205)+'~'+#31+'~'+ ExpStrL('',window_xsize-49-_fmreg_add_prev_size-fmreg_cursor_pos-1,#205), macro_background+macro_topic2, macro_background+macro_hi_text); ShowCStr(centered_frame_vdest,xstart+49+_fmreg_add_prev_size,ystart+window_ysize-2, ExpStrL('',fmreg_cursor_pos,#205)+'~'+#30+'~'+ ExpStrL('',window_xsize-49-_fmreg_add_prev_size-fmreg_cursor_pos-1,#205), macro_background+macro_topic2, macro_background+macro_hi_text); ShowStr(centered_frame_vdest,xstart+2,ystart+window_ysize-1, ExpStrR(macro_table_hint_str[20+fmreg_hpos],window_xsize-2,' '), macro_background+macro_hint); For idx := 1 to 6 do begin If (idx = fmreg_vpos) then ShowStr(centered_frame_vdest,xstart+43+_fmreg_add_prev_size,ystart+window_ysize-10+1+idx, #16+byte2hex(fmreg_page+idx-1)+#17, macro_background+macro_hi_text) else ShowStr(centered_frame_vdest,xstart+43+_fmreg_add_prev_size,ystart+window_ysize-10+1+idx, ' '+byte2hex(fmreg_page+idx-1)+' ', macro_background+macro_topic); fmreg_page_refresh(xstart+44+_fmreg_add_prev_size,ystart+window_ysize-10+1+idx,fmreg_page+idx-1); end; a2w_lister_external_proc_callback; end; procedure a2w_file_loader(loadFromFile: Boolean; loadMacros: Boolean; bankSelector: Boolean; loadBankPossible: Boolean; updateCurInstr: Boolean); type tOLD_HEADER = Record ident: array[1..20] of Char; crc32: Longint; ffver: Byte; b0len: Longint; b1len: Longint; end; type tHEADER = Record ident: array[1..20] of Char; crc32: Longint; ffver: Byte; b0len: Longint; b1len: Longint; b2len: Longint; end; const id = '_A2insbank_w/macros_'; var f: File; a2w_instdata_source: String; header: tHEADER; header2: tOLD_HEADER; crc,temp: Longint; idx,index,nm_valid: Byte; idx1,idx2: Integer; temp_str: String; arpvib_arpeggio_table_bak: Byte; arpvib_vibrato_table_bak: Byte; browser_flag: Boolean; ysize: Byte; // backup of Menu settings / variables old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; old_topic_mask_chr: Set of Char; old_frame_enabled: Boolean; old_shadow_enabled: Boolean; old_winshade: Boolean; old_center_box: Boolean; old_show_scrollbar: Boolean; old_text_attr, old_text2_attr, old_short_attr, old_short2_attr, old_disbld_attr, old_contxt_attr, old_contxt2_attr, old_topic_attr, old_hi_topic_attr: Byte; const new_keys: array[1..5] of Word = (kESC,kENTER,kF1,kTAB,kCtENTR); var old_keys: array[1..50] of Word; procedure _put_2op_instrument; begin songdata.instr_data[current_inst] := temp_songdata.instr_data[index]; songdata.instr_macros[current_inst] := temp_songdata.instr_macros[index]; songdata.dis_fmreg_col[current_inst] := temp_songdata.dis_fmreg_col[index]; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(temp_songdata.instr_names[index],10,32); idx1 := -1; idx2 := -1; If (songdata.instr_macros[current_inst].arpeggio_table <> 0) then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[ songdata.instr_macros[current_inst].arpeggio_table].arpeggio); If (songdata.instr_macros[current_inst].vibrato_table <> 0) then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[ songdata.instr_macros[current_inst].vibrato_table].vibrato); temp_str := ''; If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If NOT (temp_str <> '') then begin If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[songdata.instr_macros[current_inst].arpeggio_table].arpeggio; songdata.instr_macros[current_inst].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[songdata.instr_macros[current_inst].vibrato_table].vibrato; songdata.instr_macros[current_inst].vibrato_table := idx2; end end else Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); end; procedure _put_4op_instrument; begin songdata.instr_data[_4op_idx11] := temp_songdata.instr_data[_4op_idx21]; songdata.instr_macros[_4op_idx11] := temp_songdata.instr_macros[_4op_idx21]; songdata.dis_fmreg_col[_4op_idx11] := temp_songdata.dis_fmreg_col[_4op_idx21]; songdata.instr_names[_4op_idx11] := Copy(songdata.instr_names[_4op_idx11],1,9)+ Copy(temp_songdata.instr_names[_4op_idx21],10,32); idx1 := -1; idx2 := -1; If (songdata.instr_macros[_4op_idx11].arpeggio_table <> 0) then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[ songdata.instr_macros[_4op_idx11].arpeggio_table].arpeggio); If (songdata.instr_macros[_4op_idx11].vibrato_table <> 0) then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[ songdata.instr_macros[_4op_idx11].vibrato_table].vibrato); temp_str := ''; If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If NOT (temp_str <> '') then begin If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[songdata.instr_macros[_4op_idx11].arpeggio_table].arpeggio; songdata.instr_macros[_4op_idx11].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[songdata.instr_macros[_4op_idx11].vibrato_table].vibrato; songdata.instr_macros[_4op_idx11].vibrato_table := idx2; end end else Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); songdata.instr_data[_4op_idx12] := temp_songdata.instr_data[_4op_idx22]; songdata.instr_macros[_4op_idx12] := temp_songdata.instr_macros[_4op_idx22]; songdata.dis_fmreg_col[_4op_idx12] := temp_songdata.dis_fmreg_col[_4op_idx22]; songdata.instr_names[_4op_idx12] := Copy(songdata.instr_names[_4op_idx12],1,9)+ Copy(temp_songdata.instr_names[_4op_idx22],10,32); idx1 := -1; idx2 := -1; If (songdata.instr_macros[_4op_idx12].arpeggio_table <> 0) then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[ songdata.instr_macros[_4op_idx12].arpeggio_table].arpeggio); If (songdata.instr_macros[_4op_idx12].vibrato_table <> 0) then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[ songdata.instr_macros[_4op_idx12].vibrato_table].vibrato); temp_str := ''; If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If NOT (temp_str <> '') then begin If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[songdata.instr_macros[_4op_idx12].arpeggio_table].arpeggio; songdata.instr_macros[_4op_idx12].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[songdata.instr_macros[_4op_idx12].vibrato_table].vibrato; songdata.instr_macros[_4op_idx12].vibrato_table := idx2; end end else Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); end; label _jmp1,_jmp1e,_jmp2,_jmp2e,_end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_file_loader'; {$ENDIF} arpvib_arpeggio_table_bak := arpvib_arpeggio_table; arpvib_vibrato_table_bak := arpvib_vibrato_table; songdata_bak := songdata; temp_songdata := songdata_bak; update_current_inst := updateCurInstr; browser_flag := FALSE; progress_num_steps := 0; progress_step := 0; If NOT loadFromFile and bankSelector and NOT loadBankPossible then begin a2w_instdata_source := ''; If loadMacros then begin arp_tab_selected := _macro_editor__pos[_arp_vib_mode] in [8..13]; vib_tab_selected := _macro_editor__pos[_arp_vib_mode] in [14..20]; end else begin arp_tab_selected := songdata.instr_macros[current_inst].arpeggio_table <> 0; vib_tab_selected := songdata.instr_macros[current_inst].vibrato_table <> 0; end; // init 4OP flags (no file bank) temp_songdata.ins_4op_flags := songdata.ins_4op_flags; FillChar(_4op_flag_column,SizeOf(_4op_flag_column),0); For temp := 1 to PRED(255) do If check_4op_flag_temp(temp) then begin If NOT (_4op_flag_column[temp] in _4op_flag_chars) then _4op_flag_column[temp] := _4op_flag_chr_beg; If NOT (_4op_flag_column[SUCC(temp)] in _4op_flag_chars) then _4op_flag_column[SUCC(temp)] := _4op_flag_chr_end; end; If loadMacros then GOTO _jmp1 // Arpeggio/Vibrato Macro Browser else GOTO _jmp2; // Instrument Macro Browser end else a2w_instdata_source := instdata_source; {$i-} Assign(f,a2w_instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); 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); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2W]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; If (header.ffver = 1) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header2.b0len,2,crc); crc := Update32(header2.b1len,2,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; SeekF(f,SizeOf(header2)); If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; APACK_decompress(buf1,temp_songdata.instr_names); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; APACK_decompress(buf1,temp_songdata.macro_table); FillChar(temp_songdata.dis_fmreg_col,SizeOf(temp_songdata.dis_fmreg_col),FALSE); end; If (header.ffver = 2) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header.b0len,2,crc); crc := Update32(header.b1len,2,crc); crc := Update32(header.b2len,2,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; APACK_decompress(buf1,temp_songdata.instr_names); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; APACK_decompress(buf1,temp_songdata.macro_table); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; APACK_decompress(buf1,temp_songdata.dis_fmreg_col); end; If (header.ffver = FFVER_A2W) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header.b0len,2,crc); crc := Update32(header.b1len,2,crc); crc := Update32(header.b2len,2,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; For temp := 1 to 255 do temp_marks[temp] := temp_songdata.instr_names[temp][1]; progress_num_steps := 0; LZH_decompress(buf1,buf2,header.b0len); Move(buf2,temp_songdata.instr_names,SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)+ SizeOf(songdata.instr_macros)); Move(buf2[SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)+ SizeOf(songdata.instr_macros)],temp_songdata.ins_4op_flags, SizeOf(songdata.ins_4op_flags)); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', temp_songdata.instr_names[temp],1); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; LZH_decompress(buf1,temp_songdata.macro_table,header.b1len); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2W LOADER ',1); EXIT; end; LZH_decompress(buf1,temp_songdata.dis_fmreg_col,header.b2len); end; CloseF(f); // init 4OP flags (file bank) FillChar(_4op_flag_column,SizeOf(_4op_flag_column),0); For temp := 1 to PRED(255) do If check_4op_flag_temp(temp) then begin If NOT (_4op_flag_column[temp] in _4op_flag_chars) then _4op_flag_column[temp] := _4op_flag_chr_beg; If NOT (_4op_flag_column[SUCC(temp)] in _4op_flag_chars) then _4op_flag_column[SUCC(temp)] := _4op_flag_chr_end; end; If loadMacros then begin _jmp1: ScreenMemCopy(screen_ptr,ptr_screen_backup); nm_valid := count_macros; If (nm_valid = 0) then nm_valid := 1; If NOT bankSelector then begin mn_environment.keystroke := kCtENTR; arp_tab_selected := TRUE; vib_tab_selected := TRUE; GOTO _jmp1e; end; window_xsize := 73; If is_default_screen_mode then window_ysize := max(nm_valid+5,15)+10 else window_ysize := max(nm_valid+5,20)+10; If (a2w_instdata_source <> '') theN temp_str := ' '+iCASE(NameOnly(a2w_instdata_source))+' '#16' A/V MACROS ' else temp_str := ' ARPEGGiO/ViBRATO MACRO BROWSER '; If update_current_inst then temp_str := temp_str + '(iNS_ ) ' else temp_str := temp_str + '[iNS_ ] '; a2w_institle_pos := (window_xsize DIV 2)+(Length(temp_str) DIV 2)-3; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,window_xsize,window_ysize, temp_str, macro_background+macro_border, macro_background+macro_title, frame_double); ShowStr(centered_frame_vdest,xstart+1,ystart+window_ysize-10+1, av_browser_str[6], macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart+1,ystart+window_ysize-2, ExpStrR('',72,#205), macro_background+macro_topic2); context_str := ' ~[~'+Num2str(nm_valid,10)+'~/255]~'; xstart_arp := xstart+3; ystart_arp := ystart+window_ysize-10+1; xstart_vib := xstart+38; ystart_vib := ystart+window_ysize-10+1; scrollbar_xstart := xstart+window_xsize; scrollbar_ystart := ystart+1; scrollbar_size := window_ysize-10+1; macro_table_size := nm_valid; If (a2w_instdata_source <> '') then temp_str := a2w_instdata_source else temp_str := '?internal_instrument_data'; arpeggio_table_pos := min(1,get_bank_position(temp_str+'?macro_av?arp_pos',nm_valid)); vibrato_table_pos := min(1,get_bank_position(temp_str+'?macro_av?vib_pos',nm_valid)); a2w_queue_m[1] := av_browser_str[1]; a2w_queue_m[2] := av_browser_str[2]; a2w_queue_m[3] := av_browser_str[3]; a2w_queue_m[4] := av_browser_str[4]; a2w_queue_m[5] := av_browser_str[5]; For idx := 1 to nm_valid do begin a2w_queue_m[5+idx] := ' ~'+byte2hex(idx)+'~ '#186; If Empty(temp_songdata.macro_table[idx].arpeggio,SizeOf(tARPEGGIO_TABLE)) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#186 else With temp_songdata.macro_table[idx].arpeggio do begin If (length > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(length)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (speed > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(speed)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (loop_begin > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(loop_begin)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (loop_length > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(loop_length)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (keyoff_pos > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(keyoff_pos)+' '#186 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#186; end; If Empty(temp_songdata.macro_table[idx].vibrato,SizeOf(tViBRATO_TABLE)) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250' '#179+ ' '#250#250 else With temp_songdata.macro_table[idx].vibrato do begin If (length > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(length)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (speed > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(speed)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (delay > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(delay)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (loop_begin > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(loop_begin)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (loop_length > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(loop_length)+' '#179 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249' '#179; If (keyoff_pos > 0) then a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '+byte2hex(keyoff_pos)+' '#186 else a2w_queue_m[5+idx] := a2w_queue_m[5+idx]+' '#249#249; end; end; Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; old_topic_mask_chr := mn_setting.topic_mask_chr; old_frame_enabled := mn_setting.frame_enabled; old_shadow_enabled := mn_setting.shadow_enabled; old_winshade := mn_environment.winshade; old_center_box := mn_setting.center_box; old_show_scrollbar := mn_setting.show_scrollbar; old_text_attr := mn_setting.text_attr; old_text2_attr := mn_setting.text2_attr; old_short_attr := mn_setting.short_attr; old_short2_attr := mn_setting.short2_attr; old_disbld_attr := mn_setting.disbld_attr; old_contxt_attr := mn_setting.contxt_attr; old_contxt2_attr := mn_setting.contxt2_attr; old_topic_attr := mn_setting.topic_attr; old_hi_topic_attr := mn_setting.hi_topic_attr; Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); mn_setting.terminate_keys[4] := 0; // TAB possible only in FM-Register bank browser If NOT loadBankPossible then mn_setting.terminate_keys[5] := 0; // ^ENTER possible only in Arpeggio/Vibrato Macro Editor mn_environment.ext_proc := a2w_macro_lister_external_proc; mn_setting.topic_len := 5; mn_setting.cycle_moves := FALSE; mn_setting.topic_mask_chr := [#179,#186]; mn_setting.frame_enabled := FALSE; mn_setting.shadow_enabled := FALSE; mn_environment.winshade := FALSE; mn_setting.center_box := FALSE; mn_setting.show_scrollbar := FALSE; mn_environment.unpolite := FALSE; mn_environment.preview := TRUE; mn_environment.v_dest := ptr_temp_screen; mn_setting.text_attr := macro_background+macro_item; mn_setting.text2_attr := macro_sel_itm_bck+macro_sel_itm; mn_setting.short_attr := macro_background+macro_short; mn_setting.short2_attr := macro_sel_itm_bck+macro_sel_short; mn_setting.disbld_attr := macro_background+macro_item_dis; mn_setting.contxt_attr := macro_background+macro_context; mn_setting.contxt2_attr := macro_background+macro_context_dis; mn_setting.topic_attr := macro_background+macro_topic2; mn_setting.hi_topic_attr := macro_background+macro_hi_topic; If (a2w_instdata_source <> '') then temp_str := a2w_instdata_source else temp_str := '?internal_instrument_data'; If is_default_screen_mode then ysize := 15 else ysize := 20; If (program_screen_mode in [0,3,4,5]) then Menu(a2w_queue_m,xstart,ystart, min(1,get_bank_position(temp_str+'?macro_av?pos',nm_valid)), 72,max(nm_valid+5,ysize),nm_valid+5,'') else Menu(a2w_queue_m,xstart,ystart, min(1,get_bank_position(temp_str+'?macro_av?pos',nm_valid)), 72,max(nm_valid+5,20),nm_valid+5,''); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+window_xsize+2+1; move_to_screen_area[4] := ystart+window_ysize+1; move2screen_alt; mn_environment.unpolite := FALSE; mn_environment.preview := FALSE; mn_environment.v_dest := screen_ptr; centered_frame_vdest := mn_environment.v_dest; If is_default_screen_mode then ysize := 15 else ysize := 20; keyboard_reset_buffer; If NOT _force_program_quit then If (program_screen_mode in [0,3,4,5]) then index := Menu(a2w_queue_m,xstart,ystart, min(1,get_bank_position(temp_str+'?macro_av?pos',nm_valid)), 72,max(nm_valid+5,ysize),nm_valid+5,'') else index := Menu(a2w_queue_m,xstart,ystart, min(1,get_bank_position(temp_str+'?macro_av?pos',nm_valid)), 72,max(nm_valid+5,20),nm_valid+5,''); add_bank_position(temp_str+'?macro_av?pos',nm_valid,index+5); add_bank_position(temp_str+'?macro_av?arp_pos',nm_valid,arpeggio_table_pos); add_bank_position(temp_str+'?macro_av?vib_pos',nm_valid,vibrato_table_pos); Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; mn_setting.topic_mask_chr := old_topic_mask_chr; mn_setting.frame_enabled := old_frame_enabled; mn_setting.shadow_enabled := old_shadow_enabled; mn_environment.winshade := old_winshade; mn_setting.center_box := old_center_box; mn_setting.show_scrollbar := old_show_scrollbar; mn_setting.text_attr := old_text_attr; mn_setting.text2_attr := old_text2_attr; mn_setting.short_attr := old_short_attr; mn_setting.short2_attr := old_short2_attr; mn_setting.disbld_attr := old_disbld_attr; mn_setting.contxt_attr := old_contxt_attr; mn_setting.contxt2_attr := old_contxt2_attr; mn_setting.topic_attr := old_topic_attr; mn_setting.hi_topic_attr := old_hi_topic_attr; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+window_xsize+2+1; move_to_screen_area[4] := ystart+window_ysize+1; move2screen; If (mn_environment.keystroke = kF1) then begin HELP('macro_browser_av'); If NOT _force_program_quit then GOTO _jmp1; end; If NOT update_current_inst and (mn_environment.keystroke = kENTER) then begin songdata := songdata_bak; temp_songdata := songdata_bak; mn_environment.keystroke := kESC; end; If NOT loadMacros and (mn_environment.keystroke = kESC) then begin load_flag := BYTE_NULL; load_flag_alt := BYTE_NULL; GOTO _jmp2; end; _jmp1e: If (mn_environment.keystroke = kENTER) or (loadBankPossible and (mn_environment.keystroke = kCtENTR)) then begin If (mn_environment.keystroke = kENTER) then begin If loadMacros or _arp_vib_loader then begin arpvib_arpeggio_table := arpvib_arpeggio_table_bak; arpvib_vibrato_table := arpvib_vibrato_table_bak; If arp_tab_selected then songdata.macro_table[arpvib_arpeggio_table].arpeggio := temp_songdata.macro_table[index].arpeggio; If vib_tab_selected then songdata.macro_table[arpvib_vibrato_table].vibrato := temp_songdata.macro_table[index].vibrato; end else begin idx1 := -1; idx2 := -1; If arp_tab_selected then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[index].arpeggio); If vib_tab_selected then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[index].vibrato); temp_str := ''; If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If NOT (temp_str <> '') then begin If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[index].arpeggio; songdata.instr_macros[current_inst].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[index].vibrato; songdata.instr_macros[current_inst].vibrato_table := idx2; end; end else begin Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); GOTO _end; end; end; load_flag := 1; load_flag_alt := BYTE_NULL; end else begin temp_str := ''; If arp_tab_selected then temp_str := 'ARPEGGiO'; If vib_tab_selected then If (temp_str <> '') then temp_str := temp_str+'/ViBRATO' else temp_str := 'ViBRATO'; If NOT (NOT arp_tab_selected and NOT vib_tab_selected) or (nm_valid < 2) then begin If bankSelector then index := Dialog('ALL UNSAVED '+temp_str+' MACRO DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2W LOADER ',1) else begin index := 1; dl_environment.keystroke := kENTER; end; If (dl_environment.keystroke <> kESC) and (index = 1) then begin For idx := 1 to 255 do If NOT (idx > nm_valid) then begin If arp_tab_selected then songdata.macro_table[idx].arpeggio := temp_songdata.macro_table[idx].arpeggio; If vib_tab_selected then songdata.macro_table[idx].vibrato := temp_songdata.macro_table[idx].vibrato; end else begin FillChar(songdata.macro_table[idx].arpeggio,SizeOf(songdata.macro_table[idx].arpeggio),0); FillChar(songdata.macro_table[idx].vibrato,SizeOf(songdata.macro_table[idx].vibrato),0); end; load_flag := 1; load_flag_alt := BYTE_NULL; end; end; end; end; end else begin _jmp2: browser_flag := FALSE; ScreenMemCopy(screen_ptr,ptr_screen_backup); a2w_queue[1] := a2w_header_str[1]; a2w_queue[2] := a2w_header_str[2]; a2w_queue[3] := a2w_header_str[3]; a2w_queue_more[1] := a2w_header_hires1_str[1]; a2w_queue_more[2] := a2w_header_hires1_str[2]; a2w_queue_more[3] := a2w_header_hires1_str[3]; a2w_queue_more2[1] := a2w_header_hires2_str[1]; a2w_queue_more2[2] := a2w_header_hires2_str[2]; a2w_queue_more2[3] := a2w_header_hires2_str[3]; nm_valid := count_instruments; If (nm_valid = 0) then nm_valid := 1; If NOT bankSelector then begin mn_environment.keystroke := kCtENTR; GOTO _jmp2e; end; context_str := ''; context_str2 := ''; If (a2w_instdata_source = '') then nm_valid := 255 else begin context_str := ' ~[~'+Num2str(nm_valid,10)+'~/255]~'; If NOT loadBankPossible then context_str2 := ' ~[BANK]~' else context_str2 := ' [BANK]'; end; For idx := 1 to nm_valid do begin a2w_queue[3+idx] := '~ '+ExpStrR(Copy(temp_songdata.instr_names[idx],2,8)+'~'+ Copy(temp_songdata.instr_names[idx],10,32),44,' '); a2w_queue_more[3+idx] := a2w_queue[3+idx]; With temp_songdata.instr_data[idx].fm_data do begin a2w_queue_more[3+idx] := a2w_queue_more[3+idx]+ byte2hex(AM_VIB_EG_carrier)+ byte2hex(AM_VIB_EG_modulator)+' '+ byte2hex(KSL_VOLUM_carrier)+ byte2hex(KSL_VOLUM_modulator)+' '+ byte2hex(ATTCK_DEC_carrier)+ byte2hex(ATTCK_DEC_modulator)+' '+ byte2hex(SUSTN_REL_carrier)+ byte2hex(SUSTN_REL_modulator)+' '+ byte2hex(WAVEFORM_carrier)+ byte2hex(WAVEFORM_modulator)+' '+ byte2hex(FEEDBACK_FM)+' '; end; Case temp_songdata.instr_data[idx].panning of 0..2: temp_str := ins_pan_str2[temp_songdata.instr_data[idx].panning]; else temp_str := ExpStrL('',7,#250); end; a2w_queue_more2[3+idx] := a2w_queue_more[3+idx]+temp_str+' '; If (temp_songdata.instr_data[idx].fine_tune > 0) then temp_str := '+'+ExpStrR(Num2str(temp_songdata.instr_data[idx].fine_tune,16),5,' ') else If (temp_songdata.instr_data[idx].fine_tune < 0) then temp_str := '-'+ExpStrR(Num2str(0-temp_songdata.instr_data[idx].fine_tune,16),5,' ') else temp_str := ExpStrR('',6,' '); a2w_queue_more2[3+idx] := a2w_queue_more2[3+idx]+temp_str+' '; Case temp_songdata.instr_data[idx].perc_voice of 0..5: temp_str := perc_voice_str[temp_songdata.instr_data[idx].perc_voice]; else temp_str := ExpStrL('',7,' '); end; a2w_queue[3+idx] := a2w_queue[3+idx]+temp_str; a2w_queue_more[3+idx] := a2w_queue_more[3+idx]+temp_str; a2w_queue_more2[3+idx] := a2w_queue_more2[3+idx]+temp_str; If (temp_songdata.instr_macros[idx].length <> 0) then temp_str := ' MACRO:FM' else temp_str := ' '; With temp_songdata.macro_table[ temp_songdata.instr_macros[idx].arpeggio_table].arpeggio do If (temp_songdata.instr_macros[idx].arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'MACRO:ARP'; With temp_songdata.macro_table[ temp_songdata.instr_macros[idx].vibrato_table].vibrato do If (temp_songdata.instr_macros[idx].vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'MACRO:ViB'; a2w_queue[3+idx] := a2w_queue[3+idx]+' '+ExpStrR(temp_str,18,' '); a2w_queue_more[3+idx] := a2w_queue_more[3+idx]+' '+ExpStrR(temp_str,18,' '); a2w_queue_more2[3+idx] := a2w_queue_more2[3+idx]+' '+ExpStrR(temp_str,18,' '); end; If (a2w_instdata_source <> '') then temp_str := a2w_instdata_source else temp_str := '?internal_instrument_data'; idx := min(1,get_bank_position(temp_str+'?macro?pos',nm_valid)); fmreg_page := min(1,get_bank_position(temp_str+'?macro?fmreg_page',nm_valid)); fmreg_hpos := min(1,get_bank_position(temp_str+'?macro?fmreg_hpos',nm_valid)); fmreg_vpos := min(1,get_bank_position(temp_str+'?macro?fmreg_vpos',nm_valid)); fmreg_left_margin := min(1,get_bank_position(temp_str+'?macro?fmreg_left_margin',nm_valid)); fmreg_cursor_pos := min(1,get_bank_position(temp_str+'?macro?fmreg_cursor_pos',nm_valid)); If (a2w_instdata_source <> '') then temp_str := ' '+iCASE(NameOnly(a2w_instdata_source))+' ' else begin If updateCurInstr then add_bank_position('?internal_instrument_data?pos',255,current_inst); temp_str := ' iNSTRUMENT MACRO BROWSER '; end; Case program_screen_mode of 0, 3: begin window_xsize := 73; If is_default_screen_mode then window_ysize := max(nm_valid+3,15)+10 else window_ysize := max(nm_valid+3,20)+10; end; 4, 5: begin window_xsize := 73; window_ysize := max(nm_valid+3,20)+10; end; 1: begin window_xsize := 103; window_ysize := max(nm_valid+3,20)+10; end; 2: begin window_xsize := 122; window_ysize := max(nm_valid+3,20)+10; end; end; xstart := ((work_MaxCol-window_xsize) DIV 2); ystart := ((work_MaxLn-window_ysize) DIV 2)+1; fmreg_scrlbar_items := nm_valid; fmreg_scrlbar_size := window_ysize-10-2; If NOT (program_screen_mode in [0,3,4,5]) then _fmreg_add_prev_size := 10 else _fmreg_add_prev_size := 0; If update_current_inst then begin temp_str := temp_str + '(iNS_ ) '; idx := current_inst; end else temp_str := temp_str + '[iNS_ ] '; a2w_institle_pos := (window_xsize DIV 2)+(Length(temp_str) DIV 2)-3; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,window_xsize,window_ysize, temp_str, macro_background+macro_border, macro_background+macro_title, frame_double); ShowStr(centered_frame_vdest,xstart+1,ystart+window_ysize-10+1, ExpStrR('',window_xsize-1,#205), macro_background+macro_topic2); ShowStr(centered_frame_vdest,xstart+1,ystart+window_ysize-2, ExpStrR('',window_xsize-1,#205), macro_background+macro_topic2); ShowVStr(centered_frame_vdest,xstart+42+_fmreg_add_prev_size,ystart+window_ysize-10+1, #203#186#186#186#186#186#186#202, macro_background+macro_topic2); Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; old_topic_mask_chr := mn_setting.topic_mask_chr; old_frame_enabled := mn_setting.frame_enabled; old_shadow_enabled := mn_setting.shadow_enabled; old_winshade := mn_environment.winshade; old_center_box := mn_setting.center_box; old_show_scrollbar := mn_setting.show_scrollbar; old_text_attr := mn_setting.text_attr; old_text2_attr := mn_setting.text2_attr; old_short_attr := mn_setting.short_attr; old_short2_attr := mn_setting.short2_attr; old_disbld_attr := mn_setting.disbld_attr; old_contxt_attr := mn_setting.contxt_attr; old_contxt2_attr := mn_setting.contxt2_attr; old_topic_attr := mn_setting.topic_attr; old_hi_topic_attr := mn_setting.hi_topic_attr; Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); If NOT update_current_inst then mn_setting.terminate_keys[4] := 0; // TAB not possible when called from Macro Browser If NOT loadBankPossible then mn_setting.terminate_keys[5] := 0; // ^ENTER possible only in Instrument Control mn_environment.ext_proc := a2w_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; mn_setting.frame_enabled := FALSE; mn_setting.shadow_enabled := FALSE; mn_environment.winshade := FALSE; mn_setting.center_box := FALSE; mn_setting.show_scrollbar := FALSE; mn_environment.unpolite := FALSE; mn_environment.preview := TRUE; mn_environment.v_dest := ptr_temp_screen; mn_setting.text_attr := macro_background+macro_item; mn_setting.text2_attr := macro_sel_itm_bck+macro_sel_itm; mn_setting.short_attr := macro_background+macro_short; mn_setting.short2_attr := macro_sel_itm_bck+macro_sel_short; mn_setting.disbld_attr := macro_background+macro_item_dis; mn_setting.contxt_attr := macro_background+macro_context; mn_setting.contxt2_attr := macro_background+macro_context_dis; mn_setting.topic_attr := macro_background+macro_topic2; mn_setting.hi_topic_attr := macro_background+macro_hi_topic; If is_default_screen_mode then ysize := 15 else ysize := 20; _a2w_lister_count := max(nm_valid+3,ysize)-3; If NOT _force_program_quit then If (program_screen_mode in [0,3,4,5]) then index := Menu(a2w_queue,xstart,ystart,idx+3,72,max(nm_valid+3,ysize),nm_valid+3,temp_str) else If (program_screen_mode = 1) then index := Menu(a2w_queue_more,xstart,ystart,idx+3,102,max(nm_valid+3,20),nm_valid+3,temp_str) else index := Menu(a2w_queue_more2,xstart,ystart,idx+3,121,max(nm_valid+3,20),nm_valid+3,temp_str); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+window_xsize+2+1; move_to_screen_area[4] := ystart+window_ysize+1; move2screen_alt; mn_environment.unpolite := FALSE; mn_environment.preview := FALSE; mn_environment.v_dest := screen_ptr; centered_frame_vdest := mn_environment.v_dest; keyboard_reset_buffer; If NOT _force_program_quit then If (program_screen_mode in [0,3,4,5]) then index := Menu(a2w_queue,xstart,ystart,idx+3,72,max(nm_valid+3,ysize),nm_valid+3,temp_str) else If (program_screen_mode = 1) then index := Menu(a2w_queue_more,xstart,ystart,idx+3,102,max(nm_valid+3,20),nm_valid+3,temp_str) else index := Menu(a2w_queue_more2,xstart,ystart,idx+3,121,max(nm_valid+3,20),nm_valid+3,temp_str); If (a2w_instdata_source <> '') then temp_str := a2w_instdata_source else temp_str := '?internal_instrument_data'; add_bank_position(temp_str+'?macro?pos',nm_valid,index); add_bank_position(temp_str+'?macro?fmreg_page',nm_valid,fmreg_page); add_bank_position(temp_str+'?macro?fmreg_hpos',nm_valid,fmreg_hpos); add_bank_position(temp_str+'?macro?fmreg_vpos',nm_valid,fmreg_vpos); add_bank_position(temp_str+'?macro?fmreg_left_margin',nm_valid,fmreg_left_margin); add_bank_position(temp_str+'?macro?fmreg_cursor_pos',nm_valid,fmreg_cursor_pos); Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; mn_setting.topic_mask_chr := old_topic_mask_chr; mn_setting.frame_enabled := old_frame_enabled; mn_setting.shadow_enabled := old_shadow_enabled; mn_environment.winshade := old_winshade; mn_setting.center_box := old_center_box; mn_setting.show_scrollbar := old_show_scrollbar; mn_setting.text_attr := old_text_attr; mn_setting.text2_attr := old_text2_attr; mn_setting.short_attr := old_short_attr; mn_setting.short2_attr := old_short2_attr; mn_setting.disbld_attr := old_disbld_attr; mn_setting.contxt_attr := old_contxt_attr; mn_setting.contxt2_attr := old_contxt2_attr; mn_setting.topic_attr := old_topic_attr; mn_setting.hi_topic_attr := old_hi_topic_attr; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+window_xsize+2+1; move_to_screen_area[4] := ystart+window_ysize+1; move2screen; centered_frame_vdest := screen_ptr; If (mn_environment.keystroke = kESC) then GOTO _end; If (mn_environment.keystroke = kTAB) then begin arp_tab_selected := songdata.instr_macros[current_inst].arpeggio_table <> 0; vib_tab_selected := songdata.instr_macros[current_inst].vibrato_table <> 0; loadMacros := FALSE; browser_flag := TRUE; GOTO _jmp1; end; If (mn_environment.keystroke = kF1) then begin HELP('macro_browser'); If NOT _force_program_quit then GOTO _jmp2; end; _jmp2e: If (mn_environment.keystroke = kENTER) or (loadBankPossible and (mn_environment.keystroke = kCtENTR)) then begin If (mn_environment.keystroke = kENTER) then begin If shift_pressed then begin // put 4op instrument (alternate) _4op_ins_flag := FALSE; If (_4op_flag_column[index] = _4op_flag_chr_beg) then If check_4op_flag(current_inst) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else If check_4op_flag(PRED(current_inst)) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else else If (_4op_flag_column[index] = _4op_flag_chr_end) then If check_4op_flag(current_inst) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := PRED(index); _4op_idx22 := index; end else If check_4op_flag(PRED(current_inst)) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := PRED(index); _4op_idx22 := index; end; If _4op_ins_flag then _put_4op_instrument; end else begin // put 4op instrument (force) _4op_ins_flag := FALSE; If (_4op_flag_column[index] = _4op_flag_chr_beg) then begin _4op_ins_flag := TRUE; _4op_idx11 := current_inst; _4op_idx12 := SUCC(current_inst); _4op_idx21 := index; _4op_idx22 := SUCC(index); end else If (_4op_flag_column[index] = _4op_flag_chr_end) then begin _4op_ins_flag := TRUE; _4op_idx11 := PRED(min(current_inst,2)); _4op_idx12 := min(current_inst,2); _4op_idx21 := PRED(index); _4op_idx22 := index; end; If _4op_ins_flag then begin _put_4op_instrument; set_4op_flag(_4op_idx11); end; end; // put 2op instrument If NOT _4op_ins_flag then _put_2op_instrument; load_flag := 1; load_flag_alt := BYTE_NULL; end else begin If bankSelector then index := Dialog('ALL UNSAVED iNSTRUMENT AND MACRO DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2W LOADER ',1) else begin index := 1; dl_environment.keystroke := kENTER; end; If (dl_environment.keystroke <> kESC) and (index = 1) then begin temp_str := ''; For idx := 1 to 255 do If NOT (idx > nm_valid) then begin songdata.instr_data[idx] := temp_songdata.instr_data[idx]; songdata.instr_macros[idx] := temp_songdata.instr_macros[idx]; songdata.dis_fmreg_col[idx] := temp_songdata.dis_fmreg_col[idx]; songdata.instr_names[idx] := Copy(songdata.instr_names[idx],1,9)+ Copy(temp_songdata.instr_names[idx],10,32); idx1 := -1; idx2 := -1; If (songdata.instr_macros[idx].arpeggio_table <> 0) then idx1 := get_free_arpeggio_table_idx(temp_songdata.macro_table[ songdata.instr_macros[idx].arpeggio_table].arpeggio); If (songdata.instr_macros[idx].vibrato_table <> 0) then idx2 := get_free_vibrato_table_idx(temp_songdata.macro_table[ songdata.instr_macros[idx].vibrato_table].vibrato); If (temp_str = '') then If (idx1 = 0) then If (idx2 = 0) then temp_str := '~ARPEGGiO/ViBRATO' else temp_str := '~ARPEGGiO' else If (idx2 = 0) then temp_str := '~ViBRATO'; If (idx1 > 0) then begin songdata.macro_table[idx1].arpeggio := temp_songdata.macro_table[songdata.instr_macros[idx].arpeggio_table].arpeggio; songdata.instr_macros[idx].arpeggio_table := idx1; end; If (idx2 > 0) then begin songdata.macro_table[idx2].vibrato := temp_songdata.macro_table[songdata.instr_macros[idx].vibrato_table].vibrato; songdata.instr_macros[idx].vibrato_table := idx2; end; end else begin FillChar(songdata.instr_data[idx],SizeOf(songdata.instr_data[idx]),0); FillChar(songdata.instr_macros[idx],SizeOf(songdata.instr_macros[idx]),0); FillChar(songdata.dis_fmreg_col[idx],SizeOf(songdata.dis_fmreg_col[idx]),0); songdata.instr_names[idx] := Copy(songdata.instr_names[idx],1,9); end; songdata.ins_4op_flags := temp_songdata.ins_4op_flags; If (temp_str <> '') then Dialog('RELATED '+temp_str+' DATA~ WAS NOT LOADED!$'+ 'FREE SOME SPACE iN MACRO TABLES AND ~REPEAT THiS ACTiON~$', '~O~K$',' A2W LOADER ',1); load_flag := 1; load_flag_alt := BYTE_NULL; end; end; end; end; _end: If browser_flag then GOTO _jmp2; arpvib_arpeggio_table := arpvib_arpeggio_table_bak; arpvib_vibrato_table := arpvib_vibrato_table_bak; {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; type tBNK_HEADER = Record fver_major : Byte; fver_minor : Byte; signature : array[1..6] of Char; entries_used : Word; total_entries : Word; name_offset : Longint; data_offset : Longint; filler : array[1..8] of Byte; end; type tBNK_NAME_RECORD = Record data_index : Word; usage_flag : Boolean; ins_name : array[1..9] of Char; end; type tBNK_OPERATOR = Record ksl, freq_mult, feedback, attack, sust_level, sustain, decay, release, output, am, vib, ksr, fm: Byte; end; type tBNK_DATA_RECORD = Record mode : Byte; voice_num : Byte; modulator : tBNK_OPERATOR; carrier : tBNK_OPERATOR; wform_mod : Byte; wform_car : Byte; end; const bnk_id = 'ADLIB-'; MAX_TIMBRES = 4096; var bnk_queue: array[1..MAX_TIMBRES+3] of String[72]; bnk_skip: Byte; name_record: tBNK_NAME_RECORD; data_record: tBNK_DATA_RECORD; procedure import_instrument_from_data_record; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:import_instrument_from_data_record'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); With temp_instrument.fm_data do begin AM_VIB_EG_modulator := data_record.modulator.freq_mult AND $0f+ data_record.modulator.ksr AND 1 SHL 4+ data_record.modulator.sustain AND 1 SHL 5+ data_record.modulator.vib AND 1 SHL 6+ data_record.modulator.am AND 1 SHL 7; AM_VIB_EG_carrier := data_record.carrier.freq_mult AND $0f+ data_record.carrier.ksr AND 1 SHL 4+ data_record.carrier.sustain AND 1 SHL 5+ data_record.carrier.vib AND 1 SHL 6+ data_record.carrier.am AND 1 SHL 7; KSL_VOLUM_modulator := data_record.modulator.output AND $3f+ data_record.modulator.ksl AND 3 SHL 6; KSL_VOLUM_carrier := data_record.carrier.output AND $3f+ data_record.carrier.ksl AND 3 SHL 6; ATTCK_DEC_modulator := data_record.modulator.decay AND $0f+ data_record.modulator.attack AND $0f SHL 4; ATTCK_DEC_carrier := data_record.carrier.decay AND $0f+ data_record.carrier.attack AND $0f SHL 4; SUSTN_REL_modulator := data_record.modulator.release AND $0f+ data_record.modulator.sust_level AND $0f SHL 4; SUSTN_REL_carrier := data_record.carrier.release AND $0f+ data_record.carrier.sust_level AND $0f SHL 4; WAVEFORM_modulator := data_record.wform_mod AND 7; WAVEFORM_carrier := data_record.wform_car AND 7; FEEDBACK_FM := data_record.modulator.fm XOR 1 AND 1+ data_record.modulator.feedback AND 7 SHL 1; end; If (data_record.voice_num in [6..10]) then temp_instrument.perc_voice := data_record.voice_num-5; end; procedure bnk_file_loader_alt(instr: Word); var f: File; header: tBNK_HEADER; temp: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:bnk_file_loader_alt'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) then begin CloseF(f); EXIT; end; If NOT ((header.fver_major = 1) and (header.fver_minor = 0)) then begin CloseF(f); EXIT; end; If (instr > max(header.total_entries,MAX_TIMBRES)) or (header.signature <> bnk_id) or (header.total_entries < header.entries_used) then begin CloseF(f); EXIT; end; SeekF(f,header.name_offset+PRED(instr)*SizeOf(name_record)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,name_record,SizeOf(name_record),temp); If (temp <> SizeOf(name_record)) then begin CloseF(f); EXIT; end; SeekF(f,header.data_offset+name_record.data_index*SizeOf(data_record)); If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,data_record,SizeOf(data_record),temp); If (temp <> SizeOf(data_record)) then begin CloseF(f); EXIT; end; import_instrument_from_data_record; CloseF(f); load_flag_alt := 1; end; type tFIB_HEADER = Record ident: array[1..4] of Char; nmins: Word; end; type tFIN_DATA = Record dname: array[1..12] of Char; iname: array[1..27] of Char; idata: tFM_INST_DATA; end; procedure fib_file_loader_alt(instr: Word); const id = 'FIB'+#244; var f: File; ident: array[1..4] of Char; header: tFIB_HEADER; temp: Longint; instrument_data: tFIN_DATA; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fib_file_loader_alt'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header.ident <> id) then begin CloseF(f); EXIT; end; SeekF(f,SizeOf(header)+header.nmins*SizeOf(instrument_data)); If (IOresult <> 0) then EXIT; BlockReadF(f,ident,SizeOf(ident),temp); If (temp <> SizeOf(ident)) or (ident <> id) then begin CloseF(f); EXIT; end; SeekF(f,SizeOf(header)+PRED(instr)*SizeOf(instrument_data)); If (IOresult <> 0) then EXIT; BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); EXIT; end; import_standard_instrument_alt(instrument_data.idata); CloseF(f); load_flag_alt := 1; end; var ibk_queue: array[1..128+3] of String[45]; ibk_skip: Byte; procedure import_sbi_instrument_alt(var data); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:import_sbi_instrument_alt'; {$ENDIF} FillChar(temp_instrument,SizeOf(temp_instrument),0); With temp_instrument 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; temp_instrument.panning := 0; temp_instrument.fine_tune := 0; end; procedure ibk_file_loader_alt(instr: Word); const id = 'IBK'+#26; var f: File; header: array[1..4] of Char; temp: Longint; instrument_data: Record idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:ibk_file_loader_alt'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header <> id) then begin CloseF(f); EXIT; end; SeekF(f,$004+PRED(instr)*SizeOf(instrument_data)); If (IOresult <> 0) then EXIT; BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); EXIT; end; import_sbi_instrument_alt(instrument_data); CloseF(f); load_flag_alt := 1; end; procedure bnk_file_loader; const _perc_voice: array[1..5] of String[2] = ('BD','SD','TT','TC','HH'); var f: File; header: tBNK_HEADER; temp: Longint; index: Word; old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; xstart,ystart: Byte; nm_valid: Word; ysize: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:bnk_file_loader:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; end; begin { bnk_file_loader } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:bnk_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; If NOT ((header.fver_major = 1) and (header.fver_minor = 0)) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; If (header.signature <> bnk_id) or (header.total_entries < header.entries_used) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' '+iCASE(NameOnly(instdata_source))+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; bnk_queue[1] := bnk_header_str[1]; bnk_queue[2] := bnk_header_str[2]; bnk_queue[3] := bnk_header_str[3]; progress_num_steps := 1; progress_step := 1; progress_value := max(header.total_entries,MAX_TIMBRES); progress_old_value := BYTE_NULL; progress_xstart := xstart+2; progress_ystart := ystart+2; ShowCStr(screen_ptr,xstart+2,ystart+1, 'LOADiNG DATA FROM BANK FiLE...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(0); nm_valid := 0; bnk_skip := 0; For index := 1 to max(header.total_entries,MAX_TIMBRES) do begin If (ticklooper = 0) then If keypressed and (index > 1) then begin fkey := getkey; If (fkey = kESC) then begin Dec(index); BREAK; end; end; If (ticklooper = 0) then show_progress(index,3); SeekF(f,header.name_offset+PRED(index)*SizeOf(name_record)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; BlockReadF(f,name_record,SizeOf(name_record),temp); If (temp <> SizeOf(name_record)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; SeekF(f,header.data_offset+name_record.data_index*SizeOf(data_record)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; BlockReadF(f,data_record,SizeOf(data_record),temp); If (temp <> SizeOf(data_record)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' BNK LOADER ',1); EXIT; end; import_instrument_from_data_record; If name_record.usage_flag then begin bnk_queue[3+index-bnk_skip] := '~ ~~'; Inc(nm_valid); end else begin If (nm_valid = 0) then begin Inc(bnk_skip); CONTINUE; end; bnk_queue[3+index-bnk_skip] := ' '; end; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+ ExpStrR(CutStr(asciiz_string(name_record.ins_name)),11,' ')+'~ '; With temp_instrument.fm_data do begin bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(AM_VIB_EG_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(AM_VIB_EG_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(KSL_VOLUM_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(KSL_VOLUM_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(ATTCK_DEC_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(ATTCK_DEC_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(SUSTN_REL_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(SUSTN_REL_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(WAVEFORM_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(WAVEFORM_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(FEEDBACK_FM)+' '; end; Case data_record.mode of 0: bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+'MELODiC'; 1: Case data_record.voice_num of 6..10: bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+'PERCUSSiON ('+ _perc_voice[data_record.voice_num-5]+')'; else bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+'PERCUSSiON (??)'; end; else bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+'???'; end; end; CloseF(f); show_progress(index); // delay for awhile to show progress bar {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; If (nm_valid = 0) then EXIT; If (index = header.total_entries) and (bnk_skip = 0) then mn_environment.context := '~[~'+Num2str(nm_valid,10)+'~/'+ Num2str(index,10)+']~' else mn_environment.context := '['+Num2str(nm_valid,10)+']~['+ Num2str(index,10)+'/'+ Num2str(header.total_entries,10)+']~'; old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; mn_environment.ext_proc := bnk_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; If is_default_screen_mode then ysize := 20 else ysize := 30; keyboard_reset_buffer; If NOT _force_program_quit then index := Menu(bnk_queue,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 72,ysize,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' '); add_bank_position(instdata_source,nm_valid,index+3); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; If (mn_environment.keystroke = kENTER) then begin load_flag := 1; load_flag_alt := BYTE_NULL; bnk_file_loader_alt(bnk_skip+index); If (load_flag_alt <> BYTE_NULL) then begin songdata.instr_data[current_inst] := temp_instrument; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(bnk_queue[3+index],5,8); end; end; end; procedure fib_file_loader; const id = 'FIB'#244; var f: File; ident: array[1..4] of Char; header: tFIB_HEADER; temp: Longint; index: Word; old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; xstart,ystart: Byte; instrument_data: tFIN_DATA; nm_valid: Word; ysize: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fib_file_loader:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; end; begin { fib_file_loader } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fib_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header.ident <> id) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' '+iCASE(NameOnly(instdata_source))+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; bnk_queue[1] := fib_header_str[1]; bnk_queue[2] := fib_header_str[2]; bnk_queue[3] := fib_header_str[3]; progress_num_steps := 1; progress_step := 1; progress_value := max(header.nmins,MAX_TIMBRES); progress_old_value := BYTE_NULL; progress_xstart := xstart+2; progress_ystart := ystart+2; ShowCStr(screen_ptr,xstart+2,ystart+1, 'LOADiNG DATA FROM BANK FiLE...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(0); nm_valid := 0; bnk_skip := 0; For index := 1 to max(header.nmins,MAX_TIMBRES) do begin If (ticklooper = 0) then If keypressed and (index > 1) then begin fkey := getkey; If (fkey = kESC) then begin Dec(index); BREAK; end; end; If (ticklooper = 0) then show_progress(index,3); BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; import_standard_instrument_alt(instrument_data.idata); If NOT Empty(instrument_data.idata,SizeOf(instrument_data.idata)) then begin bnk_queue[3+index-bnk_skip] := '~ ~~'; Inc(nm_valid); end else begin If (nm_valid = 0) then begin Inc(bnk_skip); CONTINUE; end; bnk_queue[3+index-bnk_skip] := ' '; end; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+ ExpStrR(Upper(CutStr(BaseNameOnly(instrument_data.dname))),8,' ')+'~ '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+ ExpStrR(CutStr(instrument_data.iname),27,' ')+' '; With temp_instrument.fm_data do begin bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(AM_VIB_EG_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(AM_VIB_EG_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(KSL_VOLUM_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(KSL_VOLUM_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(ATTCK_DEC_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(ATTCK_DEC_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(SUSTN_REL_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(SUSTN_REL_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(WAVEFORM_carrier); bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(WAVEFORM_modulator)+' '; bnk_queue[3+index-bnk_skip] := bnk_queue[3+index-bnk_skip]+byte2hex(FEEDBACK_FM)+' '; end; end; SeekF(f,SizeOf(header)+header.nmins*SizeOf(instrument_data)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; BlockReadF(f,ident,SizeOf(ident),temp); If (temp <> SizeOf(ident)) or (ident <> id) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiB LOADER ',1); EXIT; end; CloseF(f); show_progress(index,3); // delay for awhile to show progress bar {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; If (nm_valid = 0) then EXIT; If (index = header.nmins) and (bnk_skip = 0) then mn_environment.context := '~[~'+Num2str(nm_valid,10)+'~/'+ Num2str(index,10)+']~' else mn_environment.context := '['+Num2str(nm_valid,10)+']~['+ Num2str(index,10)+'/'+ Num2str(128,10)+']~'; old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; mn_environment.ext_proc := fib_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; If is_default_screen_mode then ysize := 20 else ysize := 30; keyboard_reset_buffer; If NOT _force_program_quit then index := Menu(bnk_queue,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 72,ysize,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' '); add_bank_position(instdata_source,nm_valid,index+3); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; If (mn_environment.keystroke = kENTER) then begin load_flag := 1; load_flag_alt := BYTE_NULL; fib_file_loader_alt(index+bnk_skip); If (load_flag_alt <> BYTE_NULL) then begin songdata.instr_data[current_inst] := temp_instrument; If (CutStr(Copy(bnk_queue[3+index],16,27)) <> '') then songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(bnk_queue[3+index],16,27) else songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(bnk_queue[3+index],5,8) end; end; end; procedure ibk_file_loader; const id = 'IBK'#26; var f: File; header: array[1..4] of Char; temp: Longint; index: Word; old_external_proc: procedure; old_topic_len: Byte; old_cycle_moves: Boolean; xstart,ystart: Byte; nm_valid: Word; ysize: Byte; instrument_name: array[1..9] of Char; instrument_data: Record idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:ibk_file_loader:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; end; begin { ibk_file_loader } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:ibk_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If (temp <> SizeOf(header)) or (header <> id) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' '+iCASE(NameOnly(instdata_source))+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; ibk_queue[1] := ibk_header_str[1]; ibk_queue[2] := ibk_header_str[2]; ibk_queue[3] := ibk_header_str[3]; progress_num_steps := 1; progress_step := 1; progress_value := 128; progress_old_value := BYTE_NULL; progress_xstart := xstart+2; progress_ystart := ystart+2; ShowCStr(screen_ptr,xstart+2,ystart+1, 'LOADiNG DATA FROM BANK FiLE...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(0); nm_valid := 0; ibk_skip := 0; For index := 1 to 128 do begin If (ticklooper = 0) then If keypressed and (index > 1) then begin fkey := getkey; If (fkey = kESC) then begin Dec(index); BREAK; end; end; If (ticklooper = 0) then show_progress(index,3); SeekF(f,$004+PRED(index)*SizeOf(instrument_data)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; BlockReadF(f,instrument_data,SizeOf(instrument_data),temp); If (temp <> SizeOf(instrument_data)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; SeekF(f,$804+PRED(index)*SizeOf(instrument_name)); If (IOresult <> 0) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; BlockReadF(f,instrument_name,SizeOf(instrument_name),temp); If (temp <> SizeOf(instrument_name)) then begin CloseF(f); _restore; Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iBK LOADER ',1); EXIT; end; import_sbi_instrument_alt(instrument_data); If NOT Empty(instrument_data,SizeOf(instrument_data)) then begin ibk_queue[3+index-ibk_skip] := '~ ~~'; Inc(nm_valid); end else begin If (nm_valid = 0) then begin Inc(ibk_skip); CONTINUE; end; ibk_queue[3+index-ibk_skip] := ' '; end; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+ ExpStrR(CutStr(asciiz_string(instrument_name)),11,' ')+'~ '; With temp_instrument.fm_data do begin ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(AM_VIB_EG_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(AM_VIB_EG_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(KSL_VOLUM_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(KSL_VOLUM_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(ATTCK_DEC_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(ATTCK_DEC_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(SUSTN_REL_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(SUSTN_REL_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(WAVEFORM_carrier); ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(WAVEFORM_modulator)+' '; ibk_queue[3+index-ibk_skip] := ibk_queue[3+index-ibk_skip]+byte2hex(FEEDBACK_FM)+' '; end; end; CloseF(f); show_progress(index,3); // delay for awhile to show progress bar {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; If (nm_valid = 0) then EXIT; If (index = 128) and (ibk_skip = 0) then mn_environment.context := '~[~'+Num2str(nm_valid,10)+'~/'+ Num2str(index,10)+']~' else mn_environment.context := '['+Num2str(nm_valid,10)+']~['+ Num2str(index,10)+'/'+ Num2str(128,10)+']~'; old_external_proc := mn_environment.ext_proc; old_topic_len := mn_setting.topic_len; old_cycle_moves := mn_setting.cycle_moves; mn_environment.ext_proc := ibk_lister_external_proc; mn_setting.topic_len := 3; mn_setting.cycle_moves := FALSE; If is_default_screen_mode then ysize := 20 else ysize := 30; keyboard_reset_buffer; If NOT _force_program_quit then index := Menu(ibk_queue,01,01,min(1,get_bank_position(instdata_source,nm_valid)), 45,ysize,nm_valid+3,' '+iCASE(NameOnly(instdata_source))+' '); add_bank_position(instdata_source,nm_valid,index+3); mn_environment.ext_proc := old_external_proc; mn_setting.topic_len := old_topic_len; mn_setting.cycle_moves := old_cycle_moves; If (mn_environment.keystroke = kENTER) then begin load_flag := 1; load_flag_alt := BYTE_NULL; ibk_file_loader_alt(index+ibk_skip); If (load_flag_alt <> BYTE_NULL) then begin songdata.instr_data[current_inst] := temp_instrument; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Copy(ibk_queue[3+index],5,8); end; end; end; procedure a2b_lister_external_proc_callback; var test_ins1: Byte; test_ins2: Byte; curr_inst: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2b_lister_external_proc_callback'; {$ENDIF} If (get_4op_to_test_temp <> 0) then begin test_ins1 := LO(get_4op_to_test_temp); test_ins2 := HI(get_4op_to_test_temp); end else begin curr_inst := mn_environment.curr_pos; If NOT (curr_inst in [1..255]) then EXIT; test_ins1 := curr_inst; test_ins2 := 0; end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt(count_channel(pattern_hpos), mn_environment.keystroke, FALSE,TRUE,FALSE, // test instrument from bank, without any macros test_ins1,test_ins2); end; procedure a2w_lister_external_proc_callback; var test_ins1: Byte; test_ins2: Byte; curr_inst: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_lister_external_proc'; {$ENDIF} If (get_4op_to_test_temp <> 0) then begin test_ins1 := LO(get_4op_to_test_temp); test_ins2 := HI(get_4op_to_test_temp); end else begin curr_inst := mn_environment.curr_pos; If NOT (curr_inst in [1..255]) then EXIT; test_ins1 := curr_inst; test_ins2 := 0; end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt(count_channel(pattern_hpos), mn_environment.keystroke, TRUE,TRUE,FALSE, // test instrument from bank, with chosen FM-data and macro test_ins1,test_ins2); // and current Arp./Vib. macro tables end; procedure a2w_macro_lister_external_proc_callback; var test_ins1: Byte; test_ins2: Byte; curr_inst: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:a2w_macro_lister_external_proc_callback'; {$ENDIF} If (get_4op_to_test_temp <> 0) then begin test_ins1 := LO(get_4op_to_test_temp); test_ins2 := HI(get_4op_to_test_temp); end else begin curr_inst := mn_environment.curr_pos; If NOT (curr_inst in [1..255]) then EXIT; test_ins1 := curr_inst; test_ins2 := 0; end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt(count_channel(pattern_hpos), mn_environment.keystroke, FALSE,FALSE,TRUE, // test current instr, with current FM-data and macro test_ins1,test_ins2); // and chosen Arp./Vib. macro tables from bank end; procedure bnk_lister_external_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:bnk_lister_external_proc'; {$ENDIF} mn_environment.curr_item := Num2str(mn_environment.curr_pos+bnk_skip,10)+'.bnk'; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt2(count_channel(pattern_hpos), mn_environment.keystroke); end; procedure fib_lister_external_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:fib_lister_external_proc'; {$ENDIF} mn_environment.curr_item := Num2str(mn_environment.curr_pos+bnk_skip,10)+'.fib'; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt2(count_channel(pattern_hpos), mn_environment.keystroke); end; procedure ibk_lister_external_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT5.PAS:ibk_lister_external_proc'; {$ENDIF} mn_environment.curr_item := Num2str(mn_environment.curr_pos+ibk_skip,10)+'.ibk'; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then test_instrument_alt2(count_channel(pattern_hpos), mn_environment.keystroke); end; end. adlibtracker2-2.4.24/lgpl-2.1.txt0000644000000000000000000006461713411003760015020 0ustar rootroot GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! adlibtracker2-2.4.24/stringio.pas0000644000000000000000000007464113411003760015364 0ustar rootroot// 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 type tCHARSET = Set of Char; const DEC_NUM_CHARSET = ['0'..'9']; HEX_NUM_CHARSET = ['0'..'9','a'..'f','A'..'F']; 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 iCASE(str: String): String; function RotStrL(str1,str2: String; shift: Byte): String; function RotStrR(str1,str2: String; shift: Byte): String; function ExpStrL(str: String; size: Byte; chr: Char): String; function ExpStrR(str: String; size: Byte; chr: Char): String; function ExpC2StrL(str: String; size: Byte; chr: Char): String; function ExpC2StrR(str: String; size: Byte; chr: Char): String; function ExpC3StrL(str: String; size: Byte; chr: Char): String; function ExpC3StrR(str: String; size: Byte; chr: Char): String; function CenterStr(str: String; size: Byte): String; function DietStr(str: String; size: Byte): String; function CutStr(str: String): String; function CutStrL(str: String; margin: Byte): String; function CutStrR(str: String; margin: Byte): String; function FlipStr(str: String): String; function FilterStr(str: String; chr0,chr1: Char): String; function FilterStr1(str: String; chr0: Char): String; function FilterStr2(str: String; chr0: tCHARSET; chr1: Char): String; function Num2str(num: Longint; base: Byte): String; function Str2num(str: String; base: Byte): Longint; function Bpm2str(bpm: Real): String; type tINPUT_STR_SETTING = Record insert_mode, replace_enabled, append_enabled: Boolean; char_filter, character_set, valid_chars, word_characters: tCHARSET; terminate_keys: array[1..50] of Word; end; type tINPUT_STR_ENVIRONMENT = Record keystroke: Word; locate_pos: Byte; insert_mode: Boolean; min_num: Dword; max_num: Dword; cur_str: String; ext_proc: procedure; end; const is_setting: tINPUT_STR_SETTING = (insert_mode: TRUE; replace_enabled: TRUE; append_enabled: TRUE; char_filter: [#32..#255]; character_set: [#32..#255]; valid_chars: [#32..#255]; word_characters: ['A'..'Z','a'..'z','0'..'9','_']; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); var is_environment: tINPUT_STR_ENVIRONMENT; function InputStr(s: String; x,y,ln,ln1: Byte; atr1,atr2: Byte): String; function SameName(str1,str2: String): Boolean; function PathOnly(path: String): String; function NameOnly(path: String): String; function BaseNameOnly(path: String): String; function ExtOnly(path: String): String; procedure StringIO_Init; implementation uses DOS, StrUtils, AdT2unit,AdT2sys,AdT2keyb, TxtScrIO; function byte2hex(value: Byte): String; const data: array[0..15] of char = '0123456789ABCDEF'; begin {$IFNDEF CPU64} 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; {$ELSE} byte2hex := data[value AND $0f0 SHR 4]+ data[value AND $0f]; {$ENDIF} end; function byte2dec(value: Byte): String; const data: array[0..9] of char = '0123456789'; begin {$IFNDEF CPU64} 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; {$ELSE} If (value < 100) then byte2dec := data[value DIV 10]+ data[value MOD 10] else byte2dec := data[value DIV 100]+ data[value MOD 100 DIV 10]+ data[value MOD 100 MOD 10]; {$ENDIF} 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 {$IFNDEF CPU64} 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; {$ELSE} Upper := UpCase(str); {$ENDIF} end; function Lower(str: String): String; begin {$IFNDEF CPU64} 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; {$ELSE} Lower := LowerCase(str); {$ENDIF} end; {$IFNDEF CPU64} function iCase(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 @@5 push edi push ecx @@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 pop ecx pop edi @@3: mov al,[edi] cmp al,'i'-20h jnz @@4 add al,20h @@4: mov [edi],al inc edi loop @@3 @@5: end; end; {$ELSE} function iCase(str: String): String; begin iCase := ReplaceStr(Upper(str),'I','i'); end; {$ENDIF} function RotStrL(str1,str2: String; shift: Byte): String; begin RotStrL := Copy(str1,shift+1,Length(str1)-shift)+ Copy(str2,1,shift); end; function RotStrR(str1,str2: String; shift: Byte): String; begin RotStrR := Copy(str2,Length(str2)-shift+1,shift)+ Copy(str1,1,Length(str1)-shift); end; function ExpStrL(str: String; size: Byte; chr: Char): String; begin {$IFNDEF CPU64} 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; {$ELSE} While (Length(str) < size) do str := chr+str; ExpStrL := str; {$ENDIF} end; function ExpStrR(str: String; size: Byte; chr: Char): String; begin {$IFNDEF CPU64} 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; {$ELSE} While (Length(str) < size) do str := str+chr; ExpStrR := str; {$ENDIF} end; function ExpC2StrL(str: String; size: Byte; chr: Char): String; begin While (CStr2Len(str) < size) do str := chr+str; ExpC2StrL := str; end; function ExpC2StrR(str: String; size: Byte; chr: Char): String; begin While (CStr2Len(str) < size) do str := str+chr; ExpC2StrR := str; end; function ExpC3StrL(str: String; size: Byte; chr: Char): String; begin While (C3StrLen(str) < size) do str := chr+str; ExpC3StrL := str; end; function ExpC3StrR(str: String; size: Byte; chr: Char): String; begin While (C3StrLen(str) < size) do str := str+chr; ExpC3StrR := str; end; function CenterStr(str: String; size: Byte): String; var flag: Boolean; begin flag := FALSE; While (Length(str) < size) do begin If flag then str := ' ' + str else str := str + ' '; flag := NOT flag; end; CenterStr := str; 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 (BYTE(str[0]) <> 0) and (str[1] = ' ') do Delete(str,1,1); While (BYTE(str[0]) <> 0) and (str[BYTE(str[0])] = ' ') do Delete(str,BYTE(str[0]),1); CutStr := str; end; function CutStrL(str: String; margin: Byte): String; var idx: Byte; begin If (margin = 0) then margin := Length(str) else If (margin > Length(str)) then margin := Length(str); idx := 0; While (idx+1 <= margin) and (str[idx+1] = ' ') do Inc(idx); If (idx <> 0) then Delete(str,1,idx); CutStrL := str; end; function CutStrR(str: String; margin: Byte): String; var idx: Byte; begin If (margin > Length(str)) then margin := Length(str); idx := 0; While (str[BYTE(str[0])-idx] = ' ') and (BYTE(str[0])-idx >= margin) do Inc(idx); Dec(BYTE(str[0]),idx); CutStrR := str; end; {$IFNDEF CPU64} function FlipStr(str: String): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi mov [edi],al inc edi dec edi xor ecx,ecx mov cl,al jecxz @@2 add edi,ecx @@1: mov al,[esi] inc esi mov [edi],al dec edi loop @@1 @@2: end; end; {$ELSE} function FlipStr(str: String): String; var idx: Byte; result: String; begin result := ''; For idx := 1 to Length(str) do result := str[idx]+result; FlipStr := result; end; {$ENDIF} {$IFNDEF CPU64} 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; {$ELSE} function FilterStr(str: String; chr0,chr1: Char): String; var idx: Byte; begin For idx := 1 to Length(str) do If (str[idx] = chr0) then str[idx] := chr1; FilterStr := str; end; {$ENDIF} {$IFNDEF CPU64} function FilterStr1(str: String; chr0: Char): String; begin asm lea esi,[str] mov edi,@RESULT mov al,[esi] inc esi inc edi xor ecx,ecx mov cl,al mov ebx,ecx jecxz @@4 @@1: mov al,[esi] inc esi cmp al,chr0 jnz @@2 dec ebx jmp @@3 @@2: mov [edi],al inc edi @@3: loop @@1 @@4: mov eax,ebx mov edi,@RESULT mov [edi],al end; end; {$ELSE} function FilterStr1(str: String; chr0: Char): String; var idx: Byte; result: String; begin result := ''; For idx := 1 to Length(str) do If (str[idx] <> chr0) then result := result+str[idx]; FilterStr1 := result; end; {$ENDIF} const _treat_char: array[$80..$a5] of Char = 'CueaaaaceeeiiiAAE_AooouuyOU_____aiounN'; function FilterStr2(str: String; chr0: tCHARSET; chr1: Char): String; var temp: Byte; begin For temp := 1 to Length(str) do If NOT (str[temp] in chr0) then If (str[temp] >= #128) and (str[temp] <= #165) then str[temp] := _treat_char[BYTE(str[temp])] else If (str[temp] = #0) then str[temp] := ' ' else str[temp] := chr1; FilterStr2 := str; end; {$IFNDEF CPU64} 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; {$ELSE} function Num2str(num: Longint; base: Byte): String; const hexa: array[0..PRED(16)] of Char = '0123456789ABCDEF'; var result: String; begin result := ''; If (base >= 2) and (base <= 16) then While (num > 0) do begin result := hexa[num MOD base]+result; num := num DIV base; end; If (result = '') then Num2str := '0' else Num2str := result; end; {$ENDIF} 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; function Bpm2str(bpm: Real): String; begin If (bpm < 1000) then Bpm2str := Num2str(Trunc(bpm),10)+'.'+Num2str(Trunc((bpm-Trunc(bpm))*10),10) else Bpm2str := Num2str(Round(bpm),10); end; function InputStr(s: String; x,y,ln,ln1: Byte; atr1,atr2: Byte): String; var appn,for1st,qflg,ins: Boolean; cloc,xloc,xint,attr: Byte; key: Word; s1,s2: String; function more(value1,value2: Byte): Byte; begin If (value1 >= value2) then more := value1 else more := value2; end; label _end; begin { InputStr } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'STRINGIO.PAS:InputStr'; {$ENDIF} s := Copy(s,1,ln); If (is_environment.locate_pos > ln1) then is_environment.locate_pos := ln1; If (is_environment.locate_pos > Length(s)+1) then is_environment.locate_pos := Length(s); cloc := is_environment.locate_pos; xloc := is_environment.locate_pos; xint := x; qflg := FALSE; ins := is_setting.insert_mode; appn := NOT is_setting.append_enabled; Dec(x); If ins then ThinCursor else WideCursor; s1 := s; If (BYTE(s1[0]) > ln1) then s1[0] := CHR(ln1); ShowStr(screen_ptr,xint,y,ExpStrR('',ln1,' '),atr1); ShowStr(screen_ptr,xint,y,FilterStr2(s1,is_setting.char_filter,'_'),atr2); for1st := TRUE; Repeat s2 := s1; If (xloc = 1) then s1 := Copy(s,cloc,ln1) else s1 := Copy(s,cloc-xloc+1,ln1); If NOT appn then attr := atr2 else attr := atr1; If appn and for1st then begin ShowStr(screen_ptr,xint,y,ExpStrR(FilterStr2(s1,is_setting.char_filter,'_'),ln1,' '),atr1); for1st := FALSE; end; If (s2 <> s1) then ShowStr(screen_ptr,xint,y,ExpStrR(FilterStr2(s1,is_setting.char_filter,'_'),ln1,' '),atr1); If (ln1 < ln) then If (cloc-xloc > 0) and (Length(s) > 0) then ShowStr(screen_ptr,xint,y,#17,(attr AND $0f0)+$0f) else If (cloc-xloc = 0) and (Length(s) <> 0) then ShowStr(screen_ptr,xint,y,s[1],attr) else ShowStr(screen_ptr,xint,y,' ',atr1); If (ln1 < ln) then If (cloc-xloc+ln1 < Length(s)) then ShowStr(screen_ptr,xint+ln1-1,y,#16,(attr AND $0f0)+$0f) else If (cloc-xloc+ln1 = Length(s)) then ShowStr(screen_ptr,xint+ln1-1,y,FilterStr2(s[Length(s)],is_setting.char_filter,'_'),attr) else ShowStr(screen_ptr,xint+ln1-1,y,' ',atr1); GotoXY(x+xloc,y); If keypressed then key := getkey else GOTO _end; If LookupKey(key,is_setting.terminate_keys,50) then qflg := TRUE; If NOT qflg then Case key of kTAB: appn := TRUE; kCHplus, kNPplus: If (is_setting.character_set = DEC_NUM_CHARSET) then If (Length(Num2str(SUCC(Str2num(s,10)),10)) <= ln1) and (SUCC(Str2num(s,10)) <= is_environment.max_num) then s := Num2str(SUCC(Str2num(s,10)),10) else else If (is_setting.character_set = HEX_NUM_CHARSET) then If (Length(Num2str(SUCC(Str2num(s,16)),16)) <= ln1) and (SUCC(Str2num(s,16)) <= is_environment.max_num) then s := Num2str(SUCC(Str2num(s,16)),16); kCHmins, kNPmins: If (is_setting.character_set = DEC_NUM_CHARSET) then If (Str2num(s,10) > 0) and (PRED(Str2num(s,10)) >= is_environment.min_num) then s := Num2str(PRED(Str2num(s,10)),10) else else If (is_setting.character_set = HEX_NUM_CHARSET) then If (Str2num(s,16) > 0) and (PRED(Str2num(s,16)) >= is_environment.min_num) then s := Num2str(PRED(Str2num(s,16)),16); kCtrlY: begin appn := TRUE; s := ''; cloc := 1; xloc := 1; end; kCtrlT: begin appn := TRUE; While (s[cloc] in is_setting.word_characters) and (cloc <= Length(s)) do Delete(s,cloc,1); While NOT (s[cloc] in is_setting.word_characters) and (cloc <= Length(s)) do Delete(s,cloc,1); end; kCtrlK: begin appn := TRUE; Delete(s,cloc,Length(s)); end; kCtBkSp: begin appn := TRUE; While (s[cloc-1] in is_setting.word_characters) and (cloc > 1) do begin Dec(cloc); Delete(s,cloc,1); If (xloc > 1) then Dec(xloc); end; While NOT (s[cloc-1] in is_setting.word_characters) and (cloc > 1) do begin Dec(cloc); Delete(s,cloc,1); If (xloc > 1) then Dec(xloc); end; end; kBkSPC: begin appn := TRUE; If (cloc > 1) then begin If (xloc > 1) then Dec(xloc); Dec(cloc); Delete(s,cloc,1); end; end; kDELETE: begin appn := TRUE; If (cloc <= Length(s)) then Delete(s,cloc,1); end; kCtLEFT: begin appn := TRUE; While (s[cloc] in is_setting.word_characters) and (cloc > 1) do begin Dec(cloc); If (xloc > 1) then Dec(xloc); end; While NOT (s[cloc] in is_setting.word_characters) and (cloc > 1) do begin Dec(cloc); If (xloc > 1) then Dec(xloc); end; end; kCtRGHT: begin appn := TRUE; While (s[cloc] in is_setting.word_characters) and (cloc < Length(s)) do begin Inc(cloc); If (xloc < ln1) then Inc(xloc); end; While NOT (s[cloc] in is_setting.word_characters) and (cloc < Length(s)) do begin Inc(cloc); If (xloc < ln1) then Inc(xloc); end; end; kLEFT: begin appn := TRUE; If (cloc > 1) then Dec(cloc); If (xloc > 1) then Dec(xloc); end; kRIGHT: begin appn := TRUE; If (cloc < Length(s)) or ((cloc = Length(s)) and ((Length(s) < more(ln,ln1)))) then Inc(cloc); If (xloc < ln1) and (xloc <= Length(s)) then Inc(xloc); end; kINSERT: If is_setting.replace_enabled then begin ins := NOT ins; If ins then ThinCursor else WideCursor; end; kHOME: begin appn := TRUE; cloc := 1; xloc := 1; end; kEND: begin appn := TRUE; If (Length(s) < more(ln,ln1)) then cloc := Succ(Length(s)) else cloc := Length(s); If (cloc < ln1) then xloc := cloc else xloc := ln1; end; else If (CHR(LO(key)) in tCHARSET(is_setting.character_set)) then begin If NOT appn then begin s := ''; cloc := 1; xloc := 1; end; appn := TRUE; If ins and (Length(CutStrR(s,cloc)) < ln) then begin If (Length(CutStrR(s,cloc)) < ln) then Insert(CHR(LO(key)),s,cloc) else s[cloc] := CHR(LO(key)); s := FilterStr2(s,is_setting.valid_chars,'_'); If (cloc < ln) then Inc(cloc); If (xloc < ln) and (xloc < ln1) then Inc(xloc) end else If (Length(s) < ln) or NOT ins then begin If (cloc > Length(s)) and (Length(s) < ln) then Inc(BYTE(s[0])); s[cloc] := CHR(LO(key)); s := FilterStr2(s,is_setting.valid_chars,'_'); If (cloc < ln) then Inc(cloc); If (xloc < ln) and (xloc < ln1) then Inc(xloc); end; end; end; _end: is_environment.cur_str := s; If (Addr(is_environment.ext_proc) <> NIL) then is_environment.ext_proc; {$IFDEF GO32V2} // draw_screen; keyboard_reset_buffer_alt; {$ELSE} draw_screen; // keyboard_reset_buffer; {$ENDIF} until qflg; If (cloc = 0) then is_environment.locate_pos := 1 else is_environment.locate_pos := cloc; is_environment.keystroke := key; is_environment.insert_mode := ins; InputStr := s; end; function SameName(str1,str2: String): Boolean; var LastW: Word; result: Boolean; begin asm mov [LastW],0 xor eax,eax xor ecx,ecx xor ebx,ebx lea esi,[str1] lea edi,[str2] xor ah,ah mov al,[esi] inc esi mov cx,ax mov al,[edi] inc edi mov bx,ax or cx,cx jnz @@1 or bx,bx jz @@13 jmp @@14 xor dh,dh @@1: mov al,[esi] inc esi cmp al,'*' jne @@2 dec cx jz @@13 mov dh,1 mov LastW,cx jmp @@1 @@2: cmp al,'?' jnz @@3 inc edi or bx,bx je @@12 dec bx jmp @@12 @@3: or bx,bx je @@14 cmp al,'[' jne @@11 cmp word ptr [esi],']?' je @@9 mov ah,byte ptr [edi] xor dl,dl cmp byte ptr [esi],'!' jnz @@4 inc esi dec cx jz @@14 inc dx @@4: mov al,[esi] inc esi dec cx jz @@14 cmp al,']' je @@7 cmp ah,al je @@6 cmp byte ptr [esi],'-' jne @@4 inc esi dec cx jz @@14 cmp ah,al jae @@5 inc esi dec cx jz @@14 jmp @@4 @@5: mov al,[esi] inc esi dec cx jz @@14 cmp ah,al ja @@4 @@6: or dl,dl jnz @@14 inc dx @@7: or dl,dl jz @@14 @@8: cmp al,']' je @@10 @@9: mov al,[esi] inc esi cmp al,']' loopne @@9 jne @@14 @@10: dec bx inc edi jmp @@12 @@11: cmp [edi],al jne @@14 inc edi dec bx @@12: xor dh,dh dec cx jnz @@1 or bx,bx jnz @@14 @@13: mov result,TRUE jmp @@16 @@14: or dh,dh jz @@15 jecxz @@15 or bx,bx jz @@15 inc edi dec bx jz @@15 mov ax,LastW sub ax,cx add cx,ax movsx eax,ax sub esi,eax dec esi jmp @@1 @@15: mov result,FALSE @@16: end; SameName := result; 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 FSplit(path,dir,name,ext); NameOnly := name+ext; 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_filename(ext); end; procedure StringIO_Init; begin is_environment.locate_pos := 1; is_setting.char_filter := _valid_characters; is_setting.valid_chars := _valid_characters; is_environment.min_num := 0; is_environment.max_num := SizeOf(DWORD); is_environment.cur_str := ''; is_environment.ext_proc := NIL; end; end. adlibtracker2-2.4.24/ipattord.inc0000644000000000000000000015040113411003760015327 0ustar rootroot// 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 pattern_list__proc; procedure PATTERN_LIST(page: Byte); function PATTERN_LIST_alt(page: Byte): Byte; procedure PATTERN_ORDER_page_refresh(page: Byte); procedure PATTERN_ORDER_edit(var page,hpos,vpos: Byte); } var _nm_patterns: Byte; procedure pattern_list__proc; var chunk: tCHUNK; temp,temp1,temp2, _1st,_2nd: Byte; temps: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:pattern_list__proc'; {$ENDIF} Case mn_environment.keystroke of kSPACE: If ctrl_pressed then For temp := 0 to $7f do If NOT shift_pressed then songdata.pattern_names[temp][1] := ' ' else If (songdata.pattern_names[temp][1] <> ' ') then songdata.pattern_names[temp][1] := ' ' else songdata.pattern_names[temp][1] := #16 else If (songdata.pattern_names[mn_environment.curr_pos-1][1] <> #16) then songdata.pattern_names[mn_environment.curr_pos-1][1] := #16 else songdata.pattern_names[mn_environment.curr_pos-1][1] := ' '; kAltC, kCtrlC: begin clipboard.object_type := objPattern; For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin get_chunk(mn_environment.curr_pos-1,temp2,temp1,chunk); clipboard.pattern[temp1][temp2] := chunk; end; clipboard._string := Copy(songdata.pattern_names[mn_environment.curr_pos-1],9,33); end; kAltP, kAltV, kCtrlV: If (clipboard.object_type = objPattern) then begin For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin If (mn_environment.keystroke <> kAltV) then put_chunk(mn_environment.curr_pos-1,temp2,temp1, clipboard.pattern[temp1][temp2]); If NOT (shift_pressed and (mn_environment.keystroke = kCtrlV)) then songdata.pattern_names[mn_environment.curr_pos-1] := Copy(songdata.pattern_names[mn_environment.curr_pos-1],1,8)+ clipboard._string; end; If NOT Empty(pattdata^[(mn_environment.curr_pos-1) DIV 8] [(mn_environment.curr_pos-1) MOD 8], PATTERN_SIZE) then begin songdata.pattern_names[mn_environment.curr_pos-1][9] := #15; Inc(_nm_patterns); end else songdata.pattern_names[mn_environment.curr_pos-1][9] := #14; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kCtrlN: If NOT shift_pressed then For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(mn_environment.curr_pos-1,temp2,temp1,chunk); end else For temp := 0 to $7f do If (songdata.pattern_names[temp][1] = #16) then For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(temp,temp2,temp1,chunk); end; kCtrlW: If (_patts_marked = 2) then begin _1st := 0; While (_1st < PRED(max_patterns)) and (songdata.pattern_names[_1st][1] = ' ') do Inc(_1st); _2nd := SUCC(_1st); While (_2nd < PRED(max_patterns)) and (songdata.pattern_names[_2nd][1] = ' ') do Inc(_2nd); Move(pattdata^[_1st DIV 8][_1st MOD 8], buf1, PATTERN_SIZE); temps := Copy(songdata.pattern_names[_1st],9,33); Move(pattdata^[_2nd DIV 8][_2nd MOD 8], pattdata^[_1st DIV 8][_1st MOD 8], PATTERN_SIZE); If shift_pressed then songdata.pattern_names[_1st] := Copy(songdata.pattern_names[_1st],1,8)+ Copy(songdata.pattern_names[_2nd],9,33); Move(buf1, pattdata^[_2nd DIV 8][_2nd MOD 8], PATTERN_SIZE); If shift_pressed then songdata.pattern_names[_2nd] := Copy(songdata.pattern_names[_2nd],1,8)+ temps; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kDELETE, kNPdel: If shift_pressed then begin For temp := mn_environment.curr_pos-1 to PRED(max_patterns)-1 do begin Move(pattdata^[SUCC(temp) DIV 8][SUCC(temp) MOD 8], pattdata^[temp DIV 8][temp MOD 8], PATTERN_SIZE); songdata.pattern_names[temp] := Copy(songdata.pattern_names[SUCC(temp)],1,1)+ Copy(songdata.pattern_names[temp],2,10)+ Copy(songdata.pattern_names[SUCC(temp)],12,30); songdata.pattern_names[temp][9] := songdata.pattern_names[SUCC(temp)][9]; end; FillChar(pattdata^[PRED(max_patterns) DIV 8][PRED(max_patterns) MOD 8], PATTERN_SIZE,0); songdata.pattern_names[PRED(max_patterns)] := ' '+ Copy(songdata.pattern_names[PRED(max_patterns)],2,10); songdata.pattern_names[PRED(max_patterns)][9] := #14; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kINSERT, kNPins: If shift_pressed then begin For temp := PRED(max_patterns)-1 downto mn_environment.curr_pos-1 do begin Move(pattdata^[temp DIV 8][temp MOD 8], pattdata^[SUCC(temp) DIV 8][SUCC(temp) MOD 8], PATTERN_SIZE); songdata.pattern_names[SUCC(temp)] := Copy(songdata.pattern_names[temp],1,1)+ Copy(songdata.pattern_names[SUCC(temp)],2,10)+ Copy(songdata.pattern_names[temp],12,30); songdata.pattern_names[SUCC(temp)][9] := songdata.pattern_names[temp][9]; end; FillChar(pattdata^[(mn_environment.curr_pos-1) DIV 8] [(mn_environment.curr_pos-1) MOD 8], PATTERN_SIZE,0); songdata.pattern_names[(mn_environment.curr_pos-1)] := ' '+ Copy(songdata.pattern_names[(mn_environment.curr_pos-1)],2,10); songdata.pattern_names[(mn_environment.curr_pos-1)][9] := #14; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; ShowC3Str(screen_ptr, mn_environment.xpos+13, mn_environment.desc_pos, ' [`USED`:~'+ ExpStrL(Num2str(_nm_patterns,10)+'~/'+ Num2str(max_patterns,10),8,' ')+']'+ ' [`MARKED`:~'+ ExpStrL(Num2str(_patts_marked,10),3,' ')+'~] ', dialog_background+dialog_context_dis, dialog_background+dialog_context, dialog_background+dialog_border); If NOT ((play_status <> isStopped) and tracing) then begin pattern_patt := mn_environment.curr_pos-1; PATTERN_page_refresh(pattern_page); end; mn_environment.do_refresh := TRUE; mn_environment.refresh; end; procedure PATTERN_LIST(page: Byte); const new_keys: array[1..8] of Word = (kESC,kENTER,kF1,kF2,kCtrlS, kF3,kCtrlL,kShF3); var temp: Byte; old_keys: array[1..8] of Word; temp_marks: array[0..$7f] of Char; crc2: Longint; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_LIST'; {$ENDIF} For temp := 0 to $7f do begin temp_marks[temp] := songdata.pattern_names[temp][1]; songdata.pattern_names[temp][1] := ' '; songdata.pattern_names[temp][9] := #14; end; songdata_crc := Update32(songdata.pattern_names,SizeOf(songdata.pattern_names),0); songdata_crc := Update32(pattdata^,SizeOf(pattdata^),songdata_crc); For temp := 0 to $7f do songdata.pattern_names[temp][1] := temp_marks[temp]; _jmp1: If _force_program_quit then EXIT; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); _nm_patterns := 0; For temp := 0 to PRED(max_patterns) do If NOT Empty(pattdata^[temp DIV 8][temp MOD 8],PATTERN_SIZE) then begin songdata.pattern_names[temp][9] := #15; Inc(_nm_patterns); end else songdata.pattern_names[temp][9] := #14; Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); mn_setting.center_box := TRUE; mn_setting.cycle_moves := FALSE; mn_environment.edit_pos := 11; mn_setting.edit_contents := TRUE; mn_environment.ext_proc := pattern_list__proc; mn_setting.terminate_keys[3] := kF1; mn_environment.hlight_chrs := 1; pattern_list__page := Menu(songdata.pattern_names,0,0,page,42,MAX_PATTERN_ROWS+4,max_patterns,' PATTERN LiST '); Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_setting.edit_contents := FALSE; mn_environment.ext_proc := NIL; mn_setting.terminate_keys[3] := 0; mn_environment.hlight_chrs := 0; Case mn_environment.keystroke of kF1: begin HELP('pattern_list'); GOTO _jmp1; end; kF2, kCtrlS: begin quick_cmd := FALSE; pattern2use := pattern_list__page-1; FILE_save('a2p'); pattern2use := BYTE_NULL; GOTO _jmp1; end; kF3, kShF3, kCtrlL: begin If (mn_environment.keystroke = kShF3) then quick_cmd := TRUE; pattern2use := pattern_list__page-1; FILE_open('*.a2p$',FALSE); pattern2use := BYTE_NULL; quick_cmd := FALSE; GOTO _jmp1; end; end; For temp := 0 to $7f do begin temp_marks[temp] := songdata.pattern_names[temp][1]; songdata.pattern_names[temp][1] := ' '; songdata.pattern_names[temp][9] := #14; end; crc2 := Update32(songdata.pattern_names,SizeOf(songdata.pattern_names),0); If (Update32(pattdata^,SizeOf(pattdata^),crc2) <> songdata_crc) then module_archived := FALSE; For temp := 0 to $7f do songdata.pattern_names[temp][1] := temp_marks[temp]; end; function PATTERN_LIST_alt(page: Byte): Byte; const obj_name: array[tCOPY_OBJECT] of String[10] = ( '', '','', '','', 'NOTE','iNSTRUMENT','1ST EFFECT','2ND EFFECT', 'LiNE','TRACK','PATTERN','BLOCK', '','','', ''); var temp: Byte; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_LIST_alt'; {$ENDIF} If NOT (clipboard.object_type in [objNote,objInstrumentDef,objEffect,objEffect2, objLine,objTrack,objPattern,objMarkedBlock]) then begin PATTERN_LIST_alt := BYTE_NULL; EXIT; end; _nm_patterns := 0; For temp := 0 to PRED(max_patterns) do If NOT Empty(pattdata^[temp DIV 8][temp MOD 8],PATTERN_SIZE) then begin songdata.pattern_names[temp][9] := #15; Inc(_nm_patterns); end else songdata.pattern_names[temp][9] := #14; _jmp1: If _force_program_quit then EXIT; mn_setting.center_box := TRUE; mn_setting.cycle_moves := FALSE; mn_environment.ext_proc := pattern_list__proc; mn_setting.terminate_keys[3] := kF1; pattern_list__page := Menu(songdata.pattern_names,0,0,page,42,22,max_patterns, ' PATTERN LiST | PASTE "'+obj_name[clipboard.object_type]+'" '); mn_environment.ext_proc := NIL; mn_setting.terminate_keys[3] := 0; If (mn_environment.keystroke = kF1) then begin HELP('pattern_list'); GOTO _jmp1; end; If (mn_environment.keystroke <> kESC) then PATTERN_LIST_alt := pattern_list__page else PATTERN_LIST_alt := BYTE_NULL; end; procedure PATTERN_ORDER_page_refresh(page: Byte); var attr: Word; temp1,temp2: Byte; xstart: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_ORDER_page_refresh'; {$ENDIF} show_str(25+6+PATTORD_xshift+(MAX_ORDER_COLS*7-1) DIV 2+(MAX_ORDER_COLS*7-1) MOD 2,02, byte2hex(pattord_vpos+4*(pattord_hpos+pattord_page-1)-1), order_background+order_border); xstart := 20+PATTORD_xshift; For temp1 := 1 to MAX_ORDER_COLS do For temp2 := 03 to 06 do begin If NOT tracing or play_single_patt then begin If (songdata.pattern_order[temp2-2+4*(temp1+page-1)-1] < $80) then attr := concw(order_background+order_hi_pattn,order_background+order_hi_entry) else attr := concw(order_background+order_entry,order_background+order_hi_entry); end else begin If (current_order = temp2-2+4*(temp1+page-1)-1) then attr := concw(order_hi_bckg+order_hi_pattn,order_hi_bckg+order_hi_entry) else If (songdata.pattern_order[temp2-2+4*(temp1+page-1)-1] < $80) then attr := concw(order_background+order_pattn,order_background+order_entry) else attr := concw(order_background+order_pattn_jump,order_background+order_entry); end; If (songdata.pattern_order[temp2-2+4*(temp1+page-1)-1] < $80) then begin If (current_order = temp2-2+4*(temp1+page-1)-1) and (play_status <> isStopped) and NOT play_single_patt then show_cstr(xstart+pos1[temp1]-1,temp2, byte2hex(temp2-2+4*(temp1+page-1)-1)+'~ ~', order_played_b+order_played,HI(attr)) else show_str(xstart+pos1[temp1]-1,temp2, byte2hex(temp2-2+4*(temp1+page-1)-1)+' ',HI(attr)); If NOT no_trace_pattord then show_str(xstart+pos1[temp1]-1+3,temp2, byte2hex(songdata.pattern_order[temp2-2+4*(temp1+page-1)-1]),LO(attr)); If NOT tracing then If (temp1 <= MAX_ORDER_COLS-1) then show_str(xstart+pos1[temp1]-1+5,temp2,#240,order_background+order_border); end else begin show_str(xstart+pos1[temp1]-1,temp2, byte2hex(temp2-2+4*(temp1+page-1)-1)+' ',HI(attr)); If NOT no_trace_pattord then show_str(xstart+pos1[temp1]-1+3,temp2, byte2hex(songdata.pattern_order[temp2-2+4*(temp1+page-1)-1]-$80),LO(attr)); If NOT tracing then If (temp1 <= MAX_ORDER_COLS-1) then show_str(xstart+pos1[temp1]-1+5,temp2,#240,order_background+order_border); end; end; temp1 := 0; If tracing then count_order(temp1); If scroll_bars then begin If (program_screen_mode <> 2) then If (temp1 <> 0) then scroll_pos0 := vscroll_bar(MAX_COLUMNS-2,02,6,temp1, (page+pattord_hpos-1)*4+pattord_vpos,scroll_pos0, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark) else scroll_pos0 := vscroll_bar(MAX_COLUMNS-2,02,6,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos1 := vscroll_bar(MAX_COLUMNS-1,02,6,$7f, (page+pattord_hpos-1)*4+pattord_vpos,scroll_pos1, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_2nd_mark); end else begin If (program_screen_mode <> 2) then scroll_pos0 := vscroll_bar(MAX_COLUMNS-2,02,6,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos1 := vscroll_bar(MAX_COLUMNS-1,02,6,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); end; end; procedure PATTERN_ORDER_edit(var page,hpos,vpos: Byte); var nope: Boolean; tstr,temps: String; temp: Byte; temp1: Word; xstart: Byte; procedure copy_object; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_ORDER_edit:copy_object'; {$ENDIF} Case clipboard.object_type of objPatternDef: clipboard.pattern_order[0] := songdata.pattern_order[(page+hpos-1)*4+vpos-1]; objPatternTable: Move(songdata.pattern_order, clipboard.pattern_order,SizeOf(songdata.pattern_order)); end; end; procedure paste_object; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_ORDER_edit:paste_object'; {$ENDIF} Case clipboard.object_type of objPatternDef: begin songdata.pattern_order[(page+hpos-1)*4+vpos-1] := clipboard.pattern_order[0]; If vpos < 4 then Inc(vpos) else If hpos < MAX_ORDER_COLS then begin Inc(hpos); vpos := 1; end else If page < (23-(MAX_ORDER_COLS-9)) then begin Inc(page); vpos := 1; end; end; objPatternTable: Move(clipboard.pattern_order, songdata.pattern_order,SizeOf(songdata.pattern_order)); end; end; label _end; begin { PATTERN_ORDER_edit } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTORD.INC:PATTERN_ORDER_edit'; {$ENDIF} songdata_crc_ord := Update32(songdata.pattern_order, SizeOf(songdata.pattern_order),0); Repeat PATTERN_ORDER_page_refresh(page); PATTERN_page_refresh(pattern_page); xstart := 23+PATTORD_xshift; GotoXY(xstart+pos1[hpos]-1,03+vpos-1); If tracing then fkey := PATTERN_trace else ThinCursor; If ctrl_pressed and alt_pressed then begin DEBUG_INFO; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; nope := FALSE; If keypressed then fkey := getkey else GOTO _end; //CONTINUE; Case fkey of kLEFT: If hpos > 1 then Dec(hpos) else If page > 0 then Dec(page); kRIGHT: If hpos < MAX_ORDER_COLS then Inc(hpos) else If page < (23-(MAX_ORDER_COLS-9)) then Inc(page); kUP, kShTAB: If vpos > 1 then Dec(vpos) else If hpos > 1 then begin Dec(hpos); vpos := 4; end else If page > 0 then begin Dec(page); vpos := 4; end; kDOWN, kTAB: If vpos < 4 then Inc(vpos) else If hpos < MAX_ORDER_COLS then begin Inc(hpos); vpos := 1; end else If page < (23-(MAX_ORDER_COLS-9)) then begin Inc(page); vpos := 1; end; kPgUP: If page-8 > 0 then Dec(page,8) else begin If page > 0 then page := 0 else begin page := 0; hpos := 1; vpos := 1; end; end; kPgDOWN: If page+8 < (23-(MAX_ORDER_COLS-9)) then Inc(page,8) else begin If page < (23-(MAX_ORDER_COLS-9)) then page := (23-(MAX_ORDER_COLS-9)) else begin page := (23-(MAX_ORDER_COLS-9)); hpos := MAX_ORDER_COLS; vpos := 4; end; end; kHOME: begin page := 0; hpos := 1; vpos := 1; end; kEND: begin page := (23-(MAX_ORDER_COLS-9)); hpos := MAX_ORDER_COLS; vpos := 4; end; kCHmins, kNPmins: If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) then If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] > 0) then Dec(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) else else If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] > $80) then Dec(songdata.pattern_order[vpos+4*(hpos+page-1)-1]); kCHplus, kNPplus: If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) then If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $7f) then Inc(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) else else If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $ff) then begin If (vpos+4*(hpos+page-1)-1 = 0) and (songdata.pattern_order[vpos+4*(hpos+page-1)-1] = $80) then songdata.pattern_order[vpos+4*(hpos+page-1)-1] := 0 else Inc(songdata.pattern_order[vpos+4*(hpos+page-1)-1]); end; kAstrsk, kNPastr: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} For temp := 1 to songdata.nm_tracks do begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); end; kBkSPC: begin songdata.pattern_order[vpos+4*(hpos+page-1)-1] := $80; Case backspace_dir of 1: If (vpos < 4) then Inc(vpos) else If (hpos < MAX_ORDER_COLS) then begin vpos := 1; Inc(hpos); end else If (page < (23-(MAX_ORDER_COLS-9))) then begin hpos := MAX_ORDER_COLS; Inc(page); vpos := 1; end; 2: If (vpos > 1) then Dec(vpos) else If (hpos > 1) then begin Dec(hpos); vpos := 4; end else If (page > 0) then begin Dec(page); vpos := 4; end; end; end; kSPACE: If ctrl_pressed then If (vpos+4*(hpos+page-1)-1 < $7f) then begin songdata.pattern_order[vpos+4*(hpos+page-1)-1] := $80+vpos+4*(hpos+page-1); If (vpos < 4) then Inc(vpos) else If (hpos < MAX_ORDER_COLS) then begin vpos := 1; Inc(hpos); end else If (page < (23-(MAX_ORDER_COLS-9))) then begin hpos := MAX_ORDER_COLS; Inc(page); vpos := 1; end; end else begin songdata.pattern_order[vpos+4*(hpos+page-1)-1] := $80; If (vpos < 4) then Inc(vpos) else If (hpos < MAX_ORDER_COLS) then begin vpos := 1; Inc(hpos); end else If (page < (23-(MAX_ORDER_COLS-9))) then begin hpos := MAX_ORDER_COLS; Inc(page); vpos := 1; end; end; kAltL: begin LINE_MARKING_SETUP; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltM: If (mark_line <> 0) then begin mark_lines := NOT mark_lines; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltS: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} begin For temp := 1 to songdata.nm_tracks do channel_flag[temp] := FALSE; For temp := 1 to songdata.nm_tracks do If (temp = count_channel(pattern_hpos)) then begin channel_flag[temp] := TRUE; If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then channel_flag[SUCC(temp)] := TRUE else channel_flag[PRED(temp)] := TRUE; end; For temp := 1 to songdata.nm_tracks do If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltR: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} FillChar(channel_flag,songdata.nm_tracks,BYTE(TRUE)); kAlt1.. kAlt0: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} If (fkey <> kAlt0) then begin If shift_pressed then temp := HI(fkey)-$77+10 else temp := HI(fkey)-$77; If (temp <= songdata.nm_tracks) then begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then begin channel_flag[SUCC(temp)] := channel_flag[temp]; If NOT channel_flag[SUCC(temp)] then reset_chan_data(SUCC(temp)); end else If (temp in _4op_tracks_lo) then begin channel_flag[PRED(temp)] := channel_flag[temp]; If NOT channel_flag[PRED(temp)] then reset_chan_data(PRED(temp)); end; end; end else If shift_pressed or (10 in [chan_pos..chan_pos+MAX_TRACKS-1]) or (songdata.nm_tracks = 10) then begin channel_flag[10] := NOT channel_flag[10]; If NOT channel_flag[10] then reset_chan_data(10); If is_4op_chan(10) then begin channel_flag[11] := channel_flag[10]; If NOT channel_flag[11] then reset_chan_data(11); end; end else begin If NOT percussion_mode then temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$1~6~$1~7~$1~8~$1~9~$2~0~$' else temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$16 ~B~D$17 ~S~D$18 ~T~T$19 T~C~$20 ~H~H$'; temps := FlipStr(temps); For temp := 10 to 20 do If (temp > songdata.nm_tracks) then begin Delete(temps,Pos('~',temps),1); Delete(temps,Pos('~',temps),1); end; temps := FlipStr(temps); If (Pos('~',temps) <> 0) then begin chpos := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO TOGGLE TRACK ON/OFF$', temps, ' TRACK ON/OFF ',chpos); If (dl_environment.keystroke <> kESC) then begin channel_flag[9+chpos] := NOT channel_flag[9+chpos]; If NOT channel_flag[9+chpos] then reset_chan_data(9+chpos); If is_4op_chan(9+chpos) then If (9+chpos in [10,12,14]) then begin channel_flag[SUCC(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[SUCC(9+chpos)] then reset_chan_data(SUCC(9+chpos)); end else If (9+chpos in [11,13,15]) then begin channel_flag[PRED(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[PRED(9+chpos)] then reset_chan_data(PRED(9+chpos)); end; end; end; end; kINSERT: begin For temp := $7f downto (page+hpos-1)*4+vpos do songdata.pattern_order[temp] := songdata.pattern_order[temp-1]; songdata.pattern_order[(page+hpos-1)*4+vpos-1] := 0; end; kDELETE: begin For temp := (page+hpos-1)*4+vpos-1 to $7f-1 do songdata.pattern_order[temp] := songdata.pattern_order[temp+1]; songdata.pattern_order[$7f] := $080; end; kCtrlC: begin clipboard.object_type := objPatternDef; copy_object; end; kAltC: begin mn_setting.cycle_moves := TRUE; temp := Menu(copy_menu_str3,01,01,copypos3,30,15,15,' COPY OBJECT '); If (mn_environment.keystroke <> kESC) then begin copypos3 := temp; clipboard.object_type := tCOPY_OBJECT(temp); copy_object; end; end; kAltP, kCtrlV: paste_object; kCtrlT: TRANSPOSE; kCtrlR: REMAP; kCtrlB: MESSAGE_BOARD; kCtrlD: DEBUG_INFO; kCtrlO: OCTAVE_CONTROL; kCtrlP: If NOT ((play_status <> isStopped) and tracing) then PATTERN_LIST(pattern_patt+1) else begin PATTERN_LIST(old_pattern_patt+1); old_pattern_patt := pattern_list__page-1; end; kCtrlF: SONG_VARIABLES; kCtrlH: REPLACE; kCtrlI: INSTRUMENT_CONTROL; kCtrlE: INSTRUMENT_CONTROL_edit; kCtrlQ: MACRO_EDITOR(current_inst,FALSE); kCtrlG: MACRO_EDITOR(current_inst,TRUE); kCtrlM: MACRO_BROWSER(TRUE,TRUE); kCtrlX: REARRANGE; kCtLEFT: If (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If (play_status = isPlaying) then fast_forward := TRUE; kCtENTR: If play_single_patt then current_line := 0 else begin no_status_refresh := TRUE; fade_out_playback(FALSE); If (current_order < $7f) and (play_status <> isStopped) then If (songdata.pattern_order[SUCC(current_order)] < $80) then calibrate_player(SUCC(current_order),0,FALSE,FALSE) else If (calc_following_order(SUCC(current_order)) <> -1) then calibrate_player(calc_following_order(SUCC(current_order)),0,FALSE,FALSE) else else If (calc_following_order(0) <> -1) then calibrate_player(calc_following_order(0),0,FALSE,FALSE); no_status_refresh := FALSE; end; {$IFDEF GO32V2} kF1: HELP('pattern_order'); {$ELSE} kF1: If (sdl_opl3_emulator = 1) and ((play_status = isPlaying) or opl3_channel_recording_mode) then HELP('wav_recorder') else HELP('pattern_order'); {$ENDIF} kF2, kShF2, kCtrlS: begin If (fkey = kShF2) then quick_cmd := TRUE; FILE_save('a2m'); quick_cmd := FALSE; end; kCtrlF2: FILE_save('a2t'); kF3, kCtrlL: FILE_open('*.a2m$*.a2t$*.amd$*.cff$*.dfm$*.fmk$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); kF4, kCtrlA: NUKE; kF5, kAltF5, kShF5: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; isStopped: begin If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; start_playing; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF6: Case play_status of isPlaying: begin replay_forbidden := TRUE; play_status := isPaused; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; end; end; kShF6: If NOT replay_forbidden then begin debugging := TRUE; play_status := isPlaying; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If NOT play_single_patt and (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin fade_out_playback(FALSE); calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); If (play_status <> isStopped) then begin debugging := TRUE; play_status := isPlaying; replay_forbidden := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; kF7: begin fade_out_playback(FALSE); stop_playing; If (play_status <> isStopped) then FillChar(ai_table,SizeOf(ai_table),0); end; kF8, kAltF8, kShF8: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin stop_playing; calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); end; end; isStopped: If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); repeat_pattern := FALSE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF9, kAltF9, kShF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin stop_playing; calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); repeat_pattern := TRUE; end; end; isStopped: If (songdata.pattern_order[vpos+4*(hpos+page-1)-1] < $80) and (calc_pattern_pos(songdata.pattern_order[vpos+4*(hpos+page-1)-1]) <> BYTE_NULL) then begin debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; calibrate_player(vpos+4*(hpos+page-1)-1,0,TRUE,FALSE); repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF10, kESC: begin QUIT_request; If (fkey = kESC) then nope := TRUE; end; kENTER: nope := TRUE; else nope := TRUE; end; If nope and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then begin no_trace_pattord := TRUE; nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := HEX_NUM_CHARSET; is_environment.locate_pos := 2; is_setting.terminate_keys[3] := kUp; is_setting.terminate_keys[4] := kDown; is_setting.terminate_keys[5] := kTAB; is_setting.terminate_keys[6] := kShTAB; tstr := CHAR(LO(fkey)); Repeat tstr := ExpStrL(InputStr(tstr,xstart+pos1[hpos]-1,03+vpos-1, 2,2,order_input_bckg+order_input, order_input_warn+order_input),2,'0'); is_setting.append_enabled := TRUE; If (Str2num(tstr,16) in [0..$0ff]) and (is_environment.keystroke <> kESC) then begin If (Str2num(tstr,16) > $7f) and (Str2num(tstr,16)-$80 = vpos+4*(hpos+page-1)-1) then is_environment.keystroke := WORD_NULL else nope := TRUE; songdata.pattern_order[vpos+4*(hpos+page-1)-1] := Str2num(tstr,16); If (is_environment.keystroke = kENTER) then If (vpos < 4) then Inc(vpos) else If hpos < MAX_ORDER_COLS then begin vpos := 1; Inc(hpos); end else If page < (23-(MAX_ORDER_COLS-9)) then begin hpos := MAX_ORDER_COLS; Inc(page); vpos := 1; end; end; until (is_environment.keystroke = kESC) or (is_environment.keystroke = kUp) or (is_environment.keystroke = kDown) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB) or nope; no_trace_pattord := FALSE; nope := FALSE; Case is_environment.keystroke of kUP, kShTAB: If vpos > 1 then Dec(vpos) else If hpos > 1 then begin Dec(hpos); vpos := 4; end else If page > 0 then begin Dec(page); vpos := 4; end; kDOWN, kTAB: If vpos < 4 then Inc(vpos) else If hpos < MAX_ORDER_COLS then begin Inc(hpos); vpos := 1; end else If page < (23-(MAX_ORDER_COLS-9)) then begin Inc(page); vpos := 1; end; end; is_setting.terminate_keys[3] := 0; is_setting.terminate_keys[4] := 0; is_setting.terminate_keys[5] := 0; is_setting.terminate_keys[6] := 0; end; If (Update32(songdata.pattern_order,SizeOf(songdata.pattern_order),0) <> songdata_crc_ord) then module_archived := FALSE; _end: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} If scankey(SC_F11) and NOT ctrl_pressed and NOT alt_pressed and NOT shift_pressed then begin If (command_typing <> 0) then Case command_typing of 1: If cycle_pattern then begin command_typing := 2; cycle_pattern := FALSE; end else cycle_pattern := TRUE; 2: begin command_typing := 1; cycle_pattern := FALSE; end; end; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; If scankey(SC_F12) and NOT ctrl_pressed and NOT alt_pressed then begin If NOT shift_pressed then linefeed := NOT linefeed else jump_mark_mode := NOT jump_mark_mode; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; until (nope and ((fkey = kENTER) or (fkey = kESC) or (fkey = kF10))) or _force_program_quit; PATTERN_ORDER_page_refresh(page); end; adlibtracker2-2.4.24/adt2pack.pas0000644000000000000000000007772113411003760015221 0ustar rootroot// 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 AdT2pack; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface function LZH_compress(var source,dest; size: Dword): Dword; function LZH_compress_ultra(var source,dest; size: Dword): Dword; function LZH_decompress(var source,dest; size: Dword): Dword; implementation uses AdT2sys,AdT2extn,AdT2unit; const { DEFAULT COMPRESSION: buffer 4k, dictionary 8kb } WIN_SIZE_DEF = 1 SHL 12; DIC_SIZE_DEF = 1 SHL 13; { ULTRA COMPRESSION: buffer 32k, dictionary 16kb } WIN_SIZE_MAX = 1 SHL 15; 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 WIN_SIZE: Word = WIN_SIZE_DEF; 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; heap: array[0..NC] of Word; len_count: array[0..16] of Word; c_freq: array[0..2*(NC-1)] of Word; p_freq: array[0..2*(NP-1)] of Word; t_freq: array[0..2*(NT-1)] of Word; c_code: array[0..PRED(NC)] of Word; p_code: array[0..PRED(NT)] of Word; var freq,sort_ptr,pos_ptr: pWORD; buf,len,stream,child_count,level: pBYTE; parent,previous,next: pWORD; bits,heap_size,remain, dec_counter,match_len: Integer; bit_buf,sbit_buf,bit_count, block_size,depth,c_pos,pos,out_pos, match_pos,dec_ptr,out_mask,avail: 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; If NOT really_no_status_refresh then show_progress(input_buffer_idx,3); end; procedure WriteDataBlock(ptr: Pointer; size: Word); begin Move(ptr^,output_buffer^[output_buffer_idx],size); Inc(output_buffer_idx,size); If NOT really_no_status_refresh then show_progress(output_buffer_idx,3); 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; progress_old_value := BYTE_NULL; progress_value := size; If ultra_compression_flag then begin WIN_SIZE := WIN_SIZE_MAX; DIC_SIZE := DIC_SIZE_MAX; end else begin WIN_SIZE := WIN_SIZE_DEF; DIC_SIZE := DIC_SIZE_DEF; end; 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; procedure CountLen(idx: Integer); begin If (idx < bits) then If (depth < 16) then Inc(len_count[depth]) else Inc(len_count[16]) else begin Inc(depth); CountLen(l_tree[idx]); CountLen(r_tree[idx]); Dec(depth); end; end; procedure MakeLen(root: Integer); var idx,idx2: Integer; sum: Word; begin FillChar(len_count,SizeOf(len_count),0); CountLen(root); sum := 0; For idx := 16 downto 1 do Inc(sum,len_count[idx] SHL (16-idx)); While (sum <> 0) do begin Dec(len_count[16]); For idx := 15 downto 1 do If (len_count[idx] <> 0) then begin Dec(len_count[idx]); Inc(len_count[SUCC(idx)],2); BREAK; end; Dec(sum); end; For idx := 16 downto 1 do begin idx2 := PRED(len_count[idx]); While (idx2 >= 0) do begin Dec(idx2); len^[sort_ptr^[0]] := idx; sort_ptr := Addr(sort_ptr^[1]); end; end; end; procedure DownHeap(idx: Integer); var idx2,idx3: Integer; begin idx2 := heap[idx]; idx3 := idx SHL 1; While (idx3 <= heap_size) do begin If (idx3 < heap_size) and (freq^[heap[idx3]] > freq^[heap[SUCC(idx3)]]) then Inc(idx3); If (freq^[idx2] <= freq^[heap[idx3]]) then BREAK; heap[idx] := heap[idx3]; idx := idx3; idx3 := idx SHL 1; end; heap[idx] := idx2; end; procedure MakeCode(bits: Integer; len: pBYTE; code: pWORD); var idx,idx2: Integer; start: array[0..17] of Word; begin start[1] := 0; For idx := 1 to 16 do start[SUCC(idx)] := (start[idx]+len_count[idx]) SHL 1; For idx := 0 to PRED(bits) do begin idx2 := len^[idx]; code^[idx] := start[idx2]; Inc(start[idx2]); end; end; function MakeTree(n_par: Integer; f_par: pWORD; l_par: pBYTE; c_par: pWORD): Integer; var idx,idx2,idx3,avail: Integer; begin bits := n_par; freq := f_par; len := l_par; avail := bits; heap_size := 0; heap[1] := 0; For idx := 0 to PRED(bits) do begin len^[idx] := 0; If (freq^[idx] <> 0) then begin Inc(heap_size); heap[heap_size] := idx; end; end; If (heap_size < 2) then begin c_par^[heap[1]] := 0; MakeTree := heap[1]; EXIT; end; For idx := (heap_size DIV 2) downto 1 do DownHeap(idx); sort_ptr := c_par; Repeat idx := heap[1]; If (idx < bits) then begin sort_ptr^[0] := idx; sort_ptr := Addr(sort_ptr^[1]); end; heap[1] := heap[heap_size]; Dec(heap_size); DownHeap(1); idx3 := heap[1]; If (idx3 < bits) then begin sort_ptr^[0] := idx3; sort_ptr := Addr(sort_ptr^[1]); end; idx2 := avail; Inc(avail); freq^[idx2] := freq^[idx]+freq^[idx3]; heap[1] := idx2; DownHeap(1); l_tree[idx2] := idx; r_tree[idx2] := idx3; until (heap_size <= 1); sort_ptr := c_par; MakeLen(idx2); MakeCode(n_par,l_par,c_par); MakeTree := idx2; end; procedure CountFreq; var idx,idx2,bits,count: Integer; begin For idx := 0 to PRED(NT) do t_freq[idx] := 0; bits := NC; While (bits > 0) and (c_len[PRED(bits)] = 0) do Dec(bits); idx := 0; While (idx < bits) do begin idx2 := c_len[idx]; Inc(idx); If (idx2 = 0) then begin count := 1; While (idx < bits) and (c_len[idx] = 0) do begin Inc(idx); Inc(count); end; If (count <= 2) then Inc(t_freq[0],count) else If (count <= 18) then Inc(t_freq[1]) else If (count = 19) then begin Inc(t_freq[0]); Inc(t_freq[1]); end else Inc(t_freq[2]); end else Inc(t_freq[idx2+2]); end; end; procedure WritePtrLen(bits,n_bit,s_bit: Integer); var idx,idx2: Integer; begin While (bits > 0) and (p_len[PRED(bits)] = 0) do Dec(bits); PutBits(n_bit,bits); idx := 0; While (idx < bits) do begin idx2 := p_len[idx]; Inc(idx); If (idx2 <= 6) then PutBits(3,idx2) else begin Dec(idx2,3); PutBits(idx2,(1 SHL idx2)-2); end; If (idx = s_bit) then begin While (idx < 6) and (p_len[idx] = 0) do Inc(idx); PutBits(2,(idx-3) AND 3); end; end; end; procedure WriteCharLen; var idx,idx2,bits,count: Integer; begin bits := NC; While (bits > 0) and (c_len[PRED(bits)] = 0) do Dec(bits); PutBits(CBIT,bits); idx := 0; While (idx < bits) do begin idx2 := c_len[idx]; Inc(idx); If (idx2 = 0) then begin count := 1; While (idx < bits) and (c_len[idx] = 0) do begin Inc(idx); Inc(count); end; If (count <= 2) then For idx2 := 0 to PRED(count) do PutBits(p_len[0],p_code[0]) else If (count <= 18) then begin PutBits(p_len[1],p_code[1]); PutBits(4,Count-3); end else If (count = 19) then begin PutBits(p_len[0],p_code[0]); PutBits(p_len[1],p_code[1]); PutBits(4,15); end else begin PutBits(p_len[2],p_code[2]); PutBits(CBIT,count-20); end; end else PutBits(p_len[idx2+2],p_code[idx2+2]); end; end; procedure EncodePtr(ptr: Word); var idx,idx2: Word; begin idx := 0; idx2 := ptr; While (idx2 <> 0) do begin idx2 := idx2 SHR 1; Inc(idx); end; PutBits(p_len[idx],p_code[idx]); If (idx > 1) then PutBits(PRED(idx),ptr AND (PRED(1 SHL 16) SHR (17-idx))); end; procedure SendBlock; var idx,idx2,flags, root,pos,size: Word; begin root := MakeTree(NC,@c_freq,@c_len,@c_code); Size := c_freq[root]; PutBits(16,size); If (root >= NC) then begin CountFreq; root := MakeTree(NT,@t_freq,@p_len,@p_code); If (root >= NT) then WritePtrLen(NT,TBIT,3) else begin PutBits(TBIT,0); PutBits(TBIT,root); end; WriteCharLen; end else begin PutBits(TBIT,0); PutBits(TBIT,0); PutBits(CBIT,0); PutBits(CBIT,root); end; root := MakeTree(NP,@p_freq,@p_len,@p_code); If (root >= NP) then WritePtrLen(NP,PBIT,-1) else begin PutBits(PBIT,0); PutBits(PBIT,root); end; pos := 0; For idx := 0 to PRED(size) do begin If (idx AND 7 = 0) then begin flags := buf^[pos]; Inc(pos); end else flags:=flags SHL 1; If (flags AND (1 SHL 7) <> 0) then begin idx2 := buf^[pos]+(1 SHL 8); Inc(pos); PutBits(c_len[idx2],c_code[idx2]); idx2 := buf^[pos] SHL 8; Inc(pos); Inc(idx2,buf^[pos]); Inc(pos); EncodePtr(idx2); end else begin idx2 := buf^[pos]; Inc(pos); PutBits(c_len[idx2],c_code[idx2]); end; end; For idx := 0 to PRED(NC) do c_freq[idx] := 0; For idx := 0 to PRED(NP) do p_freq[idx] := 0; end; procedure Output(code,c_ptr: Word); begin out_mask := out_mask SHR 1; If (out_mask = 0) then begin out_mask := 1 SHL 7; If (out_pos >= WIN_SIZE-24) then begin SendBlock; out_pos := 0; end; c_pos := out_pos; Inc(out_pos); buf^[c_pos] := 0; end; buf^[out_pos] := code; Inc(out_pos); Inc(c_freq[code]); If (code >= 1 SHL 8) then begin buf^[c_pos] := buf^[c_pos] OR out_mask; buf^[out_pos] := c_ptr SHR 8; Inc(out_pos); buf^[out_pos] := c_ptr; Inc(out_pos); code := 0; While (c_ptr <> 0) do begin c_ptr := c_ptr SHR 1; Inc(code); end; Inc(p_freq[code]); end; end; procedure InitSlide; var idx: Word; begin For idx := DIC_SIZE to (DIC_SIZE+255) do begin level^[idx] := 1; pos_ptr^[idx] := 0; end; For idx := DIC_SIZE to PRED(2*DIC_SIZE) do parent^[idx] := 0; avail := 1; For idx := 1 to DIC_SIZE-2 do next^[idx] := SUCC(idx); next^[PRED(DIC_SIZE)] := 0; For idx := (2*DIC_SIZE) to MAX_HASH_VAL do next^[idx] := 0; end; function Child(pnode: Integer; chr: Byte): Integer; var node: Integer; begin node := next^[pnode+(chr SHL (DIC_BIT-9))+2*DIC_SIZE]; parent^[0] := pnode; While (parent^[node] <> pnode) do node := next^[node]; Child := node; end; procedure MakeChild(p_node: Integer; chr: Byte; c_node: Integer); var idx,idx2: Integer; begin idx := p_node+(chr SHL (DIC_BIT-9))+2*DIC_SIZE; idx2 := next^[idx]; next^[idx] := c_node; next^[c_node] := idx2; previous^[idx2] := c_node; previous^[c_node] := idx; parent^[c_node] := p_node; Inc(child_count^[p_node]); end; procedure SplitTree(old: Integer); var new,idx: Integer; begin new := avail; avail := next^[new]; child_count^[new] := 0; idx := previous^[old]; previous^[new] := idx; next^[idx] := new; idx := next^[old]; next^[new] := idx; previous^[idx] := new; parent^[new] := parent^[old]; level^[new] := match_len; pos_ptr^[new] := pos; MakeChild(new,stream^[match_pos+match_len],old); MakeChild(new,stream^[pos+match_len],pos); end; procedure InsertNode; var idx,idx2,idx3,idx4: Integer; chr: Byte; ptr1,ptr2: pCHAR; begin If (match_len >= 4) then begin Dec(match_len); idx2 := SUCC(match_pos) OR DIC_SIZE; idx := parent^[idx2]; While (idx = 0) do begin idx2 := next^[idx2]; idx := parent^[idx2]; end; While (level^[idx] >= match_len) do begin idx2 := idx; idx :=parent^[idx]; end; idx4 := idx; While (pos_ptr^[idx4] < 0) do begin pos_ptr^[idx4] := pos; idx4 := parent^[idx4]; end; If (idx4 < DIC_SIZE) then pos_ptr^[idx4] := pos OR PERC_FLAG; end else begin idx := stream^[pos]+DIC_SIZE; chr := stream^[SUCC(pos)]; idx2 := Child(idx,chr); If (idx2 = 0) then begin MakeChild(idx,chr,pos); match_len := 1; EXIT; end; match_len := 2; end; Repeat If (idx2 >= DIC_SIZE) then begin idx3 := MAX_MATCH; match_pos := idx2; end else begin idx3 := level^[idx2]; match_pos := pos_ptr^[idx2] AND NOT (1 SHL 15); end; If (match_pos >= pos) then Dec(match_pos,DIC_SIZE); ptr1 := Addr(stream^[pos+match_len]); ptr2 := Addr(stream^[match_pos+match_len]); While (match_len < idx3) do begin If (ptr1^ <> ptr2^) then begin SplitTree(idx2); EXIT; end; Inc(match_len); Inc(ptr1); Inc(ptr2); end; If (match_len >= MAX_MATCH) then BREAK; pos_ptr^[idx2] := pos; idx := idx2; idx2 := Child(idx,ORD(ptr1^)); If (idx2 = 0) then begin MakeChild(idx,ORD(ptr1^),pos); EXIT; end; Inc(match_len); until FALSE; idx4 := previous^[idx2]; previous^[pos] := idx4; next^[idx4] := pos; idx4 := next^[idx2]; next^[pos] := idx4; previous^[idx4] := pos; parent^[pos] := idx; parent^[idx2] := 0; next^[idx2] := pos; end; procedure DeleteNode; var idx,idx2,idx3,idx4: Integer; perc_idx: Integer; begin If (parent^[pos] = 0) then EXIT; idx := previous^[pos]; idx2 := next^[pos]; next^[idx] := idx2; previous^[idx2] := idx; idx := parent^[pos]; parent^[pos] := 0; Dec(child_count^[idx]); If (idx >= DIC_SIZE) or (child_count^[idx] > 1) then EXIT; idx3 := pos_ptr^[idx] AND NOT PERC_FLAG; If (idx3 >= pos) then Dec(idx3,DIC_SIZE); idx2 := idx3; perc_idx := parent^[idx]; idx4 := pos_ptr^[perc_idx]; While (idx4 AND PERC_FLAG <> 0) do begin idx4 := idx4 AND NOT PERC_FLAG; If (idx4 >= pos) then Dec(idx4,DIC_SIZE); If (idx4 > idx2) then idx2 := idx4; pos_ptr^[perc_idx] := idx2 OR DIC_SIZE; perc_idx := parent^[perc_idx]; idx4 := pos_ptr^[perc_idx]; end; If (perc_idx < DIC_SIZE) then begin If (idx4 >= pos) then Dec(idx4,DIC_SIZE); If (idx4 > idx2) then idx2 := idx4; pos_ptr^[perc_idx] := idx2 OR DIC_SIZE OR PERC_FLAG; end; idx2 := Child(idx,stream^[idx3+level^[idx]]); idx3 := previous^[idx2]; idx4 := next^[idx2]; next^[idx3] := idx4; previous^[idx4] := idx3; idx3 := previous^[idx]; next^[idx3] := idx2; previous^[idx2] := idx3; idx3 := next^[idx]; previous^[idx3] := idx2; next^[idx2] := idx3; parent^[idx2] := parent^[idx]; parent^[idx] := 0; next^[idx] := avail; avail := idx; end; procedure GetNextMatch; var bits: Integer; begin Dec(remain); Inc(pos); If (pos = 2*DIC_SIZE) then begin Move(stream^[DIC_SIZE],stream^[0],DIC_SIZE+MAX_MATCH); bits := ReadDataBlock(Addr(stream^[DIC_SIZE+MAX_MATCH]),DIC_SIZE); Inc(remain,bits); pos := DIC_SIZE; end; DeleteNode; InsertNode; end; function LZH_compress(var source,dest; size: Dword): Dword; var last_match_len,last_match_pos: Integer; begin LZH_compress := 0; input_buffer := Addr(source); input_buffer_idx := 0; input_buffer_size := size; output_buffer := Addr(dest); output_buffer_idx := 0; output_buffer^[input_buffer_idx] := 0; // set 'default' compression flag Inc(output_buffer_idx); Move(size,output_buffer^[output_buffer_idx],SizeOf(size)); Inc(output_buffer_idx,SizeOf(size)); progress_old_value := BYTE_NULL; progress_value := size; WIN_SIZE := WIN_SIZE_DEF; DIC_SIZE := DIC_SIZE_DEF; GetMem(stream,2*DIC_SIZE+MAX_MATCH); GetMem(level,DIC_SIZE+256); GetMem(child_count,DIC_SIZE+256); GetMem(pos_ptr,(DIC_SIZE+256) SHL 1); GetMem(parent,(DIC_SIZE*2) SHL 1); GetMem(previous,(DIC_SIZE*2) SHL 1); GetMem(next,(MAX_HASH_VAL+1) SHL 1); depth := 0; InitSlide; GetMem(buf,WIN_SIZE); buf^[0] := 0; FillChar(c_freq,SizeOf(c_freq),0); FillChar(p_freq,SizeOf(p_freq),0); out_pos := 0; out_mask := 0; bit_count := 8; sbit_buf := 0; remain := ReadDataBlock(Addr(stream^[DIC_SIZE]),DIC_SIZE+MAX_MATCH); match_len := 0; pos := DIC_SIZE; InsertNode; If (match_len > remain) then match_len := remain; While (remain > 0) do begin last_match_len := match_len; last_match_pos := match_pos; GetNextMatch; If (match_len > remain) then match_len := remain; If (match_len > last_match_len) or (last_match_len < THRESHOLD) then Output(stream^[PRED(pos)],0) else begin Output(last_match_len+(256-THRESHOLD),(pos-last_match_pos-2) AND PRED(DIC_SIZE)); Dec(last_match_len); While (last_match_len > 0) do begin GetNextMatch; Dec(last_match_len); end; If (match_len > remain) then match_len := remain; end; end; SendBlock; PutBits(7,0); FreeMem(buf,WIN_SIZE); FreeMem(next,(MAX_HASH_VAL+1) SHL 1); FreeMem(previous,(DIC_SIZE*2) SHL 1); FreeMem(parent,(DIC_SIZE*2) SHL 1); FreeMem(pos_ptr,(DIC_SIZE+256) SHL 1); FreeMem(child_count,DIC_SIZE+256); FreeMem(level,DIC_SIZE+256); FreeMem(stream,2*DIC_SIZE+MAX_MATCH); LZH_compress := output_buffer_idx; end; function LZH_compress_ultra(var source,dest; size: Dword): Dword; var last_match_len,last_match_pos: Integer; begin LZH_compress_ultra := 0; input_buffer := Addr(source); input_buffer_idx := 0; input_buffer_size := size; output_buffer := Addr(dest); output_buffer_idx := 0; output_buffer^[input_buffer_idx] := 1; // set 'ultra' compression flag Inc(output_buffer_idx); Move(size,output_buffer^[output_buffer_idx],SizeOf(size)); Inc(output_buffer_idx,SizeOf(size)); progress_old_value := BYTE_NULL; progress_value := size; WIN_SIZE := WIN_SIZE_MAX; DIC_SIZE := DIC_SIZE_MAX; GetMem(stream,2*DIC_SIZE+MAX_MATCH); GetMem(level,DIC_SIZE+256); GetMem(child_count,DIC_SIZE+256); GetMem(pos_ptr,(DIC_SIZE+256) SHL 1); GetMem(parent,(DIC_SIZE*2) SHL 1); GetMem(previous,(DIC_SIZE*2) SHL 1); GetMem(next,(MAX_HASH_VAL+1) SHL 1); depth := 0; InitSlide; GetMem(buf,WIN_SIZE); buf^[0] := 0; FillChar(c_freq,SizeOf(c_freq),0); FillChar(p_freq,SizeOf(p_freq),0); out_pos := 0; out_mask := 0; bit_count := 8; sbit_buf := 0; remain := ReadDataBlock(Addr(stream^[DIC_SIZE]),DIC_SIZE+MAX_MATCH); match_len := 0; pos := DIC_SIZE; InsertNode; If (match_len > remain) then match_len := remain; While (remain > 0) do begin last_match_len := match_len; last_match_pos := match_pos; GetNextMatch; If (match_len > remain) then match_len := remain; If (match_len > last_match_len) or (last_match_len < THRESHOLD) then Output(stream^[PRED(pos)],0) else begin Output(last_match_len+(256-THRESHOLD),(pos-last_match_pos-2) AND PRED(DIC_SIZE)); Dec(last_match_len); While (last_match_len > 0) do begin GetNextMatch; Dec(last_match_len); end; If (match_len > remain) then match_len := remain; end; end; SendBlock; PutBits(7,0); FreeMem(buf,WIN_SIZE); FreeMem(next,(MAX_HASH_VAL+1) SHL 1); FreeMem(previous,(DIC_SIZE*2) SHL 1); FreeMem(parent,(DIC_SIZE*2) SHL 1); FreeMem(pos_ptr,(DIC_SIZE+256) SHL 1); FreeMem(child_count,DIC_SIZE+256); FreeMem(level,DIC_SIZE+256); FreeMem(stream,2*DIC_SIZE+MAX_MATCH); LZH_compress_ultra := output_buffer_idx; end; end. adlibtracker2-2.4.24/menulib1.pas0000644000000000000000000004624213411003760015236 0ustar rootroot// 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 MenuLib1; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface uses DOS, AdT2unit,AdT2sys,AdT2keyb,AdT2ext2, DialogIO,TxtScrIO,StringIO,ParserIO; const MenuLib1_mn_setting: Record frame_type: String; shadow_enabled: Boolean; posbar_enabled: Boolean; title_attr, menu_attr, text_attr, text2_attr, default_attr, short_attr, short2_attr, disbld_attr, contxt_attr, contxt2_attr: Byte; center_box: Boolean; cycle_moves: Boolean; edit_contents: Boolean; reverse_use: Boolean; fixed_len: Byte; terminate_keys: array[1..50] of Word; end = (frame_type: frame_single; shadow_enabled: TRUE; posbar_enabled: TRUE; title_attr: $0f; menu_attr: $07; text_attr: $07; text2_attr: $70; default_attr: $0f; short_attr: $0f; short2_attr: $70; disbld_attr: $07; contxt_attr: $0f; contxt2_attr: $07; center_box: TRUE; cycle_moves: TRUE; edit_contents: FALSE; reverse_use: FALSE; fixed_len: 0; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); var MenuLib1_mn_environment: Record v_dest: tSCREEN_MEM_PTR; keystroke: Word; context: String; unpolite: Boolean; winshade: Boolean; edit_pos: Byte; curr_pos: Word; ext_proc: procedure; refresh: procedure; do_refresh: Boolean; preview: Boolean; descr_len: Byte; descr: Pointer; end; function MenuLib1_Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure MenuLib1_Init; implementation type tDBUFFR = array[1.. 100] of Record str: String; pos: Byte; key: Char; use: Boolean; end; type tMBUFFR = array[1..16384] of Record key: Char; use: Boolean; end; var idx,idx2,max,len2b,page, first,last,temp,temp2,opage,opos: Word; old_fr_shadow_enabled: Boolean; key: Word; solid: Boolean; qflg: Boolean; mbuf: tMBUFFR; contxt: String; var mnu_x,mnu_y,mnu_len,mnu_len2: Byte; mnu_data: Pointer; mnu_count: Word; var vscrollbar_pos: Word; function OutKey(str: String): Char; var result: Char; begin If (SYSTEM.Pos('~',str) = 0) then result := '~' else If (str[SYSTEM.Pos('~',str)+2] <> '~') then result := '~' else result := str[SYSTEM.Pos('~',str)+1]; OutKey := result; end; function pstr(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:pstr'; {$ENDIF} Move(pBYTE(mnu_data)[(item-1)*(mnu_len+1)],temp,mnu_len+1); If NOT solid then pstr := ExpStrR(temp,mnu_len-2,' ') else pstr := ExpStrR(temp,mnu_len,' '); end; function pdes(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:pdes'; {$ENDIF} If (mn_environment.descr <> NIL) then Move(pBYTE(mn_environment.descr)[(item-1)*(mn_environment.descr_len+1)],temp,mn_environment.descr_len+1) else temp := ''; pdes := ExpStrR(temp,mn_environment.descr_len,' '); end; procedure refresh; procedure ShowCStr_clone(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); var temp,len: Byte; highlighted: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:refresh:ShowCStr_clone'; {$ENDIF} If NOT (MenuLib1_mn_setting.fixed_len <> 0) then begin ShowCStr(dest,x,y,str,atr1,atr2); EXIT; end; highlighted := FALSE; len := 0; For temp := 1 to Length(str) do If (str[temp] = '~') then highlighted := NOT highlighted else begin If (len < MenuLib1_mn_setting.fixed_len) then begin If NOT highlighted then ShowStr(dest,x+len,y,str[temp],atr1) else ShowStr(dest,x+len,y,str[temp],atr2); Inc(len); end else begin If NOT highlighted then ShowStr(dest,x+len,y,str[temp],atr3) else ShowStr(dest,x+len,y,str[temp],atr4); Inc(len); end end; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:refresh'; {$ENDIF} If (page = opage) and (idx2 = opos) and NOT MenuLib1_mn_environment.do_refresh then EXIT else begin opage := page; opos := idx2; MenuLib1_mn_environment.do_refresh := FALSE; end; For idx := page to mnu_len2+page-1 do If (idx = idx2+page-1) then ShowCStr_clone(MenuLib1_mn_environment.v_dest,mnu_x+1,mnu_y+idx2, ExpStrR(pstr(idx2+page-1)+pdes(idx2+page-1), max+(Length(pstr(idx2+page-1))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx2+page-1)+pdes(idx2+page-1))),' '), MenuLib1_mn_setting.text2_attr,MenuLib1_mn_setting.short2_attr, MenuLib1_mn_setting.text_attr,MenuLib1_mn_setting.short_attr) else If mbuf[idx].use then ShowCStr(MenuLib1_mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(pstr(idx)+pdes(idx), max+(Length(pstr(idx))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx)+pdes(idx))),' '), MenuLib1_mn_setting.text_attr,MenuLib1_mn_setting.short_attr) else ShowCStr(MenuLib1_mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(pstr(idx)+pdes(idx), max+(Length(pstr(idx))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx)+pdes(idx))),' '), MenuLib1_mn_setting.disbld_attr,MenuLib1_mn_setting.disbld_attr); vscrollbar_pos := VScrollBar(MenuLib1_mn_environment.v_dest,mnu_x+max+1,mnu_y+1,temp2,mnu_count,idx2+page-1, vscrollbar_pos,MenuLib1_mn_setting.menu_attr,MenuLib1_mn_setting.menu_attr); end; function MenuLib1_Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure SubPos(var p: Word); var temp: Word; begin temp := p; If (temp > 1) and mbuf[temp+page-2].use then Dec(temp) else If (temp > 1) then begin Dec(temp); SubPos(temp); end else If (page > first) then Dec(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 > first) then SubPos(temp); end; procedure AddPos(var p: Word); var temp: Word; begin temp := p; If (temp < len2) and (temp < last) and mbuf[temp+page].use then Inc(temp) else If (temp < len2) and (temp < last) then begin Inc(temp); AddPos(temp); end else If (page+temp <= last) then Inc(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 < last) then AddPos(temp); end; function RetKey(code: Byte): Word; var temp: Byte; begin RetKey := 0; For temp := 1 to count do If (UpCase(mbuf[temp].key) = UpCase(CHR(code))) then begin RetKey := temp; BREAK; end; end; procedure edit_contents(item: Word); var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:MenuLib1_Menu:edit_contents'; {$ENDIF} is_setting.append_enabled := TRUE; is_setting.character_set := [#32..#255]; is_environment.locate_pos := 1; If (MenuLib1_mn_environment.edit_pos > 0) and (MenuLib1_mn_environment.edit_pos < max-2) then temp := Copy(pstr(item),MenuLib1_mn_environment.edit_pos+1, Length(pstr(item))-MenuLib1_mn_environment.edit_pos+1) else temp := CutStr(pstr(item)); While (temp <> '') and (temp[Length(temp)] = ' ') do Delete(temp,Length(temp),1); temp := InputStr(temp,x+1+MenuLib1_mn_environment.edit_pos,y+idx2, max-2-MenuLib1_mn_environment.edit_pos+1, max-2-MenuLib1_mn_environment.edit_pos+1, MenuLib1_mn_setting.text2_attr,MenuLib1_mn_setting.default_attr); If (is_environment.keystroke = kENTER) then begin If (MenuLib1_mn_environment.edit_pos > 0) and (MenuLib1_mn_environment.edit_pos < max-2) then temp := Copy(pstr(item),1,MenuLib1_mn_environment.edit_pos)+temp else temp := CutStr(temp); Move(temp,pBYTE(mnu_data)[(item-1)*(len+1)],len+1); end; ShowCStr(MenuLib1_mn_environment.v_dest,x+1,y+idx2, ExpStrR(pstr(item),max+(Length(pstr(item)))- CStrLen(pstr(item)),' '), MenuLib1_mn_setting.text2_attr,MenuLib1_mn_setting.short2_attr); end; begin { MenuLib1_Menu } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:MenuLib1_Menu'; {$ENDIF} If (count = 0) then begin MenuLib1_Menu := 0; EXIT; end; max := Length(title); mnu_data := Addr(data); mnu_count := count; mnu_len := len; If NOT MenuLib1_mn_environment.unpolite then ScreenMemCopy(MenuLib1_mn_environment.v_dest,ptr_scr_backup); If (count < 1) then EXIT; vscrollbar_pos := BYTE_NULL; If NOT MenuLib1_mn_environment.preview then HideCursor; temp := 0; For idx := 1 to count do begin mbuf[idx].key := OutKey(pstr(idx)); If NOT MenuLib1_mn_setting.reverse_use then mbuf[idx].use := mbuf[idx].key <> '~' else mbuf[idx].use := NOT (mbuf[idx].key <> '~'); If mbuf[idx].use then temp := 1; end; solid := FALSE; If (temp = 0) then begin For temp := 1 to count do mbuf[temp].use := TRUE; solid := TRUE; end; For idx := 1 to count do If (max < CStrLen(pstr(idx))+MenuLib1_mn_environment.descr_len) then max := CStrLen(pstr(idx))+MenuLib1_mn_environment.descr_len; If MenuLib1_mn_setting.center_box then begin x := (work_MaxCol-max-2) DIV 2+(work_MaxCol-max-2) MOD 2; y := (work_MaxLn-len2-1) DIV 2+(work_MaxLn-len2-1) MOD 2; end; mnu_x := x; mnu_y := y; len2b := len2; If NOT MenuLib1_mn_environment.unpolite then begin old_fr_shadow_enabled := fr_setting.shadow_enabled; fr_setting.shadow_enabled := MenuLib1_mn_setting.shadow_enabled; fr_setting.update_area := FALSE; Frame(MenuLib1_mn_environment.v_dest,x,y,x+max+1,y+len2+1,MenuLib1_mn_setting.menu_attr, title,MenuLib1_mn_setting.title_attr,MenuLib1_mn_setting.frame_type); fr_setting.update_area := TRUE; fr_setting.shadow_enabled := old_fr_shadow_enabled; contxt := DietStr(MenuLib1_mn_environment.context,max+ (Length(MenuLib1_mn_environment.context)-CStrLen(MenuLib1_mn_environment.context))); ShowCStr(MenuLib1_mn_environment.v_dest,x+max+1-CStrLen(contxt),y+len2+1, contxt,MenuLib1_mn_setting.contxt_attr,MenuLib1_mn_setting.contxt2_attr); temp2 := len2; If (len2 > count) then len2 := count; If (len2 < 1) then len2 := 1; If (spos < 1) then spos := 1; If (spos > count) then spos := count; mnu_len2 := len2; MenuLib1_mn_environment.refresh := refresh; first := 1; last := count; While NOT mbuf[first].use do Inc(first); While NOT mbuf[last].use do Dec(last); If (spos < first) or (spos > last) then spos := first; idx2 := 1; page := 1; opage := WORD_NULL; opos := WORD_NULL; While (idx2+page-1 < spos) do AddPos(idx2); end; MenuLib1_mn_environment.curr_pos := idx2+page-1; MenuLib1_mn_environment.keystroke := WORD_NULL; If (Addr(MenuLib1_mn_environment.ext_proc) <> NIL) then MenuLib1_mn_environment.ext_proc; qflg := FALSE; If MenuLib1_mn_environment.preview then begin MenuLib1_mn_environment.preview := FALSE; MenuLib1_mn_environment.unpolite := TRUE; refresh; end else Repeat key := getkey; If LookUpKey(key,MenuLib1_mn_setting.terminate_keys,50) then If NOT ((key = MenuLib1_mn_setting.terminate_keys[2]) and MenuLib1_mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx2+page-1); If NOT qflg then If (LO(key) in [$20..$0ff]) then begin idx := RetKey(LO(key)); If (idx <> 0) then begin refresh; idx2 := idx; If NOT ((key = MenuLib1_mn_setting.terminate_keys[2]) and MenuLib1_mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx); end; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then Case key of kUP: If (page+idx2-1 > first) or NOT MenuLib1_mn_setting.cycle_moves then SubPos(idx2) else begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kDOWN: If (page+idx2-1 < last) or NOT MenuLib1_mn_setting.cycle_moves then AddPos(idx2) else begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kHOME: begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kEND: begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kPgUP: For temp := 1 to len2-1 do SubPos(idx2); kPgDOWN: For temp := 1 to len2-1 do AddPos(idx2); end; MenuLib1_mn_environment.curr_pos := idx2+page-1; refresh; MenuLib1_mn_environment.keystroke := key; If (Addr(MenuLib1_mn_environment.ext_proc) <> NIL) then MenuLib1_mn_environment.ext_proc; {$IFDEF GO32V2} // draw_screen; keyboard_reset_buffer_alt; {$ELSE} draw_screen; // keyboard_reset_buffer; {$ENDIF} until qflg or _force_program_quit; If MenuLib1_mn_environment.winshade and NOT MenuLib1_mn_environment.unpolite then begin If (Addr(move_to_screen_routine) <> NIL) then begin move_to_screen_data := ptr_scr_backup; move_to_screen_area[1] := x; move_to_screen_area[2] := y; move_to_screen_area[3] := x+max+1+2; move_to_screen_area[4] := y+len2b+1+1; move_to_screen_routine; end else ScreenMemCopy(ptr_scr_backup,MenuLib1_mn_environment.v_dest); end; MenuLib1_Menu := idx2+page-1; end; procedure MenuLib1_Init; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB1.PAS:MenuLib1_Init'; {$ENDIF} MenuLib1_mn_setting.frame_type := frame_single; MenuLib1_mn_setting.center_box := FALSE; MenuLib1_mn_setting.shadow_enabled := FALSE; MenuLib1_mn_setting.cycle_moves := FALSE; MenuLib1_mn_setting.title_attr := dialog_background+dialog_title; MenuLib1_mn_setting.menu_attr := dialog_background+dialog_text; MenuLib1_mn_setting.text_attr := dialog_background+dialog_item; MenuLib1_mn_setting.text2_attr := dialog_sel_itm_bck+dialog_sel_itm; MenuLib1_mn_setting.default_attr := dialog_def_bckg+dialog_def; MenuLib1_mn_setting.short_attr := dialog_background+dialog_short; MenuLib1_mn_setting.short2_attr := dialog_sel_itm_bck+dialog_sel_short; MenuLib1_mn_setting.disbld_attr := dialog_background+dialog_item_dis; MenuLib1_mn_setting.contxt_attr := dialog_background+dialog_context; MenuLib1_mn_setting.contxt2_attr := dialog_background+dialog_context_dis; MenuLib1_mn_setting.terminate_keys[3] := kTAB; MenuLib1_mn_setting.terminate_keys[4] := kLEFT; MenuLib1_mn_setting.terminate_keys[5] := kRIGHT; MenuLib1_mn_setting.terminate_keys[6] := kCtrlO; MenuLib1_mn_setting.terminate_keys[7] := kF1; MenuLib1_mn_setting.terminate_keys[8] := kShTAB; MenuLib1_mn_environment.v_dest := screen_ptr; MenuLib1_mn_environment.keystroke := $0000; MenuLib1_mn_environment.context := ''; MenuLib1_mn_environment.unpolite := FALSE; MenuLib1_mn_environment.winshade := TRUE; MenuLib1_mn_environment.ext_proc := NIL; MenuLib1_mn_environment.refresh := NIL; MenuLib1_mn_environment.do_refresh := FALSE; MenuLib1_mn_environment.preview := FALSE; MenuLib1_mn_environment.descr_len := 0; MenuLib1_mn_environment.descr := NIL; end; end. adlibtracker2-2.4.24/adt2ext4.pas0000644000000000000000000075631213411003760015167 0ustar rootroot// 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 AdT2ext4; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const _arp_vib_loader: Boolean = FALSE; _arp_vib_mode: Boolean = FALSE; _macro_editor__pos: array[Boolean] of Byte = (1,8); _macro_editor__fmreg_hpos: array[Boolean] of Byte = (1,1); _macro_editor__fmreg_page: array[Boolean] of Byte = (1,1); _macro_editor__fmreg_left_margin: array[Boolean] of Byte = (1,1); _macro_editor__fmreg_cursor_pos: array[Boolean] of Byte = (1,1); _macro_editor__arpeggio_page: array[Boolean] of Byte = (1,1); _macro_editor__vibrato_hpos: array[Boolean] of Byte = (1,1); _macro_editor__vibrato_page: array[Boolean] of Byte = (1,1); const arpvib_arpeggio_table: Byte = 1; arpvib_vibrato_table: Byte = 1; procedure MACRO_EDITOR(instr: Byte; arp_vib_mode: Boolean); procedure MACRO_BROWSER(instrBrowser: Boolean; updateCurInstr: Boolean); implementation uses {$IFDEF GO32V2} CRT, {$ELSE} DOS, {$ENDIF} AdT2opl3,AdT2sys,AdT2keyb,AdT2unit,AdT2extn,AdT2ext2,AdT2ext3,AdT2ext5,AdT2text,AdT2pack, StringIO,DialogIO,ParserIO,TxtScrIO,DepackIO; const _pip_xloc: Byte = 1; _pip_yloc: Byte = 1; _pip_dest: tSCREEN_MEM_PTR = NIL; _pip_loop: Boolean = FALSE; _operator_enabled: array[1..4] of Boolean = (TRUE,TRUE,TRUE,TRUE); procedure _preview_indic_proc(state: Byte); begin Case state of 0: ShowStr(_pip_dest,_pip_xloc,_pip_yloc, #16' PREViEW '#17, macro_background+macro_text_dis); 1: ShowStr(_pip_dest,_pip_xloc,_pip_yloc, #16' PREViEW '#17, macro_background+macro_text); 2: ShowStr(_pip_dest,_pip_xloc,_pip_yloc, #16' PREViEW '#17, NOT (macro_background+macro_text)); end; If _pip_loop and (state <> 0) then ShowStr(_pip_dest,_pip_xloc,_pip_yloc-1, #12' LOOP', macro_background+macro_text) else ShowStr(_pip_dest,_pip_xloc,_pip_yloc-1, #12' LOOP', macro_background+macro_text_dis); end; var _m_temp,_m_temp2,_m_temp3,_m_temp5: Byte; _m_valid_key,_m_temp4: Boolean; _m_chan_handle: array[1..18] of Byte; _m_channels: Byte; _m_flag_4op: Byte; _m_event_table_bak: array[1..20] of tCHUNK; _m_freq_table_bak,_m_freqtable2_bak: array[1..20] of Word; _m_keyoff_loop_bak: array[1..20] of Boolean; _m_channel_flag_backup: array[1..20] of Boolean; _m_fmpar_table_backup: array[1..20] of tFM_PARAMETER_TABLE; _m_volume_table_backup: array[1..20] of Word; _m_pan_lock_backup: array[1..20] of Boolean; _m_volume_lock_backup: array[1..20] of Boolean; _m_peak_lock_backup: array[1..20] of Boolean; _m_panning_table_backup: array[1..20] of Byte; _m_status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; var _bak_arpeggio_table, _bak_vibrato_table: Byte; _bak_common_flag: Byte; _bak_volume_scaling: Boolean; _bak_current_inst: Byte; _4op_mode: Boolean; function _1op_preview_active: Boolean; var temp,nm_slots: Byte; begin nm_slots := 0; For temp := 1 to 4 do If _operator_enabled[temp] then Inc(nm_slots); _1op_preview_active := (nm_slots = 1); end; procedure _macro_preview_init(state,instr2: Byte); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:_macro_preview_init'; {$ENDIF} _4op_mode := (songdata.flag_4op <> 0) and (instr2 <> BYTE_NULL); Case state of 0: begin Move(_m_fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(_m_volume_table_backup,volume_table,SizeOf(volume_table)); Move(_m_panning_table_backup,panning_table,SizeOf(panning_table)); songdata.instr_macros[_bak_current_inst].arpeggio_table := _bak_arpeggio_table; songdata.instr_macros[_bak_current_inst].vibrato_table := _bak_vibrato_table; songdata.common_flag := _bak_common_flag; volume_scaling := _bak_volume_scaling; reset_player; Move(_m_channel_flag_backup,channel_flag,SizeOf(channel_flag)); Move(_m_event_table_bak,event_table,SizeOf(event_table)); Move(_m_pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(_m_volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(_m_peak_lock_backup,peak_lock,SizeOf(volume_lock)); really_no_status_refresh := FALSE; Move(_m_freq_table_bak,freq_table,SizeOf(freq_table)); Move(_m_freqtable2_bak,freqtable2,SizeOf(freqtable2)); Move(_m_keyoff_loop_bak,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := _m_status_backup.replay_forbidden; play_status := _m_status_backup.play_status; end; 1: begin _m_status_backup.replay_forbidden := replay_forbidden; _m_status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; really_no_status_refresh := TRUE; reset_player; FillChar(_m_chan_handle,SizeOf(_m_chan_handle),0); Move(channel_flag,_m_channel_flag_backup,SizeOf(_m_channel_flag_backup)); Move(event_table,_m_event_table_bak,SizeOf(_m_event_table_bak)); FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); Move(pan_lock,_m_pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,_m_volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,_m_peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,_m_panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); _m_flag_4op := songdata.flag_4op; If NOT percussion_mode and NOT (songdata.flag_4op <> 0) then _m_channels := 18 else If NOT (songdata.flag_4op <> 0) then _m_channels := 15 else begin If _4op_mode and NOT _1op_preview_active then begin _m_flag_4op := $3f; _m_channels := 6; end else begin _m_flag_4op := 0; If NOT percussion_mode then _m_channels := 18 else _m_channels := 15; end; end; _bak_arpeggio_table := songdata.instr_macros[current_inst].arpeggio_table; _bak_vibrato_table := songdata.instr_macros[current_inst].vibrato_table; _bak_common_flag := songdata.common_flag; _bak_volume_scaling := volume_scaling; _bak_current_inst := current_inst; songdata.instr_macros[current_inst].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[current_inst].vibrato_table := ptr_vibrato_table; songdata.common_flag := songdata.common_flag AND NOT $80; volume_scaling := FALSE; reset_player; Move(fmpar_table,_m_fmpar_table_backup,SizeOf(_m_fmpar_table_backup)); Move(volume_table,_m_volume_table_backup,SizeOf(_m_volume_table_backup)); Move(freq_table,_m_freq_table_bak,SizeOf(freq_table)); Move(freqtable2,_m_freqtable2_bak,SizeOf(freqtable2)); Move(keyoff_loop,_m_keyoff_loop_bak,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); misc_register := current_tremolo_depth SHL 7+ current_vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; opl2out($01,$20); opl2out($08,$40); opl3exp($0105); opl3exp($04+_m_flag_4op SHL 8); key_off(17); key_off(18); opl2out(_instr[11],misc_register); macro_speedup := songdata.macro_speedup; If (play_status = isStopped) then update_timer(songdata.tempo); end; end; end; procedure _macro_preview_body(instr,instr2,chan: Byte; fkey: Word); function output_note(chan,board_pos: Byte): Boolean; var note: Byte; freq: Word; ins: tADTRACK2_INS; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:_macro_preview_body:output_note'; {$ENDIF} note := board_pos+12*(current_octave-1); If NOT (note in [0..12*8+1]) then begin output_note := FALSE; EXIT; end; _m_chan_handle[chan] := board_scancodes[board_pos]; If _4op_mode then chan := _4op_main_chan[chan]; If _1op_preview_active then begin If _operator_enabled[1] or _operator_enabled[2] then ins := songdata.instr_data[instr] else ins := songdata.instr_data[instr2]; pBYTE(@ins)[10] := pBYTE(@ins)[10] OR 1; load_instrument(ins,chan); If _operator_enabled[1] or _operator_enabled[2] then set_ins_volume($3f-ORD(_operator_enabled[1])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[2])*($3f-HI(volume_table[chan])), chan) else set_ins_volume($3f-ORD(_operator_enabled[3])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[4])*($3f-HI(volume_table[chan])), chan); end else begin load_instrument(songdata.instr_data[instr],chan); set_ins_volume($3f-ORD(_operator_enabled[1])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[2])*($3f-HI(volume_table[chan])), chan); If percussion_mode and (songdata.instr_data[instr].perc_voice in [4,5]) then load_instrument(songdata.instr_data[instr],_perc_sim_chan[chan]); If _4op_mode then begin load_instrument(songdata.instr_data[instr2],PRED(chan)); set_ins_volume($3f-ORD(_operator_enabled[3])*($3f-LO(volume_table[PRED(chan)])), $3f-ORD(_operator_enabled[4])*($3f-HI(volume_table[PRED(chan)])), PRED(chan)); end; end; freq := nFreq(note-1)+$2000+ SHORTINT(pBYTE(@Addr(songdata.instr_data[instr])^)[12]); event_table[chan].note := note; freq_table[chan] := freq; freqtable2[chan] := freq; key_on(chan); change_freq(chan,freq); If NOT (_1op_preview_active and (_operator_enabled[3] or _operator_enabled[4])) then init_macro_table(chan,note,instr,freq) else init_macro_table(chan,note,instr2,freq); If _4op_mode and NOT _1op_preview_active then init_macro_table(PRED(chan),note,instr2,freq); end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:_macro_preview_body'; {$ENDIF} If ctrl_pressed or alt_pressed or shift_pressed then EXIT; _m_valid_key := FALSE; For _m_temp := 1 to 29 do If NOT shift_pressed then If (board_scancodes[_m_temp] = HI(fkey)) then begin _m_valid_key := TRUE; BREAK; end; If NOT _m_valid_key or NOT (_m_temp+12*(current_octave-1)-1 in [0..12*8+1]) then EXIT; _m_temp2 := _m_temp; If percussion_mode and (songdata.instr_data[instr].perc_voice in [1..5]) then begin output_note(songdata.instr_data[instr].perc_voice+15,_m_temp2); While scankey(board_scancodes[_m_temp2]) do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; end else begin Repeat _m_valid_key := FALSE; For _m_temp := 1 to 29 do begin _m_temp2 := board_scancodes[_m_temp]; _m_temp4 := scankey(_m_temp2); If NOT _4op_mode then begin _m_temp3 := get_chanpos(_m_chan_handle,_m_channels,_m_temp2); _m_temp5 := get_chanpos(_m_chan_handle,_m_channels,0) end else begin _m_temp3 := get_chanpos2(_m_chan_handle,_m_channels,_m_temp2); _m_temp5 := get_chanpos2(_m_chan_handle,_m_channels,0) end; If _m_temp4 then _m_valid_key := TRUE; If _m_temp4 and (_m_temp3 = 0) and (_m_temp5 <> 0) then output_note(_m_temp5,_m_temp); If NOT _m_temp4 and (_m_temp3 <> 0) then begin key_off(_m_temp3); _m_chan_handle[_m_temp3] := 0; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; until NOT _m_valid_key; end; end; procedure MACRO_EDITOR(instr: Byte; arp_vib_mode: Boolean); const EMPTY_FIELD = $0ffff; COMMON_FLAG = $08000; var window_area_inc_x: Byte; window_area_inc_y: Byte; procedure fmreg_page_refresh(xpos,ypos: Byte; page: Word); forward; procedure arpeggio_page_refresh(xpos,ypos: Byte; page: Word); forward; procedure arpeggio_page_refresh_alt(xpos,ypos: Byte; page: Word); forward; procedure vibrato_page_refresh(xpos,ypos: Byte; page: Word); forward; procedure vibrato_page_refresh_alt(xpos,ypos: Byte; page: Word); forward; procedure _show_proc(show_proc_index: integer; xpos,ypos: Byte; page: Word); begin Case show_proc_index of 1: fmreg_page_refresh(xpos,ypos,page); 2: arpeggio_page_refresh(xpos,ypos,page); 3: arpeggio_page_refresh_alt(xpos,ypos,page); 4: vibrato_page_refresh(xpos,ypos,page); 5: vibrato_page_refresh_alt(xpos,ypos,page); end; end; procedure show_queue(x,y: Byte; page_len: Byte; page,len: Word; show_proc_index: integer); var temp1,temp3: Byte; spos,epos: Byte; begin If (PRED(page) < page_len DIV 2) then spos := page_len DIV 2-PRED(page) else spos := 0; If (PRED(page) > len-page_len DIV 2-1) then epos := PRED(page)-(len-page_len DIV 2-1) else epos := 0; If (spos <> 0) or (epos <> 0) then begin If (spos <> 0) then For temp3 := 1 to spos do _show_proc(show_proc_index,x,y+temp3,EMPTY_FIELD); If (epos <> 0) then For temp3 := page_len downto page_len-epos+1 do _show_proc(show_proc_index,x,y+temp3,EMPTY_FIELD); end; For temp1 := 1+spos to page_len-epos do If (temp1 <> SUCC(page_len DIV 2)) then _show_proc(show_proc_index,x,y+temp1,PRED(page)+temp1-page_len DIV 2) else _show_proc(show_proc_index,x,y+temp1,PRED(page)+temp1-page_len DIV 2+COMMON_FLAG); end; const _panning: array[0..2] of Char = #241'<>'; _hex: array[0..15] of Char = '0123456789ABCDEF'; const new_keys: array[1..38] of Word = (kF1,kESC,kENTER,kSPACE,kTAB,kShTAB,kUP,kDOWN, kCtrlO,kF2,kCtrlF2,kF3,kCtrlL,kCtrlS,kCtrlM, kCtENTR,kAltC,kAltP,kCtrlC,kCtrlV, kCtPgUP,kCtPgDN,kSPACE, kCHplus,kNPplus,kCHmins,kNPmins, kCtLbr,kCtRbr,kAlt0,kAlt1,kAlt2,kAlt3,kAlt4, kCtHOME,kCtEND,kCtLEFT,kCtRGHT); var old_keys: array[1..38] of Word; temps,tstr: String; xstart,ystart,temp,temp1: Byte; fmreg_cursor_pos, fmreg_left_margin: Byte; fmreg_hpos: Byte; pos,vibrato_hpos: Byte; old_instr,old_pos,old_arp_ptr,old_vib_ptr: Byte; old_fmreg_page,old_arpeggio_page, old_vibrato_page: Byte; refresh_flag: Byte; attr: array[1..20] of Byte; frame_type: array[1..3] of String; fmreg_page,arpeggio_page, vibrato_page: Byte; fmreg_str: String; call_pickup_proc,call_pickup_proc2: Boolean; nope: Boolean; attr2: array[1..5] of Byte; _source_ins,_source_ins2: Byte; temp_marks: array[1..255] of Char; function min0(number: Integer; flag: Integer): Integer; begin If (number > 0) then min0 := number else min0 := flag; end; function fmreg_def_attr(page: Byte): Word; var attr, attr2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:fmreg_def_attr'; {$ENDIF} If (page <= songdata.instr_macros[instr].length) then If (page >= songdata.instr_macros[instr].loop_begin) and (page <= songdata.instr_macros[instr].loop_begin+ PRED(songdata.instr_macros[instr].loop_length)) and (songdata.instr_macros[instr].loop_begin > 0) and (songdata.instr_macros[instr].loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= songdata.instr_macros[instr].keyoff_pos) and (songdata.instr_macros[instr].keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; fmreg_def_attr := attr+attr2 SHL 8; end; function _fmreg_str(page: Byte): String; var fmreg_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_fmreg_str'; {$ENDIF} With songdata.instr_macros[instr].data[page].fm_data do begin fmreg_str := _hex[ATTCK_DEC_modulator SHR 4]+' '+ _hex[ATTCK_DEC_modulator AND $0f]+' '+ _hex[SUSTN_REL_modulator SHR 4]+' '+ _hex[SUSTN_REL_modulator AND $0f]+' '+ _hex[WAVEFORM_modulator AND 7]+' '+ byte2hex(KSL_VOLUM_modulator AND $3f)+' '+ _hex[KSL_VOLUM_modulator SHR 6]+' '+ _hex[AM_VIB_EG_modulator AND $0f]+' '; If (AM_VIB_EG_modulator SHR 7 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'T'; If (AM_VIB_EG_modulator SHR 6 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'V'; If (AM_VIB_EG_modulator SHR 4 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'K'; If (AM_VIB_EG_modulator SHR 5 AND 1 = 0) then fmreg_str := fmreg_str+#250' ' else fmreg_str := fmreg_str+'S '; fmreg_str := fmreg_str+ _hex[ATTCK_DEC_carrier SHR 4]+' '+ _hex[ATTCK_DEC_carrier AND $0f]+' '+ _hex[SUSTN_REL_carrier SHR 4]+' '+ _hex[SUSTN_REL_carrier AND $0f]+' '+ _hex[WAVEFORM_carrier AND 7]+' '+ byte2hex(KSL_VOLUM_carrier AND $3f)+' '+ _hex[KSL_VOLUM_carrier SHR 6]+' '+ _hex[AM_VIB_EG_carrier AND $0f]+' '; If (AM_VIB_EG_carrier SHR 7 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'T'; If (AM_VIB_EG_carrier SHR 6 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'V'; If (AM_VIB_EG_carrier SHR 4 AND 1 = 0) then fmreg_str := fmreg_str+#250 else fmreg_str := fmreg_str+'K'; If (AM_VIB_EG_carrier SHR 5 AND 1 = 0) then fmreg_str := fmreg_str+#250' ' else fmreg_str := fmreg_str+'S '; fmreg_str := fmreg_str+_hex[FEEDBACK_FM AND 1]+' '; fmreg_str := fmreg_str+_hex[FEEDBACK_FM SHR 1 AND 7]+' '; end; With songdata.instr_macros[instr].data[page] do begin If (freq_slide < 0) then fmreg_str := fmreg_str+'-'+ExpStrL(Num2str(Abs(freq_slide),16),3,'0')+' ' else fmreg_str := fmreg_str+'+'+ExpStrL(Num2str(Abs(freq_slide),16),3,'0')+' '; fmreg_str := fmreg_str+ _panning[panning]+' '+ byte2hex(duration); end; _fmreg_str := fmreg_str; end; function _dis_fmreg_col(fmreg_col: Byte): Boolean; var result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_dis_fmreg_col'; {$ENDIF} result := FALSE; Case fmreg_col of 1,2,3,4, 5: If songdata.dis_fmreg_col[instr][fmreg_col-1] then result := TRUE; 6, 7: If songdata.dis_fmreg_col[instr][5] then result := TRUE; 8,9,10,11,12,13, 14,15,16,17, 18: If songdata.dis_fmreg_col[instr][fmreg_col-2] then result := TRUE; 19, 20: If songdata.dis_fmreg_col[instr][17] then result := TRUE; 21,22,23,24, 25,26,27, 28: If songdata.dis_fmreg_col[instr][fmreg_col-3] then result := TRUE; 29,30,31, 32: If songdata.dis_fmreg_col[instr][26] then result := TRUE; 33: If songdata.dis_fmreg_col[instr][27] then result := TRUE; end; If (fmreg_col in [14..28]) and (songdata.instr_data[current_inst].perc_voice in [2..5]) then result := TRUE; _dis_fmreg_col := result; end; function _str1(def_chr: Char): String; const _on_off: array[BOOLEAN] of Char = (#205,#254); var temp: Byte; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_str1'; {$ENDIF} temp_str := ''; _on_off[FALSE] := def_chr; For temp := 0 to 4 do temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][temp]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][5]]+ _on_off[songdata.dis_fmreg_col[instr][5]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][6]]+ def_chr+ _on_off[songdata.dis_fmreg_col[instr][7]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][8]]+ _on_off[songdata.dis_fmreg_col[instr][9]]+ _on_off[songdata.dis_fmreg_col[instr][10]]+ _on_off[songdata.dis_fmreg_col[instr][11]]+def_chr; For temp := 12 to 16 do temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][temp]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][17]]+ _on_off[songdata.dis_fmreg_col[instr][17]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][18]]+def_chr+ _on_off[songdata.dis_fmreg_col[instr][19]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][20]]+ _on_off[songdata.dis_fmreg_col[instr][21]]+ _on_off[songdata.dis_fmreg_col[instr][22]]+ _on_off[songdata.dis_fmreg_col[instr][23]]+def_chr; For temp := 24 to 25 do temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][temp]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][26]]+ _on_off[songdata.dis_fmreg_col[instr][26]]+ _on_off[songdata.dis_fmreg_col[instr][26]]+ _on_off[songdata.dis_fmreg_col[instr][26]]+def_chr; temp_str := temp_str+ _on_off[songdata.dis_fmreg_col[instr][27]]; _str1 := temp_str; end; {$IFNDEF CPU64} function _str2(str: String; len: Byte): String; begin asm lea esi,[str] mov edi,@RESULT movzx ebx,len xor edx,edx push edi lodsb inc edi xor ecx,ecx mov ecx,ebx jecxz @@3 movzx ecx,al jecxz @@3 @@1: cmp edx,ebx jae @@3 lodsb stosb cmp al,'`' jz @@2 inc edx @@2: loop @@1 @@3: pop edi mov eax,esi lea esi,[str] sub eax,esi dec eax stosb end; end; {$ELSE} function _str2(str: String; len: Byte): String; var idx,len2: Byte; result: String; begin result := ''; len2 := 0; idx := 0; While (idx < Length(str)) and (len > len2) do begin Inc(idx); If (str[idx] <> '`') then Inc(len2); result := result+str[idx]; end; _str2 := result; end; {$ENDIF} procedure fmreg_page_refresh(xpos,ypos: Byte; page: Word); var attr,attr2: Byte; temps,fmreg_str2: String; fmreg_col,index, index2: Byte; dummy_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:fmreg_page_refresh'; {$ENDIF} attr := LO(fmreg_def_attr(page AND $0fff)); attr2 := HI(fmreg_def_attr(page AND $0fff)); fmreg_str := _fmreg_str(page AND $0fff); fmreg_str2 := fmreg_str; index := 0; index2 := 0; For fmreg_col := 1 to 35-1 do If _dis_fmreg_col(fmreg_col) then begin Insert('`',fmreg_str2,pos5[fmreg_col]+index); Insert('`',fmreg_str2,pos5[fmreg_col]+index+2); If (pos5[fmreg_col] < fmreg_left_margin) then Inc(index2,2); Inc(index,2); end; temps := Copy(fmreg_str2,fmreg_left_margin+index2, Length(fmreg_str2)-fmreg_left_margin-index2+1); dummy_str := macro_retrig_str[songdata.instr_macros[instr].data[page AND $0ff].fm_data. FEEDBACK_FM SHR 5]; If NOT arp_vib_mode then begin If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowC3Str(ptr_temp_screen,xpos,ypos, '~'+byte2hex(page)+'~ '#179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_area_inc_x)+'~', macro_background+macro_text, attr, macro_background+macro_text_dis) else ShowC3Str(ptr_temp_screen,xpos-1,ypos, ' ~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_area_inc_x)+'~ ', macro_current_bckg+macro_current, attr2, macro_current_bckg+macro_current_dis) else ShowStr(ptr_temp_screen,xpos,ypos,ExpStrL('',36,' '),attr); end else begin If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowC3Str(ptr_temp_screen,xpos,ypos, byte2hex(page)+' '#179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_area_inc_x)+'~', macro_background+macro_text_dis, macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowC3Str(ptr_temp_screen,xpos-1,ypos, ' '+ byte2hex(page AND NOT COMMON_FLAG)+' '#179'~'+dummy_str+'~'#246'~'+ _str2(temps,31+window_area_inc_x)+'~ ', macro_background+macro_text_dis, macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowStr(ptr_temp_screen,xpos,ypos,ExpStrL('',36,' '), macro_background+macro_text_dis); end; end; function arpeggio_def_attr(page: Byte): Word; var attr, attr2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:arpeggio_def_attr'; {$ENDIF} If (page <= songdata.macro_table[ptr_arpeggio_table]. arpeggio.length) then If (page >= songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin) and (page <= songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ PRED(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length)) and (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin > 0) and (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos) and (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; arpeggio_def_attr := attr+attr2 SHL 8; end; procedure arpeggio_page_refresh(xpos,ypos: Byte; page: Word); var attr,attr2: Byte; temps: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:arpeggio_page_refresh'; {$ENDIF} attr := LO(arpeggio_def_attr(page AND $0fff)); attr2 := HI(arpeggio_def_attr(page AND $0fff)); Case songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[page AND $0fff] of 0: temps := #250#250#250; 1..96: temps := '+'+ExpStrR(Num2str(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[page AND $0fff],10),2,' '); $80..$80+12*8+1: temps := note_layout[songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[page AND $0fff]-$80]; end; If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowCStr(ptr_temp_screen,xpos,ypos, '~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179' ~'+ temps+'~', macro_background+macro_text,attr) else ShowCStr(ptr_temp_screen,xpos-1,ypos, ' ~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179' ~'+ temps+'~ ', macro_current_bckg+macro_current,attr2) else ShowStr(ptr_temp_screen,xpos,ypos,ExpStrL('',9,' '),attr); end; function vibrato_def_attr(page: Byte): Word; var attr, attr2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:vibrato_def_attr'; {$ENDIF} If (page <= songdata.macro_table[ptr_vibrato_table]. vibrato.length) then If (page >= songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin) and (page <= songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ PRED(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length)) and (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin > 0) and (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length > 0) then begin attr := macro_background+macro_text_loop; attr2 := macro_current_bckg+macro_current_loop; end else If (page >= songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos) and (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > 0) then begin attr := macro_background+macro_text_keyoff; attr2 := macro_current_bckg+macro_current_koff; end else begin attr := macro_background+macro_text; attr2 := macro_current_bckg+macro_current; end else begin attr := macro_background+macro_text_dis; attr2 := macro_current_bckg+macro_current_dis; end; vibrato_def_attr := attr+attr2 SHL 8; end; procedure vibrato_page_refresh(xpos,ypos: Byte; page: Word); var attr,attr2: Byte; temps: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:vibrato_page_refresh'; {$ENDIF} attr := LO(vibrato_def_attr(page AND $0fff)); attr2 := HI(vibrato_def_attr(page AND $0fff)); If (songdata.macro_table[ptr_vibrato_table]. vibrato.data[page AND $0fff] = 0) then temps := #250#250#250 else If (songdata.macro_table[ptr_vibrato_table]. vibrato.data[page AND $0fff] < 0) then temps := '-'+byte2hex(Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[page AND $0fff])) else temps := '+'+byte2hex(Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[page AND $0fff])); If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowCStr(ptr_temp_screen,xpos,ypos, '~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179' ~'+ temps+'~', macro_background+macro_text,attr) else ShowCStr(ptr_temp_screen,xpos-1,ypos, ' ~'+byte2hex(page AND NOT COMMON_FLAG)+'~ '#179' ~'+ temps+'~ ', macro_current_bckg+macro_current,attr2) else ShowStr(ptr_temp_screen,xpos,ypos,ExpStrL('',9,' '),attr); end; procedure arpeggio_page_refresh_alt(xpos,ypos: Byte; page: Word); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:arpeggio_page_refresh_alt'; {$ENDIF} If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowCStr(ptr_temp_screen,xpos,ypos, byte2hex(page AND NOT COMMON_FLAG)+' '#179' ~'+ #250#250#250'~', macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowCStr(ptr_temp_screen,xpos-1,ypos, ' '+ byte2hex(page AND NOT COMMON_FLAG)+' '#179' ~'+ #250#250#250'~ ', macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowStr(ptr_temp_screen,xpos,ypos, ExpStrL('',9,' '), macro_background+macro_text_dis); end; procedure vibrato_page_refresh_alt(xpos,ypos: Byte; page: Word); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:vibrato_page_refresh_alt'; {$ENDIF} temps := #250#250#250; If (page <> EMPTY_FIELD) then If (page OR COMMON_FLAG <> page) then ShowCStr(ptr_temp_screen,xpos,ypos, byte2hex(page AND NOT COMMON_FLAG)+' '#179' ~'+ #250#250#250'~', macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowCStr(ptr_temp_screen,xpos-1,ypos, ' '+ byte2hex(page AND NOT COMMON_FLAG)+' '#179' ~'+ #250#250#250'~ ', macro_background+macro_text_dis, macro_background+macro_text_dis) else ShowStr(ptr_temp_screen,xpos,ypos, ExpStrL('',9,' '), macro_background+macro_text_dis); end; function _gfx_bar_str(value: Byte; neg: Boolean): String; var result: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_gfx_bar_str'; {$ENDIF} result := ''; If NOT neg then Repeat If (value > 15) then begin result := result+#219; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := result+CHR(127+value) until (value <= 15) else Repeat If (value > 15) then begin result := #219+result; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := CHR(158-value)+result; until (value <= 15); _gfx_bar_str := flipstr(result); end; function _fmreg_param(page,fmreg_hpos: Byte): Integer; var result: Integer; fmreg_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_fmreg_param'; {$ENDIF} fmreg_str := _fmreg_str(page); Case fmreg_hpos of {%n} 1,2,3,4,5,8,9,14,15,16,17, 18,21,22,27,28: result := Str2num(fmreg_str[pos5[fmreg_hpos]],16); {%nn} 6,7: result := Str2num(Copy(fmreg_str,pos5[6],2),16); 19,20: result := Str2num(Copy(fmreg_str,pos5[19],2),16); 34,35: result := Str2num(Copy(fmreg_str,pos5[34],2),16); {sw} 10,11,12,13,23,24, 25,26: If (fmreg_str[pos5[fmreg_hpos]] = #251) then result := 1 else result := 0; {fsl} 29,30,31,32: begin result := Str2num(Copy(fmreg_str,pos5[30],3),16); If (fmreg_str[pos5[29]] = '-') then result := -result; end; {pan} 33: Case SYSTEM.Pos(fmreg_str[pos5[33]],_panning) of 1: result := 0; 2: result := -1; 3: result := 1; end; end; _fmreg_param := result; end; const flag_FMREG = 1; flag_ARPEGGiO = 2; flag_VIBRATO = 4; procedure refresh(refresh_flag: Byte); var nm_slots: Byte; temp,max_value: Integer; d_factor: Real; temp_str: String; _add_prev_size, _sub_prev_xpos_a, _sub_prev_xpos_v: Integer; _axis_attr: Byte; _4op_pos_shift, _4op_ins1,_4op_ins2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:refresh'; {$ENDIF} For temp := 1 to 20 do If (pos = temp) then attr[temp] := macro_background+macro_hi_text else If (temp in [1..7]) and arp_vib_mode then attr[temp] := macro_background+macro_text_dis else If (temp in [8..13]) and (ptr_arpeggio_table = 0) then attr[temp] := macro_background+macro_text_dis else If (temp in [14..20]) and (ptr_vibrato_table = 0) then attr[temp] := macro_background+macro_text_dis else attr[temp] := macro_background+macro_text; If (ptr_arpeggio_table <> 0) then begin attr2[1] := macro_input_bckg+macro_input; attr2[3] := macro_background+macro_topic; end else begin attr2[1] := macro_background+macro_text_dis; attr2[3] := macro_background+macro_text_dis; end; If (ptr_vibrato_table <> 0) then begin attr2[2] := macro_input_bckg+macro_input; attr2[4] := macro_background+macro_topic; end else begin attr2[2] := macro_background+macro_text_dis; attr2[4] := macro_background+macro_text_dis; end; If NOT arp_vib_mode then attr2[5] := macro_input_bckg+macro_input else attr2[5] := macro_background+macro_text_dis; If (pos = 7) then frame_type[1] := frame_double else frame_type[1] := frame_single; If (pos = 13) then frame_type[2] := frame_double else frame_type[2] := frame_single; If (pos = 20) then frame_type[3] := frame_double else frame_type[3] := frame_single; If NOT arp_vib_mode then begin ShowStr(ptr_temp_screen,xstart+2,ystart+1,'FM-REGiSTER', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+2,ystart+2,'DEFiNiTiON MACRO-TABLE', macro_background+macro_topic); end else begin ShowStr(ptr_temp_screen,xstart+2,ystart+1,'FM-REGiSTER', macro_background+macro_text_dis); ShowStr(ptr_temp_screen,xstart+2,ystart+2,'DEFiNiTiON MACRO-TABLE', macro_background+macro_text_dis); end; ShowStr(ptr_temp_screen,xstart+2,ystart+3, ExpStrL('',78+window_area_inc_x,#205), macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+2,ystart+10, ExpStrL('',78+window_area_inc_x,#205), macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+2,ystart+22+window_area_inc_y, ExpStrL('',78+window_area_inc_x,#205), macro_background+macro_text); If NOT arp_vib_mode then begin ShowCStr(ptr_temp_screen,xstart+2,ystart+4, 'LENGTH ~'+ byte2hex(songdata.instr_macros[instr].length)+' ~', attr[1],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+5, 'LOOP BEGiN ~'+ byte2hex(songdata.instr_macros[instr].loop_begin)+' ~', attr[2],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+6, 'LOOP LENGTH ~'+ byte2hex(songdata.instr_macros[instr].loop_length)+' ~', attr[3],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+7, 'KEY-OFF ~'+ byte2hex(songdata.instr_macros[instr].keyoff_pos)+' ~', attr[4],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+8, 'ARPEGGiO TABLE ~'+ byte2hex(ptr_arpeggio_table)+' ~', attr[5],attr2[5]); ShowCStr(ptr_temp_screen,xstart+2,ystart+9, 'ViBRATO TABLE ~'+ byte2hex(ptr_vibrato_table)+' ~', attr[6],attr2[5]); _add_prev_size := window_area_inc_x DIV 2; _sub_prev_xpos_a := 0; _sub_prev_xpos_v := 0; end else begin _add_prev_size := 0; _sub_prev_xpos_a := 20; _sub_prev_xpos_v := -3; end; ShowStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+2,'ARPEGGiO ('+ byte2hex(ptr_arpeggio_table)+')', attr2[3]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+4, 'LENGTH ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length)+' ~', attr[8],attr2[1]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+5, 'SPEED ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed)+' ~', attr[9],attr2[1]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+6, 'LOOP BEGiN ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin)+' ~', attr[10],attr2[1]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+7, 'LOOP LENGTH ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length)+' ~', attr[11],attr2[1]); ShowCStr(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+8, 'KEY-OFF ~'+ byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos)+' ~', attr[12],attr2[1]); ShowStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+2,'ViBRATO ('+ byte2hex(ptr_vibrato_table)+')', attr2[4]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+4, 'LENGTH ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.length)+' ~', attr[14],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+5, 'SPEED ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.speed)+' ~', attr[15],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+6, 'DELAY ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.delay)+' ~', attr[16],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+7, 'LOOP BEGiN ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin)+' ~', attr[17],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+8, 'LOOP LENGTH ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length)+' ~', attr[18],attr2[2]); ShowCStr(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+9, 'KEY-OFF ~'+ byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos)+' ~', attr[19],attr2[2]); fr_setting.update_area := FALSE; fr_setting.shadow_enabled := FALSE; If (refresh_flag AND flag_FMREG = flag_FMREG) then Frame(ptr_temp_screen,xstart+2,ystart+11, xstart+42+_add_prev_size*2,ystart+21+window_area_inc_y, attr[7],'', macro_background+macro_text,frame_type[1]); If (refresh_flag AND flag_ARPEGGIO = flag_ARPEGGIO) then Frame(ptr_temp_screen,xstart+48+window_area_inc_x,ystart+11, xstart+59+_add_prev_size*2,ystart+21+window_area_inc_y, attr[13],'', macro_background+macro_text,frame_type[2]); If (refresh_flag AND flag_VIBRATO = flag_VIBRATO) then Frame(ptr_temp_screen,xstart+65+window_area_inc_x,ystart+11, xstart+76+_add_prev_size*2,ystart+21+window_area_inc_y, attr[20],'', macro_background+macro_text,frame_type[3]); fr_setting.update_area := TRUE; fr_setting.shadow_enabled := TRUE; show_queue(xstart+4,ystart+11,9+window_area_inc_y,fmreg_page,255,1); If (refresh_flag AND flag_FMREG = flag_FMREG) then If NOT arp_vib_mode then begin If (window_area_inc_x <> 26) then HScrollBar(ptr_temp_screen,xstart+29+_add_prev_size*2,ystart+21+window_area_inc_y, 13,35,fmreg_hpos,WORD_NULL, macro_scrbar_bckg+macro_scrbar_text, macro_scrbar_bckg+macro_scrbar_mark); VScrollBar(ptr_temp_screen,xstart+43+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,fmreg_page,WORD_NULL, macro_scrbar_bckg+macro_scrbar_text, macro_scrbar_bckg+macro_scrbar_mark); end else begin HScrollBar(ptr_temp_screen,xstart+29+_add_prev_size*2,ystart+21+window_area_inc_y, 13,35,fmreg_hpos,WORD_NULL, macro_background+macro_text_dis, macro_background+macro_text_dis); VScrollBar(ptr_temp_screen,xstart+43+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,fmreg_page,WORD_NULL, macro_background+macro_text_dis, macro_background+macro_text_dis); end; If (pos = 7) then ShowStr(ptr_temp_screen,xstart+2+8,ystart+11, Copy(_str1(#205),fmreg_left_margin,31), attr[7]) else ShowStr(ptr_temp_screen,xstart+2+8,ystart+11, Copy(_str1(#196),fmreg_left_margin,31), attr[7]); If (refresh_flag AND flag_ARPEGGIO = flag_ARPEGGIO) then If (ptr_arpeggio_table <> 0) then begin show_queue(xstart+50+_add_prev_size*2,ystart+11,9+window_area_inc_y,arpeggio_page,255,2); VScrollBar(ptr_temp_screen,xstart+60+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,arpeggio_page,WORD_NULL, macro_scrbar_bckg+macro_scrbar_text, macro_scrbar_bckg+macro_scrbar_mark) end else begin show_queue(xstart+50+_add_prev_size*2,ystart+11,9+window_area_inc_y,1,255,3); VScrollBar(ptr_temp_screen,xstart+60+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,1,WORD_NULL, macro_background+macro_text_dis, macro_background+macro_text_dis); end; If (refresh_flag AND flag_VIBRATO = flag_VIBRATO) then If (ptr_vibrato_table <> 0) then begin show_queue(xstart+67+_add_prev_size*2,ystart+11,9+window_area_inc_y,vibrato_page,255,4); VScrollBar(ptr_temp_screen,xstart+77+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,vibrato_page,WORD_NULL, macro_scrbar_bckg+macro_scrbar_text, macro_scrbar_bckg+macro_scrbar_mark); end else begin show_queue(xstart+67+_add_prev_size*2,ystart+11,9+window_area_inc_y,1,255,5); VScrollBar(ptr_temp_screen,xstart+77+_add_prev_size*2,ystart+12, 9+window_area_inc_y,255,1,WORD_NULL, macro_background+macro_text_dis, macro_background+macro_text_dis); end; If (pos <> 7) then ShowStr(ptr_temp_screen,xstart+2,ystart+23+window_area_inc_y, ExpStrR(macro_table_hint_str[pos],77,' '), macro_background+macro_hint) else ShowStr(ptr_temp_screen,xstart+2,ystart+23+window_area_inc_y, ExpStrR(macro_table_hint_str[20+fmreg_hpos],77,' '), macro_background+macro_hint); If (pos in [1..7]) then begin ShowStr(ptr_temp_screen,xstart+32+_add_prev_size,ystart+3, #253, macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+32+_add_prev_size,ystart+10, #252, macro_background+macro_text); If NOT (fmreg_hpos in [29..33]) then begin ShowVStr(ptr_temp_screen,xstart+22,ystart+4, #179#179#179#179#179#158, macro_background+macro_text); ShowVStr(ptr_temp_screen,xstart+42+window_area_inc_x,ystart+4, #179#179#179#179#179#158, macro_background+macro_text); end else begin ShowVStr(ptr_temp_screen,xstart+22,ystart+4, #179#179#158#179#179#179, macro_background+macro_text); ShowVStr(ptr_temp_screen,xstart+42+window_area_inc_x,ystart+4, #179#179#158#179#179#179, macro_background+macro_text); end; max_value := 0; For temp := 1 to 255 do If (Abs(_fmreg_param(temp,fmreg_hpos)) > max_value) then max_value := Abs(_fmreg_param(temp,fmreg_hpos)); If NOT (fmreg_hpos in [29..33]) then begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+4, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+5, '+', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+8, ' ', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+9, ExpStrR('',3,' '), macro_background+macro_topic); end else begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+4, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+5, '+', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+8, '-', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1,ystart+9, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); end; If NOT (fmreg_hpos in [29..33]) then d_factor := 90/min(max_value,1) else d_factor := 45/min(max_value,1); If NOT (fmreg_hpos in [29..33]) then For temp := -9-_add_prev_size to 9+_add_prev_size do If (fmreg_page+temp >= 1) and (fmreg_page+temp <= 255) then If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL(_gfx_bar_str(Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor),FALSE),6,' '), LO(fmreg_def_attr(fmreg_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL(_gfx_bar_str(Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor),FALSE),6,' '), macro_background+macro_text_dis) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL('',6,' '), macro_background+macro_text) else For temp := -9-_add_prev_size to 9+_add_prev_size do If (fmreg_page+temp >= 1) and (fmreg_page+temp <= 255) then If (Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor) >= 0) then If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrR(ExpStrL(_gfx_bar_str(Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor),FALSE),3,' '),6,' '), LO(fmreg_def_attr(fmreg_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrR(ExpStrL(_gfx_bar_str(Round(_fmreg_param(fmreg_page+temp,fmreg_hpos)*d_factor),FALSE),3,' '),6,' '), macro_background+macro_text_dis) else If NOT _dis_fmreg_col(fmreg_hpos) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(_fmreg_param(fmreg_page+temp,fmreg_hpos))*d_factor),TRUE),3,' '),6,' '), LO(fmreg_def_attr(fmreg_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(_fmreg_param(fmreg_page+temp,fmreg_hpos))*d_factor),TRUE),3,' '),6,' '), macro_background+macro_text_dis) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size,ystart+4, ExpStrR('',6,' '), macro_background+macro_text); end; If (pos in [8..13]) or arp_vib_mode then begin If NOT (pos in [8..13]) then _axis_attr := macro_background+macro_topic else begin ShowStr(ptr_temp_screen,xstart+32+_add_prev_size-_sub_prev_xpos_a,ystart+3, #253, macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+32+_add_prev_size-_sub_prev_xpos_a,ystart+10, #252, macro_background+macro_text); end; If (pos in [8..13]) then If arp_vib_mode then _axis_attr := macro_background+macro_hi_text else _axis_attr := macro_background+macro_text else _axis_attr := macro_background+macro_text; ShowVStr(ptr_temp_screen,xstart+22-_sub_prev_xpos_a,ystart+4, #179#179#179#179#179#158, _axis_attr); ShowVStr(ptr_temp_screen,xstart+42+window_area_inc_x-_sub_prev_xpos_a,ystart+4, #179#179#179#179#179#158, _axis_attr); max_value := 0; For temp := 1 to 255 do If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] > max_value) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] < $80) then max_value := Abs(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp]); If NOT arp_vib_mode then begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+4, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+5, '+ ', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+8, ' ', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+9, ExpStrR('',3,' '), macro_background+macro_topic); end else If (pos in [8..13]) then begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+4, ExpStrR(Num2Str(max_value,10),3,' '), macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+5, '+ ', macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+8, ' ', macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_a,ystart+9, ExpStrR('',3,' '), macro_background+macro_hi_text); end; d_factor := 90/min(max_value,1); For temp := -9-_add_prev_size to 9+_add_prev_size do If (arpeggio_page+temp >= 1) and (arpeggio_page+temp <= 255) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page+temp] < $80) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_a,ystart+4, ExpStrL(_gfx_bar_str(Round(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page+temp]*d_factor),FALSE),6,' '), LO(arpeggio_def_attr(arpeggio_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_a,ystart+4, ExpStrL(FilterStr(note_layout[songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page+temp]-$80],'-',#241),6,' '), LO(arpeggio_def_attr(arpeggio_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_a,ystart+4, ExpStrL('',6,' '), macro_background+macro_text); end; If (pos in [14..20]) or arp_vib_mode then begin If NOT (pos in [14..20]) then _axis_attr := macro_background+macro_text else begin ShowStr(ptr_temp_screen,xstart+32+_add_prev_size-_sub_prev_xpos_v,ystart+3, #253, macro_background+macro_text); ShowStr(ptr_temp_screen,xstart+32+_add_prev_size-_sub_prev_xpos_v,ystart+10, #252, macro_background+macro_text); end; If (pos in [14..20]) then If arp_vib_mode then _axis_attr := macro_background+macro_hi_text else _axis_attr := macro_background+macro_text else _axis_attr := macro_background+macro_text; ShowVStr(ptr_temp_screen,xstart+22-_sub_prev_xpos_v,ystart+4, #179#179#158#179#179#179, _axis_attr); ShowVStr(ptr_temp_screen,xstart+42+window_area_inc_x-_sub_prev_xpos_v,ystart+4, #179#179#158#179#179#179, _axis_attr); max_value := 0; For temp := 1 to 255 do If (Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp]) > max_value) then max_value := Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp]); If NOT arp_vib_mode then begin ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_v,ystart+4, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_v,ystart+5, '+', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_v,ystart+8, '-', macro_background+macro_topic); ShowStr(ptr_temp_screen,xstart+42+window_area_inc_x+1-_sub_prev_xpos_v,ystart+9, ExpStrR(ExpStrL(Num2Str(max_value,16),2,'0'),3,' '), macro_background+macro_topic); end else If (pos in [14..20]) then begin ShowStr(ptr_temp_screen,xstart+20-_sub_prev_xpos_v,ystart+4, ExpStrL(ExpStrL(Num2Str(max_value,16),2,'0'),2,' '), macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+20-_sub_prev_xpos_v,ystart+5, ' +', macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+20-_sub_prev_xpos_v,ystart+8, ' -', macro_background+macro_hi_text); ShowStr(ptr_temp_screen,xstart+20-_sub_prev_xpos_v,ystart+9, ExpStrL(ExpStrL(Num2Str(max_value,16),2,'0'),2,' '), macro_background+macro_hi_text); end; d_factor := 45/min(max_value,1); For temp := -9-_add_prev_size to 9+_add_prev_size do If (vibrato_page+temp >= 1) and (vibrato_page+temp <= 255) then If (Round(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page+temp]*d_factor) >= 0) then ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_v,ystart+4, ExpStrR(ExpStrL(_gfx_bar_str(Round(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page+temp]*d_factor),FALSE),3,' '),6,' '), LO(vibrato_def_attr(vibrato_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_v,ystart+4, ExpStrL(ExpStrR(_gfx_bar_str(Round(Abs(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page+temp])*d_factor),TRUE),3,' '),6,' '), LO(vibrato_def_attr(vibrato_page+temp))) else ShowVStr(ptr_temp_screen,xstart+32+temp+_add_prev_size-_sub_prev_xpos_v,ystart+4, ExpStrR('',6,' '), macro_background+macro_text); end; If NOT (get_4op_to_test <> 0) then _4op_pos_shift := 0 else _4op_pos_shift := 6; If (get_4op_to_test <> 0) then begin _4op_ins1 := HI(get_4op_to_test); _4op_ins2 := LO(get_4op_to_test); If (_4op_ins1 = _4op_ins2) then ShowC3Str(ptr_temp_screen,xstart+01,ystart+24+window_area_inc_y, ' `[`'#244+byte2hex(_4op_ins1)+ ','#245+byte2hex(_4op_ins1)+' '+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[10] AND 1]+'/'+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[10] AND 1]+ '`]` ', macro_background+macro_hi_text, macro_hi_text SHL 4, macro_background+macro_border) else If (current_inst = _4op_ins1) then ShowC3Str(ptr_temp_screen,xstart+01,ystart+24+window_area_inc_y, ' `[`~'#244+byte2hex(_4op_ins1)+ '~,'#245+byte2hex(_4op_ins2)+' ~'+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[10] AND 1]+'~/'+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[10] AND 1]+ '`]` ', macro_background+macro_hi_text, macro_hi_text SHL 4, macro_background+macro_border) else ShowC3Str(ptr_temp_screen,xstart+01,ystart+24+window_area_inc_y, ' `[`'#244+byte2hex(_4op_ins1)+ ',~'#245+byte2hex(_4op_ins2)+'~ '+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins1])^)[10] AND 1]+'/~'+ connection_str[pBYTE(@Addr(songdata.instr_data[_4op_ins2])^)[10] AND 1]+ '~`]` ', macro_background+macro_hi_text, macro_hi_text SHL 4, macro_background+macro_border); end else ShowCStr(ptr_temp_screen, xstart+01,ystart+24+window_area_inc_y, ' [~'+perc_voice_str[songdata.instr_data[current_inst].perc_voice]+'~] ', macro_background+macro_border, macro_background+macro_hi_text); If (songdata.instr_macros[current_inst].length <> 0) then temp_str := ' [~MACRO:FM' else temp_str := ' '; If NOT arp_vib_mode then begin If (ptr_arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'[~MACRO:ARP'; If (ptr_vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'[~MACRO:ViB'; end; If (temp_str <> ' ') then temp_str := temp_str+'~] '; ShowCStr(ptr_temp_screen,xstart+11+_4op_pos_shift,ystart+24+window_area_inc_y,ExpStrR(temp_str,21+2,#205), macro_background+macro_border, macro_background+macro_hi_text); If (songdata.instr_data[instr].perc_voice in [2..5]) then begin temp_str := '```` '; nm_slots := 1; end else If NOT (get_4op_to_test <> 0) then begin temp_str := ' `[`12`]` '; nm_slots := 2; end else begin temp_str := ' `[`1234`]` '; nm_slots := 4; end; temp_str := temp_str+'[~SPEED:'+Num2str(songdata.tempo*songdata.macro_speedup,10)+#174+'~] '; ShowC3Str(ptr_temp_screen,xstart+window_area_inc_x+59,ystart+24+window_area_inc_y, ExpStrL(temp_str,28,#205), macro_background+macro_border, macro_background+macro_context, macro_background+macro_context_dis); If (nm_slots > 1) then For temp := 1 to nm_slots do If (NOT _operator_enabled[temp]) then ShowStr(ptr_temp_screen,xstart+window_area_inc_x+83-C3StrLen(temp_str)-1+temp,ystart+24+window_area_inc_y, #250, instrument_bckg+instrument_border); _preview_indic_proc(0); move2screen_alt; end; function hex(chr: Char): Byte; begin hex := PRED(SYSTEM.Pos(UpCase(chr),_hex)); end; procedure copy_object; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:copy_object'; {$ENDIF} Case clipboard.object_type of objMacroTableLine: Case clipboard.mcrtab_type of mttFM_reg_table: clipboard.fmreg_table.data[1] := songdata.instr_macros[instr].data[fmreg_page]; mttArpeggio_table: clipboard.macro_table.arpeggio.data[1] := songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]; mttVibrato_table: clipboard.macro_table.vibrato.data[1] := songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page]; end; objMacroTableColumn: Case clipboard.mcrtab_type of mttFM_reg_table: begin clipboard.fmtab_def_typ := fmreg_hpos; For temp := 1 to 255 do clipboard.fmreg_table.data[temp] := songdata.instr_macros[instr].data[temp]; end; mttArpeggio_table: clipboard.macro_table.arpeggio := songdata.macro_table[ptr_arpeggio_table].arpeggio; mttVibrato_table: clipboard.macro_table.vibrato := songdata.macro_table[ptr_vibrato_table].vibrato; end; objMacroTable: Case clipboard.mcrtab_type of mttFM_reg_table: clipboard.fmreg_table := songdata.instr_macros[instr]; mttArpeggio_table: clipboard.macro_table.arpeggio := songdata.macro_table[ptr_arpeggio_table].arpeggio; mttVibrato_table: clipboard.macro_table.vibrato := songdata.macro_table[ptr_vibrato_table].vibrato; end; end; end; procedure paste_object; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:paste_object'; {$ENDIF} Case clipboard.object_type of objMacroTableLine: Case clipboard.mcrtab_type of mttFM_reg_table: If (pos = 7) then begin temp := songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM; songdata.instr_macros[instr].data[fmreg_page] := clipboard.fmreg_table.data[1]; songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM := temp AND $0c0+ songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM; end; mttArpeggio_table: If (pos = 13) then songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := clipboard.macro_table.arpeggio.data[1]; mttVibrato_table: If (pos = 20) then songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page] := clipboard.macro_table.vibrato.data[1]; end; objMacroTableColumn: Case clipboard.mcrtab_type of mttFM_reg_table: For temp := 1 to 255 do With songdata.instr_macros[instr].data[temp] do Case clipboard.fmtab_def_typ of 1: fm_data.ATTCK_DEC_modulator := clipboard.fmreg_table.data[temp].fm_data.ATTCK_DEC_modulator AND $0f0+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.ATTCK_DEC_modulator AND $0f; 3: fm_data.SUSTN_REL_modulator := clipboard.fmreg_table.data[temp].fm_data.SUSTN_REL_modulator AND $0f0+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.SUSTN_REL_modulator AND $0f; 5: fm_data.WAVEFORM_modulator := clipboard.fmreg_table.data[temp].fm_data.WAVEFORM_modulator; 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0+ clipboard.fmreg_table.data[temp].fm_data.KSL_VOLUM_modulator AND $3f; 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ clipboard.fmreg_table.data[temp].fm_data.KSL_VOLUM_modulator AND $0c0; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $0f; 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $80; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $40; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $10; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_modulator AND $20; 14: fm_data.ATTCK_DEC_carrier := clipboard.fmreg_table.data[temp].fm_data.ATTCK_DEC_carrier AND $0f0+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.ATTCK_DEC_carrier AND $0f; 16: fm_data.SUSTN_REL_carrier := clipboard.fmreg_table.data[temp].fm_data.SUSTN_REL_carrier AND $0f0+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.SUSTN_REL_carrier AND $0f; 18: fm_data.WAVEFORM_carrier := clipboard.fmreg_table.data[temp].fm_data.WAVEFORM_carrier; 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0+ clipboard.fmreg_table.data[temp].fm_data.KSL_VOLUM_carrier AND $3f; 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ clipboard.fmreg_table.data[temp].fm_data.KSL_VOLUM_carrier AND $0c0; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $0f; 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $80; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $40; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $10; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df+ clipboard.fmreg_table.data[temp].fm_data.AM_VIB_EG_carrier AND $20; 27: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0fe+ clipboard.fmreg_table.data[temp].fm_data.FEEDBACK_FM AND 1; 28: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0c1+ clipboard.fmreg_table.data[temp].fm_data.FEEDBACK_FM AND $03e; 29,30,31, 32: freq_slide := clipboard.fmreg_table.data[temp].freq_slide; 33: panning := clipboard.fmreg_table.data[temp].panning; 34, 35: duration := clipboard.fmreg_table.data[temp].duration; end; mttArpeggio_table: If (pos in [8..13]) then For temp := 1 to 255 do songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] := clipboard.macro_table.arpeggio.data[temp]; mttVibrato_table: If (pos in [14..20]) then For temp := 1 to 255 do songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp] := clipboard.macro_table.vibrato.data[temp]; end; objMacroTable: Case clipboard.mcrtab_type of mttFM_reg_table: If (pos in [1..7]) then songdata.instr_macros[instr] := clipboard.fmreg_table; mttArpeggio_table: If (pos in [8..13]) then songdata.macro_table[ptr_arpeggio_table].arpeggio := clipboard.macro_table.arpeggio; mttVibrato_table: If (pos in [14..20]) then songdata.macro_table[ptr_vibrato_table].vibrato := clipboard.macro_table.vibrato; end; end; end; procedure _scroll_cur_left; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_scroll_cur_left'; {$ENDIF} Repeat If (fmreg_cursor_pos > 1) then Dec(fmreg_cursor_pos) else Dec(fmreg_left_margin); until (fmreg_str[PRED(fmreg_left_margin+fmreg_cursor_pos-1)] = ' ') or (fmreg_left_margin+fmreg_cursor_pos-1 = 1); fmreg_cursor_pos := pos5[fmreg_hpos]-fmreg_left_margin+1; end; procedure _scroll_cur_right; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR:_scroll_cur_right'; {$ENDIF} Repeat If (fmreg_cursor_pos < max(57,31+window_area_inc_x)) then Inc(fmreg_cursor_pos) else Inc(fmreg_left_margin); until (fmreg_str[SUCC(fmreg_left_margin+fmreg_cursor_pos-1)] = ' ') or (fmreg_left_margin+fmreg_cursor_pos-1 = 57); fmreg_cursor_pos := pos5[fmreg_hpos]-fmreg_left_margin+1; end; function _inc(value,limit: Integer): Integer; begin If (value < limit) then Inc(value); _inc := value; end; function _dec(value,limit: Integer): Integer; begin If (value > limit) then Dec(value); _dec := value; end; procedure _set_operator_flag(operator: Byte; toggle: Boolean); var _temp_operator_enabled: array[1..4] of Boolean; begin If (songdata.instr_data[instr].perc_voice in [2..5]) or (NOT (get_4op_to_test <> 0) and NOT (operator in [1..2])) or (NOT (operator in [1..4])) then EXIT; If NOT toggle then begin FillChar(_operator_enabled,SizeOf(_operator_enabled),FALSE); _operator_enabled[operator] := TRUE; EXIT; end; Move(_operator_enabled,_temp_operator_enabled,SizeOf(_temp_operator_enabled)); If NOT (get_4op_to_test <> 0) and (operator in [1,2]) then begin _temp_operator_enabled[operator] := NOT _temp_operator_enabled[operator]; If NOT ((_temp_operator_enabled[1] = FALSE) and (_temp_operator_enabled[2] = FALSE)) then Move(_temp_operator_enabled,_operator_enabled,SizeOf(_operator_enabled)); end else If (get_4op_to_test <> 0) and (operator in [1,2,3,4]) then begin _temp_operator_enabled[operator] := NOT _temp_operator_enabled[operator]; If NOT ((_temp_operator_enabled[1] = FALSE) and (_temp_operator_enabled[2] = FALSE) and (_temp_operator_enabled[3] = FALSE) and (_temp_operator_enabled[4] = FALSE)) then Move(_temp_operator_enabled,_operator_enabled,SizeOf(_operator_enabled)); end; end; function _check_macro_speed_change: Boolean; begin _check_macro_speed_change := FALSE; Case is_environment.keystroke of kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If (current_inst > 1) then begin Dec(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); STATUS_LINE_refresh; keyboard_reset_buffer; _check_macro_speed_change := TRUE; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If (current_inst < 255) then begin Inc(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); STATUS_LINE_refresh; keyboard_reset_buffer; _check_macro_speed_change := TRUE; end; end; If (is_environment.keystroke = kAlt0) or (is_environment.keystroke = kAlt1) or (is_environment.keystroke = kAlt2) or (is_environment.keystroke = kAlt3) or (is_environment.keystroke = kAlt4) then begin _check_macro_speed_change := TRUE; Case is_environment.keystroke of kAlt0: FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); kAlt1: If shift_pressed then _set_operator_flag(1,TRUE) else _set_operator_flag(1,FALSE); kAlt2: If shift_pressed then _set_operator_flag(2,TRUE) else _set_operator_flag(2,FALSE); kAlt3: If shift_pressed then _set_operator_flag(3,TRUE) else _set_operator_flag(3,FALSE); kAlt4: If shift_pressed then _set_operator_flag(4,TRUE) else _set_operator_flag(4,FALSE); end; end; end; procedure _check_fmreg_general_keys; begin Case is_environment.keystroke of kCtHOME: If NOT shift_pressed then If (songdata.instr_macros[instr].length > 0) then Dec(songdata.instr_macros[instr].length) else else If (songdata.instr_macros[instr].loop_begin > 0) then begin Dec(songdata.instr_macros[instr].loop_begin); While NOT ((songdata.instr_macros[instr]. keyoff_pos > songdata.instr_macros[instr]. loop_begin+ min0(songdata.instr_macros[instr]. loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); end; kCtEND: If NOT shift_pressed then If (songdata.instr_macros[instr].length < 255) then Inc(songdata.instr_macros[instr].length) else else If (songdata.instr_macros[instr].loop_begin < 255) then begin Inc(songdata.instr_macros[instr].loop_begin); While NOT ((songdata.instr_macros[instr]. keyoff_pos > songdata.instr_macros[instr]. loop_begin+ min0(songdata.instr_macros[instr]. loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); end; kCtPgUP: If NOT shift_pressed then else If (songdata.instr_macros[instr].loop_length > 0) then begin Dec(songdata.instr_macros[instr].loop_length); While NOT ((songdata.instr_macros[instr]. keyoff_pos > songdata.instr_macros[instr]. loop_begin+ min0(songdata.instr_macros[instr]. loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); end; kCtPgDN: If NOT shift_pressed then else If (songdata.instr_macros[instr].loop_length < 255) then begin Inc(songdata.instr_macros[instr].loop_length); While NOT ((songdata.instr_macros[instr]. keyoff_pos > songdata.instr_macros[instr]. loop_begin+ min0(songdata.instr_macros[instr]. loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); end; end; end; procedure _check_arp_general_keys; begin Case is_environment.keystroke of kCtHOME: If NOT shift_pressed then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.length > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin > 0) then begin Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin); While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; kCtEND: If NOT shift_pressed then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.length < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin < 255) then begin Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin); While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; kCtPgUP: If NOT shift_pressed then If (ptr_arpeggio_table > 1) then Dec(ptr_arpeggio_table) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length > 0) then begin Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length); While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; kCtPgDN: If NOT shift_pressed then If (ptr_arpeggio_table < 255) then Inc(ptr_arpeggio_table) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length < 255) then begin Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length); While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; end; end; procedure _check_vib_general_keys; begin Case is_environment.keystroke of kCtHOME: If NOT shift_pressed then If (songdata.macro_table[ptr_vibrato_table]. vibrato.length > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.length) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin > 0) then begin Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin); While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; kCtEND: If NOT shift_pressed then If (songdata.macro_table[ptr_vibrato_table]. vibrato.length < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.length) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin < 255) then begin Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin); While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; kCtPgUP: If NOT shift_pressed then If (ptr_vibrato_table > 1) then Dec(ptr_vibrato_table) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length > 0) then begin Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length); While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; kCtPgDN: If NOT shift_pressed then If (ptr_vibrato_table < 255) then Inc(ptr_vibrato_table) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length < 255) then begin Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length); While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; end; end; label _jmp1,_jmp2,_end2; begin { MACRO_EDITOR } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_EDITOR'; {$ENDIF} _arp_vib_mode := arp_vib_mode; If is_default_screen_mode then begin window_area_inc_x := 0; window_area_inc_y := 0; end else begin {$IFDEF GO32V2} If arp_vib_mode then window_area_inc_x := 0 else If (MaxCol > 81+26+4) then window_area_inc_x := 26 else window_area_inc_x := 10; If (MaxLn > 24+20+3) then window_area_inc_y := 20 else window_area_inc_y := 10; {$ELSE} If arp_vib_mode then window_area_inc_x := 0 else window_area_inc_x := 26; If (program_screen_mode = 1) then window_area_inc_y := 10 else window_area_inc_y := 20; {$ENDIF} end; call_pickup_proc := FALSE; _source_ins := instrum_page; call_pickup_proc2 := FALSE; _source_ins2 := instrum_page; _jmp1: If NOT arp_vib_mode then begin ptr_arpeggio_table := songdata.instr_macros[instr].arpeggio_table; ptr_vibrato_table := songdata.instr_macros[instr].vibrato_table; end else begin ptr_arpeggio_table := arpvib_arpeggio_table; ptr_vibrato_table := arpvib_vibrato_table; end; pos := _macro_editor__pos[arp_vib_mode]; If arp_vib_mode and (pos < 8) then pos := 8 else If NOT arp_vib_mode and (((ptr_arpeggio_table = 0) and (pos in [8..13])) or ((ptr_vibrato_table = 0) and (pos in [14..20]))) then pos := 1; fmreg_hpos := _macro_editor__fmreg_hpos[arp_vib_mode]; fmreg_page := _macro_editor__fmreg_page[arp_vib_mode]; fmreg_left_margin := _macro_editor__fmreg_left_margin[arp_vib_mode]; fmreg_cursor_pos := _macro_editor__fmreg_cursor_pos[arp_vib_mode]; arpeggio_page := _macro_editor__arpeggio_page[arp_vib_mode]; vibrato_hpos := _macro_editor__vibrato_hpos[arp_vib_mode]; vibrato_page := _macro_editor__vibrato_page[arp_vib_mode]; If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; songdata.instr_names[temp][1] := ' '; end; songdata_crc := Update32(songdata,SizeOf(songdata),0); For temp := 1 to 255 do songdata.instr_names[temp][1] := temp_marks[temp]; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; If NOT arp_vib_mode then centered_frame(xstart,ystart,81+window_area_inc_x,24+window_area_inc_y, ' iNSTRUMENT MACRO EDiTOR (iNS_ ) ', macro_background+dialog_border, macro_background+dialog_title, frame_double) else centered_frame(xstart,ystart,81+window_area_inc_x,24+window_area_inc_y, ' ARPEGGiO/ViBRATO MACRO EDiTOR (iNS_ ) ', macro_background+dialog_border, macro_background+dialog_title, frame_double); _pip_xloc := xstart+30+(window_area_inc_x DIV 2); _pip_yloc := ystart+2; _pip_dest := ptr_temp_screen; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+81+2+window_area_inc_x; move_to_screen_area[4] := ystart+24+1+window_area_inc_y; refresh(flag_FMREG+flag_ARPEGGIO+flag_VIBRATO); move_to_screen_area[1] := xstart+1; move_to_screen_area[2] := ystart+1; move_to_screen_area[3] := xstart+80+window_area_inc_x; move_to_screen_area[4] := ystart+24+window_area_inc_y; If (pos = 1) then GotoXY(xstart+17,ystart+4); ThinCursor; centered_frame_vdest := screen_ptr; Move(is_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,is_setting.terminate_keys,SizeOf(new_keys)); old_instr := instr; old_pos := pos; old_arp_ptr := ptr_arpeggio_table; old_vib_ptr := ptr_vibrato_table; old_fmreg_page := fmreg_page; old_arpeggio_page := arpeggio_page; old_vibrato_page := vibrato_page; _jmp2: If NOT arp_vib_mode then begin songdata.instr_macros[instr].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[instr].vibrato_table := ptr_vibrato_table; end; If (instr <> current_inst) then instr := current_inst; If NOT arp_vib_mode then begin ptr_arpeggio_table := songdata.instr_macros[instr].arpeggio_table; ptr_vibrato_table := songdata.instr_macros[instr].vibrato_table; end; If arp_vib_mode and (pos < 8) then pos := 8 else If NOT arp_vib_mode and (((ptr_arpeggio_table = 0) and (pos in [8..13])) or ((ptr_vibrato_table = 0) and (pos in [14..20]))) then pos := 1; If NOT arp_vib_mode then ShowStr(centered_frame_vdest,xstart+54+(window_area_inc_x DIV 2),ystart, byte2hex(instr),macro_background+dialog_title) else ShowStr(centered_frame_vdest,xstart+57+(window_area_inc_x DIV 2),ystart, byte2hex(instr),macro_background+dialog_title); If NOT _force_program_quit then Repeat If arp_vib_mode then refresh(flag_ARPEGGIO+flag_VIBRATO) else begin Case pos of 1..7: begin refresh_flag := flag_FMREG; If (old_pos in [8..13]) or (old_arpeggio_page <> arpeggio_page) or (old_arp_ptr <> ptr_arpeggio_table) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_ARPEGGIO; If (old_pos in [14..20]) or (old_vibrato_page <> vibrato_page) or (old_vib_ptr <> ptr_vibrato_table) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_VIBRATO; end; 8..13: begin refresh_flag := flag_ARPEGGIO; If (old_pos in [1..7]) or (old_fmreg_page <> fmreg_page) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_FMREG; If (old_pos in [14..20]) or (old_vibrato_page <> vibrato_page) or (old_vib_ptr <> ptr_vibrato_table) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_VIBRATO; end; 14..20: begin refresh_flag := flag_VIBRATO; If (old_pos in [1..7]) or (old_fmreg_page <> fmreg_page) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_FMREG; If (old_pos in [8..13]) or (old_arpeggio_page <> arpeggio_page) or (old_arp_ptr <> ptr_arpeggio_table) or (old_instr <> instr) then refresh_flag := refresh_flag+flag_ARPEGGIO; end; end; old_instr := instr; old_pos := pos; old_arp_ptr := ptr_arpeggio_table; old_vib_ptr := ptr_vibrato_table; old_fmreg_page := fmreg_page; old_arpeggio_page := arpeggio_page; old_vibrato_page := vibrato_page; refresh(refresh_flag); end; is_setting.append_enabled := TRUE; is_environment.locate_pos := 1; Case pos of (* FM_op_table table - pos: 1..7 *) 1: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.instr_macros[instr].length), xstart+17,ystart+4, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.instr_macros[instr].length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.instr_macros[instr].length < 255) then Inc(songdata.instr_macros[instr].length); kCHmins, kNPmins: If (songdata.instr_macros[instr].length > 0) then Dec(songdata.instr_macros[instr].length); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 2 else If (is_environment.keystroke = kUP) then pos := 7 else If (is_environment.keystroke = kShTAB) then If (ptr_vibrato_table <> 0) then pos := 20 else If (ptr_arpeggio_table <> 0) then pos := 13 else pos := 7; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 14 else If (ptr_arpeggio_table <> 0) then pos := 8; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 2: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.instr_macros[instr].loop_begin), xstart+17,ystart+5, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.instr_macros[instr].loop_begin := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.instr_macros[instr].loop_begin < 255) then Inc(songdata.instr_macros[instr].loop_begin); kCHmins, kNPmins: If (songdata.instr_macros[instr].loop_begin > 0) then Dec(songdata.instr_macros[instr].loop_begin); end; While NOT ((songdata.instr_macros[instr].keyoff_pos > songdata.instr_macros[instr].loop_begin+ min0(songdata.instr_macros[instr].loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 3 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 1; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 17 else If (ptr_arpeggio_table <> 0) then pos := 10; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 10 else If (ptr_vibrato_table <> 0) then pos := 17; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 3: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.instr_macros[instr].loop_length), xstart+17,ystart+6, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.instr_macros[instr].loop_length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.instr_macros[instr].loop_length < 255) then Inc(songdata.instr_macros[instr].loop_length); kCHmins, kNPmins: If (songdata.instr_macros[instr].loop_length > 0) then Dec(songdata.instr_macros[instr].loop_length); end; While NOT ((songdata.instr_macros[instr].keyoff_pos > songdata.instr_macros[instr].loop_begin+ min0(songdata.instr_macros[instr].loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos = 0)) do Inc(songdata.instr_macros[instr].keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 4 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 2; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 18 else If (ptr_arpeggio_table <> 0) then pos := 11; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 11 else If (ptr_vibrato_table <> 0) then pos := 18; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 4: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.instr_macros[instr].keyoff_pos), xstart+17,ystart+7, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or (Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255) and (Str2num(temps,16) > songdata.instr_macros[instr].loop_begin+ min0(songdata.instr_macros[instr].loop_length-1,0)) or (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (Str2num(temps,16) = 0); songdata.instr_macros[instr].keyoff_pos := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0) or (songdata.instr_macros[instr].keyoff_pos <> 0) then If (songdata.instr_macros[instr].keyoff_pos < 255) then Inc(songdata.instr_macros[instr].keyoff_pos) else else If (songdata.instr_macros[instr].loop_begin+ songdata.instr_macros[instr].loop_length <= 255) then songdata.instr_macros[instr].keyoff_pos := songdata.instr_macros[instr].loop_begin+ songdata.instr_macros[instr].loop_length; kCHmins, kNPmins: If (min0(songdata.instr_macros[instr].keyoff_pos-1,0) > songdata.instr_macros[instr].loop_begin+ min0(songdata.instr_macros[instr].loop_length-1,0)) or ((songdata.instr_macros[instr].keyoff_pos > 0) and ((songdata.instr_macros[instr].loop_begin = 0) or (songdata.instr_macros[instr].loop_length = 0))) then Dec(songdata.instr_macros[instr].keyoff_pos); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 5 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 3; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 19 else If (ptr_arpeggio_table <> 0) then pos := 12; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 12 else If (ptr_vibrato_table <> 0) then pos := 19; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 5: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(ptr_arpeggio_table), xstart+17,ystart+8, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); ptr_arpeggio_table := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (ptr_arpeggio_table < 255) then Inc(ptr_arpeggio_table); kCHmins, kNPmins: If (ptr_arpeggio_table > 0) then Dec(ptr_arpeggio_table); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 6 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 4; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 14 else If (ptr_arpeggio_table <> 0) then pos := 8; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14; end; end; 6: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(ptr_vibrato_table), xstart+17,ystart+9, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); ptr_vibrato_table := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (ptr_vibrato_table < 255) then Inc(ptr_vibrato_table); kCHmins, kNPmins: If (ptr_vibrato_table > 0) then Dec(ptr_vibrato_table); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 7 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 5; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If (ptr_vibrato_table <> 0) then pos := 14 else If (ptr_arpeggio_table <> 0) then pos := 8; kCtRGHT: If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 7: begin GotoXY(xstart+10+fmreg_cursor_pos-1,ystart+16+(window_area_inc_y DIV 2)); is_environment.keystroke := getkey; If (HI(is_environment.keystroke) = HI(kSlashR)) then With songdata.instr_macros[instr].data[fmreg_page] do begin nope := TRUE; Case fmreg_hpos of 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator XOR $80; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator XOR $40; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator XOR $10; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator XOR $20; 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier XOR $80; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier XOR $40; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier XOR $10; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier XOR $20; 33: begin nope := FALSE; Case panning of 0: panning := 2; 1: panning := 0; 2: panning := 1; end; end else nope := FALSE; end; If nope then If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; If _check_macro_speed_change then GOTO _jmp2; _check_fmreg_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT shift_pressed then If (ptr_vibrato_table <> 0) then pos := 20 else If (ptr_arpeggio_table <> 0) then pos := 13 else else If (fmreg_page > songdata.instr_macros[instr].length) then fmreg_page := min(1,songdata.instr_macros[instr].length) else fmreg_page := 1; kCtRGHT: If NOT shift_pressed then If (ptr_arpeggio_table <> 0) then pos := 13 else If (ptr_vibrato_table <> 0) then pos := 20 else else If (fmreg_page < songdata.instr_macros[instr].length) then fmreg_page := min(1,songdata.instr_macros[instr].length) else fmreg_page := 255; kUP: If (fmreg_page > 1) then Dec(fmreg_page) else If cycle_pattern then fmreg_page := 255; kDOWN: If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; kPgUP: If (fmreg_page > 16) then Dec(fmreg_page,16) else fmreg_page := 1; kPgDOWN: If (fmreg_page+16 < 255) then Inc(fmreg_page,16) else fmreg_page := 255; kHOME: If NOT shift_pressed then fmreg_page := 1 else begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kEND: If NOT shift_pressed then fmreg_page := 255 else begin fmreg_hpos := 35; fmreg_cursor_pos := max(57,31+window_area_inc_x); fmreg_left_margin := min(pos5[fmreg_hpos]-(31+window_area_inc_x)+1,1); end; kNPHOME: If shift_pressed then begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kNPEND: If shift_pressed then begin fmreg_hpos := 35; fmreg_cursor_pos := max(57,31+window_area_inc_x); fmreg_left_margin := min(pos5[fmreg_hpos]-(31+window_area_inc_x)+1,1); end; kLEFT: If (fmreg_hpos > 1) then begin Dec(fmreg_hpos); _scroll_cur_left; end else If cycle_pattern then begin fmreg_hpos := 35; fmreg_cursor_pos := max(57,31+window_area_inc_x); fmreg_left_margin := min(pos5[fmreg_hpos]-(31+window_area_inc_x)+1,1); end; kRIGHT: If (fmreg_hpos < 35) then begin Inc(fmreg_hpos); _scroll_cur_right; end else If cycle_pattern then begin fmreg_hpos := 1; fmreg_cursor_pos := 1; fmreg_left_margin := 1; end; kTAB: If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1; kShTAB: pos := 6; kENTER: If NOT shift_pressed then begin If (ptr_arpeggio_table <> 0) then pos := 8 else If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1; end else call_pickup_proc2 := TRUE; kCtrlC: begin If NOT shift_pressed then clipboard.object_type := objMacroTableLine else clipboard.object_type := objMacroTableColumn; clipboard.mcrtab_type := mttFM_reg_table; copy_object; end; kCtrlV, kAltP: begin paste_object; If (clipboard.object_type = objMacroTableLine) and (clipboard.mcrtab_type = mttFM_reg_table) then If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kAltC: If ctrl_pressed and (fmreg_hpos in [1..13]) then For temp := 1 to 255 do With songdata.instr_macros[instr].data[temp] do Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := (fm_data.ATTCK_DEC_carrier SHR 4) SHL 4+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ (fm_data.ATTCK_DEC_carrier AND $0f); 3: fm_data.SUSTN_REL_modulator := (fm_data.SUSTN_REL_carrier SHR 4) SHL 4+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ (fm_data.SUSTN_REL_carrier AND $0f); 5: fm_data.WAVEFORM_modulator := fm_data.WAVEFORM_carrier; 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0+ (fm_data.KSL_VOLUM_carrier AND $3f); 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ (fm_data.KSL_VOLUM_carrier SHR 6) SHL 6; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ (fm_data.AM_VIB_EG_carrier AND $0f); 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f+ (fm_data.AM_VIB_EG_carrier SHR 7) SHL 7; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf+ (fm_data.AM_VIB_EG_carrier SHR 6 AND 1) SHL 6; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef+ (fm_data.AM_VIB_EG_carrier SHR 4 AND 1) SHL 4; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df+ (fm_data.AM_VIB_EG_carrier SHR 5 AND 1) SHL 5; end; kAltM: If ctrl_pressed and (fmreg_hpos in [14..26]) then For temp := 1 to 255 do With songdata.instr_macros[instr].data[temp] do Case fmreg_hpos of 14: fm_data.ATTCK_DEC_carrier := (fm_data.ATTCK_DEC_modulator SHR 4) SHL 4+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ (fm_data.ATTCK_DEC_modulator AND $0f); 16: fm_data.SUSTN_REL_carrier := (fm_data.SUSTN_REL_modulator SHR 4) SHL 4+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ (fm_data.SUSTN_REL_modulator AND $0f); 18: fm_data.WAVEFORM_carrier := fm_data.WAVEFORM_modulator; 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0+ (fm_data.KSL_VOLUM_modulator AND $3f); 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ (fm_data.KSL_VOLUM_modulator SHR 6) SHL 6; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ (fm_data.AM_VIB_EG_modulator AND $0f); 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f+ (fm_data.AM_VIB_EG_modulator SHR 7) SHL 7; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf+ (fm_data.AM_VIB_EG_modulator SHR 6 AND 1) SHL 6; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef+ (fm_data.AM_VIB_EG_modulator SHR 4 AND 1) SHL 4; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df+ (fm_data.AM_VIB_EG_modulator SHR 5 AND 1) SHL 5; end; kCtrlE: begin If (songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM OR MACRO_ENVELOPE_RESTART_FLAG <> songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f + MACRO_ENVELOPE_RESTART_FLAG else songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kCtrlN: begin If (songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM OR MACRO_NOTE_RETRIG_FLAG <> songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f + MACRO_NOTE_RETRIG_FLAG else songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kCtrlZ: begin If (songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM OR MACRO_ZERO_FREQ_FLAG <> songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f + MACRO_ZERO_FREQ_FLAG else songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[fmreg_page].fm_data. FEEDBACK_FM AND $1f; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kAltE: If ctrl_pressed then For temp := 1 to 255 do If (songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM OR MACRO_ENVELOPE_RESTART_FLAG = songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM AND $1f; kAltN: If ctrl_pressed then For temp := 1 to 255 do If (songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM OR MACRO_NOTE_RETRIG_FLAG = songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM AND $1f; kAltZ: If ctrl_pressed then For temp := 1 to 255 do If (songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM OR MACRO_ZERO_FREQ_FLAG = songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM) then songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM := songdata.instr_macros[instr].data[temp].fm_data. FEEDBACK_FM AND $1f; kCtENTR: If NOT shift_pressed then begin temp := songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM; songdata.instr_macros[instr].data[fmreg_page].fm_data := songdata.instr_data[instr].fm_data; songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM := temp AND $0c0+ songdata.instr_data[instr].fm_data.FEEDBACK_FM; songdata.instr_macros[instr].data[fmreg_page].panning := songdata.instr_data[instr].panning; songdata.instr_macros[instr].data[fmreg_page].duration := min(songdata.instr_macros[instr].data[fmreg_page].duration,1); With songdata.instr_macros[instr].data[fmreg_page].fm_data do begin KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $c0+ 63-KSL_VOLUM_modulator AND $3f; KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $c0+ 63-KSL_VOLUM_carrier AND $3f; end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end else call_pickup_proc := TRUE; kINSERT: begin For temp := 255-1 downto fmreg_page do begin songdata.instr_macros[instr].data[SUCC(temp)] := songdata.instr_macros[instr].data[temp] end; FillChar(songdata.instr_macros[instr].data[fmreg_page], SizeOf(songdata.instr_macros[instr].data[fmreg_page]),0); end; kDELETE: begin For temp := fmreg_page to 255-1 do begin songdata.instr_macros[instr].data[temp] := songdata.instr_macros[instr].data[SUCC(temp)] end; FillChar(songdata.instr_macros[instr].data[255], SizeOf(songdata.instr_macros[instr].data[255]),0); end; kCHplus, kNPplus: With songdata.instr_macros[instr].data[fmreg_page] do Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := _inc(fm_data.ATTCK_DEC_modulator SHR 4,15) SHL 4+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ _inc(fm_data.ATTCK_DEC_modulator AND $0f,15); 3: fm_data.SUSTN_REL_modulator := _inc(fm_data.SUSTN_REL_modulator SHR 4,15) SHL 4+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ _inc(fm_data.SUSTN_REL_modulator AND $0f,15); 5: fm_data.WAVEFORM_modulator := _inc(fm_data.WAVEFORM_modulator,7); 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0+ _inc(fm_data.KSL_VOLUM_modulator AND $3f,63); 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ _inc(fm_data.KSL_VOLUM_modulator SHR 6,3) SHL 6; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ _inc(fm_data.AM_VIB_EG_modulator AND $0f,15); 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f+ _inc(fm_data.AM_VIB_EG_modulator SHR 7,1) SHL 7; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf+ _inc(fm_data.AM_VIB_EG_modulator SHR 6 AND 1,1) SHL 6; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef+ _inc(fm_data.AM_VIB_EG_modulator SHR 4 AND 1,1) SHL 4; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df+ _inc(fm_data.AM_VIB_EG_modulator SHR 5 AND 1,1) SHL 5; 14: fm_data.ATTCK_DEC_carrier := _inc(fm_data.ATTCK_DEC_carrier SHR 4,15) SHL 4+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ _inc(fm_data.ATTCK_DEC_carrier AND $0f,15); 16: fm_data.SUSTN_REL_carrier := _inc(fm_data.SUSTN_REL_carrier SHR 4,15) SHL 4+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ _inc(fm_data.SUSTN_REL_carrier AND $0f,15); 18: fm_data.WAVEFORM_carrier := _inc(fm_data.WAVEFORM_carrier,7); 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0+ _inc(fm_data.KSL_VOLUM_carrier AND $3f,63); 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ _inc(fm_data.KSL_VOLUM_carrier SHR 6,3) SHL 6; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ _inc(fm_data.AM_VIB_EG_carrier AND $0f,15); 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f+ _inc(fm_data.AM_VIB_EG_carrier SHR 7,1) SHL 7; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf+ _inc(fm_data.AM_VIB_EG_carrier SHR 6 AND 1,1) SHL 6; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef+ _inc(fm_data.AM_VIB_EG_carrier SHR 4 AND 1,1) SHL 4; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df+ _inc(fm_data.AM_VIB_EG_carrier SHR 5 AND 1,1) SHL 5; 27: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0fe+ _inc(fm_data.FEEDBACK_FM AND 1,1); 28: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND 1+ _inc(fm_data.FEEDBACK_FM SHR 1,7) SHL 1; 29,30,31, 32: freq_slide := _inc(freq_slide,1023); 33: Case panning of 0: panning := 2; 1: panning := 0; end; 34, 35: duration := _inc(duration,255); end; kCHmins, kNPmins: With songdata.instr_macros[instr].data[fmreg_page] do Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := _dec(fm_data.ATTCK_DEC_modulator SHR 4,0) SHL 4+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ _dec(fm_data.ATTCK_DEC_modulator AND $0f,0); 3: fm_data.SUSTN_REL_modulator := _dec(fm_data.SUSTN_REL_modulator SHR 4,0) SHL 4+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ _dec(fm_data.SUSTN_REL_modulator AND $0f,0); 5: fm_data.WAVEFORM_modulator := _dec(fm_data.WAVEFORM_modulator,0); 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0+ _dec(fm_data.KSL_VOLUM_modulator AND $3f,0); 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ _dec(fm_data.KSL_VOLUM_modulator SHR 6,0) SHL 6; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ _dec(fm_data.AM_VIB_EG_modulator AND $0f,0); 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f+ _dec(fm_data.AM_VIB_EG_modulator SHR 7,0) SHL 7; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf+ _dec(fm_data.AM_VIB_EG_modulator SHR 6 AND 1,0) SHL 6; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef+ _dec(fm_data.AM_VIB_EG_modulator SHR 4 AND 1,0) SHL 4; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df+ _dec(fm_data.AM_VIB_EG_modulator SHR 5 AND 1,0) SHL 5; 14: fm_data.ATTCK_DEC_carrier := _dec(fm_data.ATTCK_DEC_carrier SHR 4,0) SHL 4+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ _dec(fm_data.ATTCK_DEC_carrier AND $0f,0); 16: fm_data.SUSTN_REL_carrier := _dec(fm_data.SUSTN_REL_carrier SHR 4,0) SHL 4+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ _dec(fm_data.SUSTN_REL_carrier AND $0f,0); 18: fm_data.WAVEFORM_carrier := _dec(fm_data.WAVEFORM_carrier,0); 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0+ _dec(fm_data.KSL_VOLUM_carrier AND $3f,0); 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ _dec(fm_data.KSL_VOLUM_carrier SHR 6,0) SHL 6; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ _dec(fm_data.AM_VIB_EG_carrier AND $0f,0); 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f+ _dec(fm_data.AM_VIB_EG_carrier SHR 7,0) SHL 7; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf+ _dec(fm_data.AM_VIB_EG_carrier SHR 6 AND 1,0) SHL 6; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef+ _dec(fm_data.AM_VIB_EG_carrier SHR 4 AND 1,0) SHL 4; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df+ _dec(fm_data.AM_VIB_EG_carrier SHR 5 AND 1,0) SHL 5; 27: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0fe+ _dec(fm_data.FEEDBACK_FM AND 1,0); 28: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND 1+ _dec(fm_data.FEEDBACK_FM SHR 1,0) SHL 1; 29,30,31, 32: freq_slide := _dec(freq_slide,-1023); 33: Case panning of 0: panning := 1; 2: panning := 0; end; 34, 35: duration := _dec(duration,0); end; kBkSPC: If NOT shift_pressed then With songdata.instr_macros[instr].data[fmreg_page] do begin Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0; 3: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0; 5: fm_data.WAVEFORM_modulator := 0; 6, 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0c0; 8: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0; 10: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $7f; 11: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0bf; 12: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0ef; 13: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0df; 14: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0; 16: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0; 18: fm_data.WAVEFORM_carrier := 0; 19, 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0c0; 21: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0; 23: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $7f; 24: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0bf; 25: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0ef; 26: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0df; 27: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0fe; 28: fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0c1; 29,30,31, 32: freq_slide := 0; 33: panning := 0; 34, 35: duration := 0; end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end else begin FillChar(songdata.instr_macros[instr].data[fmreg_page].fm_data, SizeOf(songdata.instr_macros[instr].data[fmreg_page].fm_data),0); songdata.instr_macros[instr].data[fmreg_page].freq_slide := 0; songdata.instr_macros[instr].data[fmreg_page].panning := 0; songdata.instr_macros[instr].data[fmreg_page].duration := 0; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; kCtBkSp: Case fmreg_hpos of 1,2,3,4, 5: songdata.dis_fmreg_col[instr][fmreg_hpos-1] := NOT songdata.dis_fmreg_col[instr][fmreg_hpos-1]; 6, 7: songdata.dis_fmreg_col[instr][5] := NOT songdata.dis_fmreg_col[instr][5]; 8,9,10,11,12,13, 14,15,16,17, 18: songdata.dis_fmreg_col[instr][fmreg_hpos-2] := NOT songdata.dis_fmreg_col[instr][fmreg_hpos-2]; 19, 20: songdata.dis_fmreg_col[instr][17] := NOT songdata.dis_fmreg_col[instr][17]; 21,22,23,24, 25,26,27, 28: songdata.dis_fmreg_col[instr][fmreg_hpos-3] := NOT songdata.dis_fmreg_col[instr][fmreg_hpos-3]; 29,30,31, 32: songdata.dis_fmreg_col[instr][26] := NOT songdata.dis_fmreg_col[instr][26]; 33: songdata.dis_fmreg_col[instr][27] := NOT songdata.dis_fmreg_col[instr][27]; end; kAltS: Case fmreg_hpos of 1,2,3,4, 5: For temp := 0 to 27 do If (temp <> fmreg_hpos-1) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 6, 7: For temp := 0 to 27 do If (temp <> 5) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 8,9,10,11,12,13, 14,15,16,17, 18: For temp := 0 to 27 do If (temp <> fmreg_hpos-2) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 19, 20: For temp := 0 to 27 do If (temp <> 17) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 21,22,23,24, 25,26,27, 28: For temp := 0 to 27 do If (temp <> fmreg_hpos-3) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 29,30,31, 32: For temp := 0 to 27 do If (temp <> 26) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; 33: For temp := 0 to 27 do If (temp <> 27) then songdata.dis_fmreg_col[instr][temp] := TRUE else songdata.dis_fmreg_col[instr][temp] := FALSE; end; kAltR: For temp := 0 to 27 do songdata.dis_fmreg_col[instr][temp] := FALSE; kAstrsk, kNPastr: For temp := 0 to 27 do songdata.dis_fmreg_col[instr][temp] := NOT songdata.dis_fmreg_col[instr][temp]; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['0'..'9','A'..'F']) and NOT shift_pressed then With songdata.instr_macros[instr].data[fmreg_page] do begin nope := TRUE; Case fmreg_hpos of 1: fm_data.ATTCK_DEC_modulator := hex(CHAR(LO(is_environment.keystroke))) SHL 4+ fm_data.ATTCK_DEC_modulator AND $0f; 2: fm_data.ATTCK_DEC_modulator := fm_data.ATTCK_DEC_modulator AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 3: fm_data.SUSTN_REL_modulator := hex(CHAR(LO(is_environment.keystroke))) SHL 4+ fm_data.SUSTN_REL_modulator AND $0f; 4: fm_data.SUSTN_REL_modulator := fm_data.SUSTN_REL_modulator AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 5: If (hex(CHAR(LO(is_environment.keystroke))) <= 7) then fm_data.WAVEFORM_modulator := hex(CHAR(LO(is_environment.keystroke))) else nope := FALSE; 6: If (hex(CHAR(LO(is_environment.keystroke))) <= 3) then fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0cf+ hex(CHAR(LO(is_environment.keystroke))) SHL 4 else nope := FALSE; 7: fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 8: If (hex(CHAR(LO(is_environment.keystroke))) <= 3) then fm_data.KSL_VOLUM_modulator := fm_data.KSL_VOLUM_modulator AND $3f+ hex(CHAR(LO(is_environment.keystroke))) SHL 6 else nope := FALSE; 9: fm_data.AM_VIB_EG_modulator := fm_data.AM_VIB_EG_modulator AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 14: fm_data.ATTCK_DEC_carrier := hex(CHAR(LO(is_environment.keystroke))) SHL 4+ fm_data.ATTCK_DEC_carrier AND $0f; 15: fm_data.ATTCK_DEC_carrier := fm_data.ATTCK_DEC_carrier AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 16: fm_data.SUSTN_REL_carrier := hex(CHAR(LO(is_environment.keystroke))) SHL 4+ fm_data.SUSTN_REL_carrier AND $0f; 17: fm_data.SUSTN_REL_carrier := fm_data.SUSTN_REL_carrier AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 18: If (hex(CHAR(LO(is_environment.keystroke))) <= 7) then fm_data.WAVEFORM_carrier := hex(CHAR(LO(is_environment.keystroke))) else nope := FALSE; 19: If (hex(CHAR(LO(is_environment.keystroke))) <= 3) then fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0cf+ hex(CHAR(LO(is_environment.keystroke))) SHL 4 else nope := FALSE; 20: fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 21: If (hex(CHAR(LO(is_environment.keystroke))) <= 3) then fm_data.KSL_VOLUM_carrier := fm_data.KSL_VOLUM_carrier AND $3f+ hex(CHAR(LO(is_environment.keystroke))) SHL 6 else nope := FALSE; 22: fm_data.AM_VIB_EG_carrier := fm_data.AM_VIB_EG_carrier AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); 27: If (hex(CHAR(LO(is_environment.keystroke))) <= 1) then fm_data.FEEDBACK_FM := hex(CHAR(LO(is_environment.keystroke)))+ fm_data.FEEDBACK_FM AND $0fe else nope := FALSE; 28: If (hex(CHAR(LO(is_environment.keystroke))) <= 7) then fm_data.FEEDBACK_FM := fm_data.FEEDBACK_FM AND $0c1+ hex(CHAR(LO(is_environment.keystroke))) SHL 1 else nope := FALSE; 30: If (freq_slide > 0) or ((freq_slide = 0) and (songdata.instr_macros[instr].data[min(fmreg_page-1,1)].freq_slide >= 0)) then freq_slide := freq_slide AND $0ff+ hex(CHAR(LO(is_environment.keystroke))) SHL 8 else freq_slide := -(Abs(freq_slide) AND $0ff+ hex(CHAR(LO(is_environment.keystroke))) SHL 8); 31: If (freq_slide > 0) or ((freq_slide = 0) and (songdata.instr_macros[instr].data[min(fmreg_page-1,1)].freq_slide >= 0)) then freq_slide := freq_slide AND $0f0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4 else freq_slide := -(Abs(freq_slide) AND $0f0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4); 32: If (freq_slide > 0) or ((freq_slide = 0) and (songdata.instr_macros[instr].data[min(fmreg_page-1,1)].freq_slide >= 0)) then freq_slide := freq_slide AND $0ff0+ hex(CHAR(LO(is_environment.keystroke))) else freq_slide := -(Abs(freq_slide) AND $0ff0+ hex(CHAR(LO(is_environment.keystroke)))); 34: duration := duration AND $0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4; 35: duration := duration AND $0f0+ hex(CHAR(LO(is_environment.keystroke))); else nope := FALSE; end; If nope then Case fmreg_hpos of 6,19,30,31, 34: If NOT (command_typing = 2) then begin If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end else begin Inc(fmreg_hpos); _scroll_cur_right; end; 7,20,32, 35: begin If (command_typing = 2) then begin If (fmreg_hpos <> 32) then Dec(fmreg_hpos) else Dec(fmreg_hpos,2); _scroll_cur_left; end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; else If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['L','C','R']) and NOT shift_pressed then With songdata.instr_macros[instr].data[fmreg_page] do begin nope := TRUE; Case fmreg_hpos of 33: Case UpCase(CHAR(LO(is_environment.keystroke))) of 'L': panning := 1; 'C': panning := 0; 'R': panning := 2; end; else nope := FALSE; end; If nope then If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['+','-']) and (fmreg_hpos = 29) then With songdata.instr_macros[instr].data[fmreg_page] do begin Case UpCase(CHAR(LO(is_environment.keystroke))) of '+': freq_slide := Abs(freq_slide); '-': freq_slide := -Abs(freq_slide); end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; If shift_pressed and ((is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN)) then begin If (ptr_arpeggio_table <> 0) then arpeggio_page := fmreg_page; If (ptr_vibrato_table <> 0) then vibrato_page := fmreg_page; end; end; (* Arpeggio table - pos: 8..13 *) 8: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length), xstart+60+window_area_inc_x,ystart+4, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_arpeggio_table]. arpeggio.length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.length < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.length > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.length); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 9 else If (is_environment.keystroke = kUP) then pos := 13 else If (is_environment.keystroke = kShTAB) then If NOT arp_vib_mode then pos := 7 else pos := 20; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 1 else pos := 14; kCtRGHT: If arp_vib_mode then pos := 14 else If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 9: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed), xstart+60+window_area_inc_x,ystart+5, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.speed); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 10 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 8; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 1 else pos := 15; kCtRGHT: If arp_vib_mode then pos := 15 else If (ptr_vibrato_table <> 0) then pos := 15 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 10: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin), xstart+60+window_area_inc_x,ystart+6, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin); end; While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 11 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 9; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 2 else pos := 17; kCtRGHT: If arp_vib_mode then pos := 17 else If (ptr_vibrato_table <> 0) then pos := 17 else pos := 2; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 11: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length), xstart+60+window_area_inc_x,ystart+7, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length > 0) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length); end; While NOT ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 12 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 10; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 3 else pos := 18; kCtRGHT: If arp_vib_mode then pos := 18 else If (ptr_vibrato_table <> 0) then pos := 18 else pos := 3; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 12: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos), xstart+60+window_area_inc_x,ystart+8, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or (Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255) and (Str2num(temps,16) > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (Str2num(temps,16) = 0); songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos <> 0) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos < 255) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length <= 255) then songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos := songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length; kCHmins, kNPmins: If (min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos-1,0) > songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin+ min0(songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length-1,0)) or ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos > 0) and ((songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_begin = 0) or (songdata.macro_table[ptr_arpeggio_table]. arpeggio.loop_length = 0))) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.keyoff_pos); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 13 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 11; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT arp_vib_mode then pos := 4 else pos := 19; kCtRGHT: If arp_vib_mode then pos := 19 else If (ptr_vibrato_table <> 0) then pos := 19 else pos := 4; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 13: begin GotoXY(xstart+55+window_area_inc_x,ystart+16+(window_area_inc_y DIV 2)); is_environment.keystroke := getkey; If _check_macro_speed_change then GOTO _jmp2; _check_arp_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT shift_pressed then If NOT arp_vib_mode then pos := 7 else pos := 20 else If (arpeggio_page > songdata.macro_table[ptr_arpeggio_table].arpeggio.length) then arpeggio_page := min(1,songdata.macro_table[ptr_arpeggio_table].arpeggio.length) else arpeggio_page := 1; kCtRGHT: If NOT shift_pressed then If NOT arp_vib_mode then If (ptr_vibrato_table <> 0) then pos := 20 else pos := 7 else pos := 20 else If (arpeggio_page < songdata.macro_table[ptr_arpeggio_table].arpeggio.length) then arpeggio_page := min(1,songdata.macro_table[ptr_arpeggio_table].arpeggio.length) else arpeggio_page := 255; kUP: If (arpeggio_page > 1) then Dec(arpeggio_page) else If cycle_pattern then arpeggio_page := 255; kDOWN: If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; kPgUP: If (arpeggio_page > 16) then Dec(arpeggio_page,16) else arpeggio_page := 1; kPgDOWN: If (arpeggio_page+16 < 255) then Inc(arpeggio_page,16) else arpeggio_page := 255; kHOME: arpeggio_page := 1; kEND: arpeggio_page := 255; kENTER,kTAB: If NOT arp_vib_mode then If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1 else pos := 14; kShTAB: pos := 12; kCtrlC: begin If NOT shift_pressed then clipboard.object_type := objMacroTableLine else clipboard.object_type := objMacroTableColumn; clipboard.mcrtab_type := mttArpeggio_table; copy_object; end; kCtrlV, kAltP: begin paste_object; If (clipboard.object_type = objMacroTableLine) and (clipboard.mcrtab_type = mttArpeggio_table) then If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end; kCHplus, kNPplus: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] < $80) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] < 96) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] < $80+96+1) then Inc(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]); kCHmins, kNPmins: If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] < $80) then If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] > 1) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]) else else If (songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] > $80+1) then Dec(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]); kBkSPC: begin songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := 0; If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end; kINSERT: begin For temp := 255-1 downto arpeggio_page do begin songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[SUCC(temp)] := songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] end; FillChar(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page], SizeOf(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]),0); end; kDELETE: begin For temp := arpeggio_page to 255-1 do begin songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[temp] := songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[SUCC(temp)] end; FillChar(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[255], SizeOf(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[255]),0); end; end; If shift_pressed and ((is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN)) then begin fmreg_page := arpeggio_page; If (ptr_vibrato_table <> 0) then vibrato_page := arpeggio_page; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['A',UpCase(b_note),'C'..'G']) and NOT shift_pressed then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['1'..'9','a',b_note,'c'..'g', 'A',UpCase(b_note),'C'..'F','#','-']; is_environment.locate_pos := 2; tstr := CHAR(LO(is_environment.keystroke)); Repeat tstr := InputStr(tstr,xstart+55+window_area_inc_x,ystart+16+(window_area_inc_y DIV 2),3,3, macro_input_bckg+macro_input, macro_def_bckg+macro_def); is_setting.append_enabled := TRUE; If (UpCase(tstr[1]) in ['+','0'..'9','A',UpCase(b_note),'C'..'G']) and ((is_environment.keystroke = kENTER) or (is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB)) then begin nope := FALSE; If (tstr[1] = '+') then Delete(tstr,1,1); If (tstr[1] in DEC_NUM_CHARSET) and (Str2num(tstr,10) >= 0) and (Str2num(tstr,10) <= 96) then begin nope := TRUE; songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := Str2num(tstr,10); If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end else begin If (Length(tstr) = 2) then If tstr[2] in ['1'..'9'] then Insert('-',tstr,2) else If tstr[2] in ['-','#'] then tstr := tstr + Num2str(current_octave,10); If (Length(tstr) = 1) then tstr := tstr + '-' + Num2str(current_octave,10); For temp1 := 1 to 12*8+1 do If (Upper(tstr) = note_layout[temp1]) then begin nope := TRUE; songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := $80+temp1; BREAK; end; If NOT nope and (Length(tstr) = 2) then For temp1 := 1 to 12*8+1 do If (Copy(Upper(tstr),1,2) = Copy(note_layout[temp1],1,2)) then begin nope := TRUE; songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := $80+temp1; BREAK; end; If nope then Case is_environment.keystroke of kUP: If (arpeggio_page > 1) then Dec(arpeggio_page) else If cycle_pattern then arpeggio_page := 255; kDOWN, kENTER: If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end; If NOT nope then Case songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] of 0: tstr := '+0'; 1..96: tstr := '+'+Num2str(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page],10); $80..$80+12*8+1: tstr := note_layout[songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]-$80]; end; end; end; until (nope or (is_environment.keystroke = kESC)) and ((is_environment.keystroke = kESC) or (is_environment.keystroke = kENTER) or (is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB)); nope := FALSE; Case is_environment.keystroke of kTAB: If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1; kShTAB: pos := 12; kESC: is_environment.keystroke := kENTER; end; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['+','0'..'9']) and NOT shift_pressed then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['+','0'..'9']; is_environment.locate_pos := 2; tstr := CHAR(LO(is_environment.keystroke)); If (CHAR(LO(is_environment.keystroke)) <> '+') then begin tstr := '+'+tstr; Inc(is_environment.locate_pos); end; Repeat tstr := InputStr(tstr,xstart+55+window_area_inc_x,ystart+16+(window_area_inc_y DIV 2),3,3, macro_input_bckg+macro_input, macro_def_bckg+macro_def); is_setting.append_enabled := TRUE; temps := tstr; If ((is_environment.keystroke = kENTER) or (is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB)) then begin nope := FALSE; If (tstr[1] = '+') then Delete(tstr,1,1); If (tstr[1] in DEC_NUM_CHARSET) and (Str2num(tstr,10) >= 0) and (Str2num(tstr,10) <= 96) then begin nope := TRUE; songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] := Str2num(tstr,10); end else tstr := temps; If nope then Case is_environment.keystroke of kUP: If (arpeggio_page > 1) then Dec(arpeggio_page) else If cycle_pattern then arpeggio_page := 255; kDOWN, kENTER: If (arpeggio_page < 255) then Inc(arpeggio_page) else If cycle_pattern then arpeggio_page := 1; end; If NOT nope then Case songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page] of 0: tstr := '+0'; 1..96: tstr := '+'+Num2str(songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page],10); $80..$80+12*8+1: tstr := note_layout[songdata.macro_table[ptr_arpeggio_table]. arpeggio.data[arpeggio_page]-$80]; end; end; until (nope or (is_environment.keystroke = kESC)) and ((is_environment.keystroke = kESC) or (is_environment.keystroke = kENTER) or (is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kShTAB)); nope := FALSE; Case is_environment.keystroke of kTAB: If NOT arp_vib_mode then If (ptr_vibrato_table <> 0) then pos := 14 else pos := 1 else pos := 14; kShTAB: pos := 12; kESC: is_environment.keystroke := kENTER; end; end; end; (* Vibrato table - pos: 14..20 *) 14: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.length), xstart+77+window_area_inc_x,ystart+4, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.length < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.length); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.length > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.length); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 15 else If (is_environment.keystroke = kUP) then pos := 20 else If (is_environment.keystroke = kShTAB) then If NOT arp_vib_mode then If (ptr_arpeggio_table <> 0) then pos := 13 else pos := 7 else pos := 13; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 8 else If (ptr_arpeggio_table <> 0) then pos := 8 else pos := 1; kCtRGHT: If arp_vib_mode then pos := 8 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 15: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.speed), xstart+77+window_area_inc_x,ystart+5, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.speed := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.speed < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.speed); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.speed > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.speed); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 16 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 14; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 9 else If (ptr_arpeggio_table <> 0) then pos := 9 else pos := 1; kCtRGHT: If arp_vib_mode then pos := 9 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 16: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.delay), xstart+77+window_area_inc_x,ystart+6, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.delay := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.delay < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.delay); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.delay > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.delay); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 17 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 15; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 8 else If (ptr_arpeggio_table <> 0) then pos := 8 else pos := 1; kCtRGHT: If arp_vib_mode then pos := 8 else pos := 1; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 17: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin), xstart+77+window_area_inc_x,ystart+7, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin); end; While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 18 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 16; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 10 else If (ptr_arpeggio_table <> 0) then pos := 10 else pos := 2; kCtRGHT: If arp_vib_mode then pos := 10 else pos := 2; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 18: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length), xstart+77+window_area_inc_x,ystart+8, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255)); songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length); kCHmins, kNPmins: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length > 0) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length); end; While NOT ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos = 0)) do Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 19 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 17; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 11 else If (ptr_arpeggio_table <> 0) then pos := 11 else pos := 3; kCtRGHT: If arp_vib_mode then pos := 11 else pos := 3; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 19: begin is_setting.character_set := HEX_NUM_CHARSET; Repeat temps := InputStr(byte2hex(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos), xstart+77+window_area_inc_x,ystart+9, 2,2, macro_input_bckg+macro_input, macro_def_bckg+macro_def); until (is_environment.keystroke = kESC) or (Str2num(temps,16) >= 0) and (Str2num(temps,16) <= 255) and (Str2num(temps,16) > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (Str2num(temps,16) = 0); songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos := Str2num(temps,16); Case is_environment.keystroke of kCHplus, kNPplus: If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos <> 0) then If (songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos < 255) then Inc(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos) else else If (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length <= 255) then songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos := songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length; kCHmins, kNPmins: If (min0(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos-1,0) > songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin+ min0(songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length-1,0)) or ((songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos > 0) and ((songdata.macro_table[ptr_vibrato_table]. vibrato.loop_begin = 0) or (songdata.macro_table[ptr_vibrato_table]. vibrato.loop_length = 0))) then Dec(songdata.macro_table[ptr_vibrato_table]. vibrato.keyoff_pos); end; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 20 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 18; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If arp_vib_mode then pos := 12 else If (ptr_arpeggio_table <> 0) then pos := 12 else pos := 4; kCtRGHT: If arp_vib_mode then pos := 12 else pos := 4; kCtrlC: begin clipboard.object_type := objMacroTable; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: paste_object; end; end; 20: begin GotoXY(xstart+72+vibrato_hpos-1+window_area_inc_x,ystart+16+(window_area_inc_y DIV 2)); is_environment.keystroke := getkey; If _check_macro_speed_change then GOTO _jmp2; _check_vib_general_keys; Case is_environment.keystroke of kCtLEFT: If NOT shift_pressed then If NOT arp_vib_mode then If (ptr_arpeggio_table <> 0) then pos := 13 else pos := 7 else pos := 13 else If (vibrato_page > songdata.macro_table[ptr_vibrato_table].vibrato.length) then vibrato_page := min(1,songdata.macro_table[ptr_vibrato_table].vibrato.length) else vibrato_page := 1; kCtRGHT: If NOT shift_pressed then If NOT arp_vib_mode then pos := 7 else pos := 13 else If (vibrato_page < songdata.macro_table[ptr_vibrato_table].vibrato.length) then vibrato_page := min(1,songdata.macro_table[ptr_vibrato_table].vibrato.length) else vibrato_page := 255; kUP: If (vibrato_page > 1) then Dec(vibrato_page) else If cycle_pattern then vibrato_page := 255; kDOWN: If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; kPgUP: If (vibrato_page > 16) then Dec(vibrato_page,16) else vibrato_page := 1; kPgDOWN: If (vibrato_page+16 < 255) then Inc(vibrato_page,16) else vibrato_page := 255; kHOME: vibrato_page := 1; kEND: vibrato_page := 255; kLEFT: If (vibrato_hpos > 1) then Dec(vibrato_hpos) else vibrato_hpos := 3; kRIGHT: If (vibrato_hpos < 3) then Inc(vibrato_hpos) else vibrato_hpos := 1; kENTER,kTAB: If NOT arp_vib_mode then pos := 1 else pos := 8; kShTAB: pos := 19; kCtrlC: begin If NOT shift_pressed then clipboard.object_type := objMacroTableLine else clipboard.object_type := objMacroTableColumn; clipboard.mcrtab_type := mttVibrato_table; copy_object; end; kCtrlV, kAltP: begin paste_object; If (clipboard.object_type = objMacroTableLine) and (clipboard.mcrtab_type = mttVibrato_table) then If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; end; kBkSPC: begin songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page] := 0; If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; end; kINSERT: begin For temp := 255-1 downto vibrato_page do begin songdata.macro_table[ptr_vibrato_table]. vibrato.data[SUCC(temp)] := songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp] end; FillChar(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page], SizeOf(songdata.macro_table[ptr_vibrato_table]. vibrato.data[vibrato_page]),0); end; kDELETE: begin For temp := vibrato_page to 255-1 do begin songdata.macro_table[ptr_vibrato_table]. vibrato.data[temp] := songdata.macro_table[ptr_vibrato_table]. vibrato.data[SUCC(temp)] end; FillChar(songdata.macro_table[ptr_vibrato_table]. vibrato.data[255], SizeOf(songdata.macro_table[ptr_vibrato_table]. vibrato.data[255]),0); end; end; If shift_pressed and ((is_environment.keystroke = kUP) or (is_environment.keystroke = kDOWN)) then begin fmreg_page := vibrato_page; If (ptr_arpeggio_table <> 0) then arpeggio_page := vibrato_page; end; If (UpCase(CHAR(LO(is_environment.keystroke))) in ['0'..'9','A'..'F','+','-']) then With songdata.macro_table[ptr_vibrato_table].vibrato do begin nope := TRUE; Case vibrato_hpos of 1: Case UpCase(CHAR(LO(is_environment.keystroke))) of '+': data[vibrato_page] := Abs(data[vibrato_page]); '-': data[vibrato_page] := -Abs(data[vibrato_page]); else nope := FALSE; end; 2: Case UpCase(CHAR(LO(is_environment.keystroke))) of '0'..'7': If (data[vibrato_page] > 0) or ((data[vibrato_page] = 0) and (data[min(vibrato_page-1,1)] >= 0)) then data[vibrato_page] := data[vibrato_page] AND $0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4 else data[vibrato_page] := -(Abs(data[vibrato_page]) AND $0f+ hex(CHAR(LO(is_environment.keystroke))) SHL 4); '8'..'F': If (data[vibrato_page] > 0) or ((data[vibrato_page] = 0) and (data[min(vibrato_page-1,1)] >= 0)) then data[vibrato_page] := $7f else data[vibrato_page] := -$7f; '+': begin If (data[vibrato_page] < $7f) then Inc(data[vibrato_page]); nope := FALSE; end; '-': begin If (data[vibrato_page] > -$7f) then Dec(data[vibrato_page]); nope := FALSE; end; end; 3: Case UpCase(CHAR(LO(is_environment.keystroke))) of '0'..'9', 'A'..'F': If (data[vibrato_page] > 0) or ((data[vibrato_page] = 0) and (data[min(vibrato_page-1,1)] >= 0)) then data[vibrato_page] := data[vibrato_page] AND $0f0+ hex(CHAR(LO(is_environment.keystroke))) else data[vibrato_page] := -(Abs(data[vibrato_page]) AND $0f0+ hex(CHAR(LO(is_environment.keystroke)))); '+': begin If (data[vibrato_page] < $7f) then Inc(data[vibrato_page]); nope := FALSE; end; '-': begin If (data[vibrato_page] > -$7f) then Dec(data[vibrato_page]); nope := FALSE; end; end; end; If nope then Case vibrato_hpos of 1,3: begin If (command_typing = 2) and NOT (UpCase(CHAR(LO(is_environment.keystroke))) in ['-','+']) and (vibrato_hpos = 3) then Dec(vibrato_hpos); If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; end; 2: If NOT (command_typing = 2) or (UpCase(CHAR(LO(is_environment.keystroke))) in ['-','+']) then begin If (vibrato_page < 255) then Inc(vibrato_page) else If cycle_pattern then vibrato_page := 1; end else Inc(vibrato_hpos); end; end; end; end; If NOT shift_pressed and (is_environment.keystroke = kSPACE) then begin refresh(0); HideCursor; _pip_dest := screen_ptr; If (get_4op_to_test <> 0) then _macro_preview_init(1,BYTE(NOT BYTE_NULL)) else _macro_preview_init(1,BYTE_NULL); If ctrl_pressed and (is_environment.keystroke = kSPACE) then begin _pip_loop := TRUE; For temp := 1 to 20 do keyoff_loop[temp] := _pip_loop; end else For temp := 1 to 20 do keyoff_loop[temp] := _pip_loop; macro_preview_indic_proc := _preview_indic_proc; is_environment.keystroke := WORD_NULL; If NOT _force_program_quit then Repeat // update octave For temp := 1 to 8 do If (temp <> current_octave) then show_str(30+temp,30,CHR(48+temp), main_background+main_stat_line) else show_str(30+temp,30,CHR(48+temp), main_background+main_hi_stat_line); If keypressed then begin is_environment.keystroke := getkey; Case is_environment.keystroke of kF7: For temp := 1 to 20 do reset_chan_data(temp); kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; reset_player; end else If (current_inst > 1) then begin Dec(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); STATUS_LINE_refresh; reset_player; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; reset_player; end else If (current_inst < 255) then begin Inc(current_inst); If NOT (marked_instruments = 2) then reset_marked_instruments; instrum_page := current_inst; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); STATUS_LINE_refresh; reset_player; end; kAlt0: FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); kAlt1: If shift_pressed then _set_operator_flag(1,TRUE) else _set_operator_flag(1,FALSE); kAlt2: If shift_pressed then _set_operator_flag(2,TRUE) else _set_operator_flag(2,FALSE); kAlt3: If shift_pressed then _set_operator_flag(3,TRUE) else _set_operator_flag(3,FALSE); kAlt4: If shift_pressed then _set_operator_flag(4,TRUE) else _set_operator_flag(4,FALSE); end; If (is_environment.keystroke = kCtLbr) or (is_environment.keystroke = kCtRbr) or (is_environment.keystroke = kAlt0) or (is_environment.keystroke = kAlt1) or (is_environment.keystroke = kAlt2) or (is_environment.keystroke = kAlt3) or (is_environment.keystroke = kAlt4) then begin keyboard_reset_buffer; If NOT arp_vib_mode then begin songdata.instr_macros[instr].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[instr].vibrato_table := ptr_vibrato_table; end; If (get_4op_to_test <> 0) then _macro_preview_init(0,BYTE(NOT BYTE_NULL)) else _macro_preview_init(0,BYTE_NULL); instr := current_inst; If NOT arp_vib_mode then begin ptr_arpeggio_table := songdata.instr_macros[instr].arpeggio_table; ptr_vibrato_table := songdata.instr_macros[instr].vibrato_table; end; If arp_vib_mode and (pos < 8) then pos := 8 else If NOT arp_vib_mode and (((ptr_arpeggio_table = 0) and (pos in [8..13])) or ((ptr_vibrato_table = 0) and (pos in [14..20]))) then pos := 1; If NOT arp_vib_mode then ShowStr(centered_frame_vdest,xstart+54+(window_area_inc_x DIV 2),ystart, byte2hex(instr),macro_background+dialog_title) else ShowStr(centered_frame_vdest,xstart+57+(window_area_inc_x DIV 2),ystart, byte2hex(instr),macro_background+dialog_title); refresh(flag_FMREG+flag_ARPEGGIO+flag_VIBRATO); If (get_4op_to_test <> 0) then _macro_preview_init(1,BYTE(NOT BYTE_NULL)) else _macro_preview_init(1,BYTE_NULL); end; If (get_4op_to_test <> 0) then _macro_preview_body(LO(get_4op_to_test),HI(get_4op_to_test),count_channel(pattern_hpos),is_environment.keystroke) else _macro_preview_body(instrum_page,BYTE_NULL,count_channel(pattern_hpos),is_environment.keystroke); If ctrl_pressed and NOT shift_pressed and (is_environment.keystroke = kSPACE) then begin _pip_loop := NOT _pip_loop; For temp := 1 to 20 do keyoff_loop[temp] := _pip_loop; is_environment.keystroke := WORD_NULL; end; If shift_pressed and (is_environment.keystroke = kSPACE) then is_environment.keystroke := WORD_NULL; end else If NOT (seconds_counter >= ssaver_time) then GOTO _end2 //CONTINUE else begin screen_saver; GOTO _end2; //CONTINUE; end; _end2: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (is_environment.keystroke = kSPACE) or (is_environment.keystroke = kESC); If (get_4op_to_test <> 0) then _macro_preview_init(0,BYTE(NOT BYTE_NULL)) else _macro_preview_init(0,BYTE_NULL); macro_preview_indic_proc := NIL; _pip_dest := ptr_temp_screen; ThinCursor; end; {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (is_environment.keystroke = kESC) or (is_environment.keystroke = kCtrlO) or (is_environment.keystroke = kF1) or (is_environment.keystroke = kF2) or (is_environment.keystroke = kCtrlF2) or (is_environment.keystroke = kF3) or (is_environment.keystroke = kCtrlL) or (is_environment.keystroke = kCtrlS) or (is_environment.keystroke = kCtrlM) or (NOT ctrl_pressed and (is_environment.keystroke = kAltC)) or call_pickup_proc or call_pickup_proc2; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); _macro_editor__pos[arp_vib_mode] := pos; _macro_editor__fmreg_hpos[arp_vib_mode] := fmreg_hpos; _macro_editor__fmreg_page[arp_vib_mode] := fmreg_page; _macro_editor__fmreg_left_margin[arp_vib_mode] := fmreg_left_margin; _macro_editor__fmreg_cursor_pos[arp_vib_mode] := fmreg_cursor_pos; _macro_editor__arpeggio_page[arp_vib_mode] := arpeggio_page; _macro_editor__vibrato_hpos[arp_vib_mode] := vibrato_hpos; _macro_editor__vibrato_page[arp_vib_mode] := vibrato_page; If NOT arp_vib_mode then begin songdata.instr_macros[instr].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[instr].vibrato_table := ptr_vibrato_table; end else begin If shift_pressed then begin songdata.instr_macros[current_inst].arpeggio_table := ptr_arpeggio_table; songdata.instr_macros[current_inst].vibrato_table := ptr_vibrato_table; end; arpvib_arpeggio_table := ptr_arpeggio_table; arpvib_vibrato_table := ptr_vibrato_table; end; For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; songdata.instr_names[temp][1] := ' '; end; If (Update32(songdata,SizeOf(songdata),0) <> songdata_crc) then module_archived := FALSE; For temp := 1 to 255 do songdata.instr_names[temp][1] := temp_marks[temp]; HideCursor; Move(old_keys,is_setting.terminate_keys,SizeOf(old_keys)); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+81+2+window_area_inc_x; move_to_screen_area[4] := ystart+24+1+window_area_inc_x; move2screen; Case is_environment.keystroke of kAltC: If NOT ctrl_pressed then begin If (pos in [7,13,20]) then begin copy_menu_str4[13] := copy_macro_str[2]; copy_menu_str4[14] := copy_macro_str[4]; end else begin copy_menu_str4[13] := copy_macro_str[1]; copy_menu_str4[14] := copy_macro_str[3]; end; mn_setting.cycle_moves := TRUE; temp := Menu(copy_menu_str4,01,01,copypos4,30,15,15,' COPY OBJECT '); copy_menu_str4[13] := copy_macro_str[2]; copy_menu_str4[14] := copy_macro_str[4]; If (mn_environment.keystroke <> kESC) then begin copypos4 := temp; clipboard.object_type := tCOPY_OBJECT(temp); Case pos of 1..7: clipboard.mcrtab_type := mttFM_reg_table; 8..13: clipboard.mcrtab_type := mttArpeggio_table; 14..20: clipboard.mcrtab_type := mttVibrato_table; end; copy_object; end; GOTO _jmp1; end; kENTER: If call_pickup_proc2 then begin call_pickup_proc2 := FALSE; temp := INSTRUMENT_CONTROL_alt(_source_ins2,'FM-REGiSTER MACRO: PASTE DATA TO iNSTRUMENT'); If (temp <> 0) then begin _source_ins2 := temp; songdata.instr_data[_source_ins2].fm_data := songdata.instr_macros[instr].data[fmreg_page].fm_data; songdata.instr_data[_source_ins2].panning := songdata.instr_macros[instr].data[fmreg_page].panning; songdata.instr_data[_source_ins2].fine_tune := songdata.instr_data[instr].fine_tune; songdata.instr_data[_source_ins2].perc_voice := songdata.instr_data[instr].perc_voice; songdata.instr_data[_source_ins2].fm_data.FEEDBACK_FM := songdata.instr_data[_source_ins2].fm_data.FEEDBACK_FM AND $3f; With songdata.instr_data[_source_ins2].fm_data do begin KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $c0+ 63-KSL_VOLUM_modulator AND $3f; KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $c0+ 63-KSL_VOLUM_carrier AND $3f; end; end; GOTO _jmp1; end; kCtENTR: If call_pickup_proc then begin call_pickup_proc := FALSE; temp := INSTRUMENT_CONTROL_alt(_source_ins,'FM-REGiSTER MACRO: PASTE DATA FROM iNSTRUMENT'); If (temp <> 0) then begin _source_ins := temp; temp := songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM; songdata.instr_macros[instr].data[fmreg_page].fm_data := songdata.instr_data[_source_ins].fm_data; songdata.instr_macros[instr].data[fmreg_page]. fm_data.FEEDBACK_FM := temp AND $0c0+ songdata.instr_data[_source_ins].fm_data.FEEDBACK_FM AND $3f; songdata.instr_macros[instr].data[fmreg_page].panning := songdata.instr_data[_source_ins].panning; songdata.instr_macros[instr].data[fmreg_page].duration := min(songdata.instr_macros[instr].data[fmreg_page].duration,1); With songdata.instr_macros[instr].data[fmreg_page].fm_data do begin KSL_VOLUM_modulator := KSL_VOLUM_modulator AND $c0+ 63-KSL_VOLUM_modulator AND $3f; KSL_VOLUM_carrier := KSL_VOLUM_carrier AND $c0+ 63-KSL_VOLUM_carrier AND $3f; end; If (fmreg_page < 255) then Inc(fmreg_page) else If cycle_pattern then fmreg_page := 1; end; GOTO _jmp1; end; kF2, kCtrlS: begin quick_cmd := FALSE; If NOT arp_vib_mode then FILE_save('a2f') else FILE_save('a2w'); GOTO _jmp1; end; kCtrlF2: begin quick_cmd := FALSE; If NOT arp_vib_mode then FILE_save('a2w'); GOTO _jmp1; end; kF3, kCtrlL: begin If (pos < 8) then temps := '*.a2i$*.a2f$*.a2b$*.a2w$'+ '*.bnk$*.cif$*.fib$*.fin$*.ibk$*.ins$*.sbi$*.sgi$' else temps := '*.a2w$'; quick_cmd := FALSE; If NOT (pos < 8) then _arp_vib_loader := TRUE else _arp_vib_loader := FALSE; If _arp_vib_loader then begin arp_tab_selected := pos in [8..13]; vib_tab_selected := pos in [14..20]; If NOT arp_vib_mode then begin arpvib_arpeggio_table := ptr_arpeggio_table; arpvib_vibrato_table := ptr_vibrato_table; end; end else begin arp_tab_selected := ptr_arpeggio_table <> 0; vib_tab_selected := ptr_vibrato_table <> 0; If NOT (arp_tab_selected or vib_tab_selected) then begin arp_tab_selected := TRUE; vib_tab_selected := TRUE; end; end; FILE_open(temps,FALSE); update_instr_data(instrum_page); GOTO _jmp1; end; kCtrlO: begin OCTAVE_CONTROL; GOTO _jmp1; end; kCtrlM: begin MACRO_BROWSER((pos < 8),FALSE); GOTO _jmp1; end; kF1: begin If NOT arp_vib_mode then HELP('macro_editor') else HELP('macro_editor_(av)'); GOTO _jmp1; end; end; _pip_loop := FALSE; end; procedure MACRO_BROWSER(instrBrowser: Boolean; updateCurInstr: Boolean); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT4.PAS:MACRO_BROWSER'; {$ENDIF} songdata_crc := Update32(songdata,SizeOf(songdata),0); a2w_file_loader(FALSE,NOT instrBrowser,TRUE,FALSE,updateCurInstr); // browse internal A2W data If (Update32(songdata,SizeOf(songdata),0) <> songdata_crc) then module_archived := FALSE; end; end. adlibtracker2-2.4.24/ipattern.inc0000644000000000000000000072205213411003760015336 0ustar rootroot// 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 cancel_note_recorder; procedure PATTERN_tabs_refresh; procedure STATUS_LINE_refresh; function last_chan_pos: Byte; function last_hpos: Byte; procedure PATTERN_page_refresh(page: Byte); procedure PATTERN_position_preview(pattern,line,channel,mode: Byte); function PATTERN_trace: Word; procedure PATTERN_edit(var pattern,page,hpos: Byte); } const old_nm_track_chan: Byte = 0; old_track_chan_start: Byte = 0; const pattern_undo_flag: Boolean = FALSE; var pattern_undo_patt: Byte; pattern_undo_data: array[0..PRED(SizeOf(tPATTERN_DATA) DIV 16)] of Byte; procedure cancel_note_recorder; begin If track_notes then begin old_nm_track_chan := nm_track_chan; old_track_chan_start := track_chan_start; track_notes := FALSE; nm_track_chan := 1; end; end; procedure PATTERN_tabs_refresh; var temp: Byte; begin If (command_typing <> 0) then begin For temp := chan_pos to max(chan_pos+MAX_TRACKS-1,songdata.nm_tracks) do If (temp <> count_channel(pattern_hpos)) then show_str(08+(temp-PRED(chan_pos)-1)*15,10, patt_tab_str[0], pattern_bckg+pattern_border); Case count_pos(pattern_hpos) of 0, 1: show_cstr(08+(count_channel(pattern_hpos)-PRED(chan_pos)-1)*15,10, patt_tab_str[1], pattern_bckg+pattern_border, pattern_bckg+pattern_pos_indic); 2, 3: show_cstr(08+(count_channel(pattern_hpos)-PRED(chan_pos)-1)*15,10, patt_tab_str[2], pattern_bckg+pattern_border, pattern_bckg+pattern_pos_indic); 4,5, 6: show_cstr(08+(count_channel(pattern_hpos)-PRED(chan_pos)-1)*15,10, patt_tab_str[3], pattern_bckg+pattern_border, pattern_bckg+pattern_pos_indic); 7,8, 9: show_cstr(08+(count_channel(pattern_hpos)-PRED(chan_pos)-1)*15,10, patt_tab_str[4], pattern_bckg+pattern_border, pattern_bckg+pattern_pos_indic); end; end; end; procedure STATUS_LINE_refresh; var tracking_indicator_attr: array[Boolean] of Byte; attr: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:STATUS_LINE_refresh'; {$ENDIF} If really_no_status_refresh then EXIT; If (get_4op_to_test <> 0) then show_cstr(40,MAX_PATTERN_ROWS+12,'~[~'+byte2hex(HI(get_4op_to_test))+'~+~'+byte2hex(LO(get_4op_to_test))+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line) else show_cstr(40,MAX_PATTERN_ROWS+12,'~[~'+byte2hex(current_inst)+'~]~'#196#196#196, main_background+main_border, main_background+main_stat_line); If marking and NOT (discard_block or (tracing and (pattern_patt <> tracing_block_pattern))) then show_cstr(MAX_COLUMNS-39,MAX_PATTERN_ROWS+12,'~[M.BLOCK:~'+ byte2hex(block_y0)+','+byte2dec(block_x0)+'~'#196#16'~'+ byte2hex(block_y1)+','+byte2dec(block_x1)+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line) else begin show_cstr(MAX_COLUMNS-39,MAX_PATTERN_ROWS+12,'~[LN:~'+ExpStrL(Num2str(pattern_page,10),3,'0')+'/'+ExpStrL(Num2str(PRED(songdata.patt_len),10),3,'0')+'~;~', main_background+main_hi_stat_line, main_background+main_stat_line); show_cstr(MAX_COLUMNS-27,MAX_PATTERN_ROWS+12,'~TRK:~'+byte2dec(count_channel(pattern_hpos))+'/'+byte2dec(songdata.nm_tracks)+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line); end; If midiboard or (debugging and (play_status = isStopped)) then show_str(03,MAX_PATTERN_ROWS+12,'MBOARD',main_background+main_hi_stat_line) else show_str(03,MAX_PATTERN_ROWS+12,'MBOARD',main_background+main_stat_line); If NOT debugging and tracing and (play_status <> isStopped) then show_str(10,MAX_PATTERN_ROWS+12,'TRACE',main_background+main_hi_stat_line) else show_str(10,MAX_PATTERN_ROWS+12,'TRACE',main_background+main_stat_line); If debugging and (play_status <> isStopped) then show_str(16,MAX_PATTERN_ROWS+12,'DEBUG',main_background+main_hi_stat_line) else show_str(16,MAX_PATTERN_ROWS+12,'DEBUG',main_background+main_stat_line); tracking_indicator_attr[TRUE] := main_background+main_hi_stat_line; If (play_status = isPlaying) and tracing then If track_notes_ins then tracking_indicator_attr[FALSE] := main_behavior SHL 4 AND $0f0 else tracking_indicator_attr[FALSE] := main_hi_stat_line SHL 4 AND $0f0 else tracking_indicator_attr[FALSE] := main_background+main_stat_line; If track_notes then begin If jump_mark_mode and mark_lines then attr := main_background+main_dis_stat_line else attr := main_background+main_hi_stat_line; show_cstr(22,MAX_PATTERN_ROWS+12,'NRECM~:'#30+CHR(ORD('0')+rec_correction)+'~', tracking_indicator_attr[_NRECM_blink_flag], attr); end else If debugging and (play_status = isStopped) then show_str(22,MAX_PATTERN_ROWS+12,'TRACKiNG',main_background+main_hi_stat_line) else show_str(22,MAX_PATTERN_ROWS+12,'TRACKiNG',main_background+main_stat_line); If linefeed and NOT (command_typing = 0) then show_str(MAX_COLUMNS-16,MAX_PATTERN_ROWS+12,#127,main_background+main_behavior) else show_str(MAX_COLUMNS-16,MAX_PATTERN_ROWS+12,#127,main_background+main_behavior_dis); If jump_mark_mode then show_str(MAX_COLUMNS-15,MAX_PATTERN_ROWS+12,#23,main_background+main_behavior) else show_str(MAX_COLUMNS-15,MAX_PATTERN_ROWS+12,#23,main_background+main_behavior_dis); end; function last_chan_pos: Byte; begin If (songdata.nm_tracks > MAX_TRACKS) then last_chan_pos := max(16,songdata.nm_tracks-MAX_TRACKS+1) else last_chan_pos := 1; end; function last_hpos: Byte; begin last_hpos := max(_pattedit_lastpos,songdata.nm_tracks*(_pattedit_lastpos DIV MAX_TRACKS)); end; procedure PATTERN_page_refresh(page: Byte); var attr: Word; temp,temp1,temp2,temp3,attr2,attr3: Byte; chan_attr: Byte; {$IFNDEF GO32V2} chanrec_indicator_attr: array[Boolean] of Byte; {$ENDIF} temps: String; spos,epos: Byte; dummy_str: String[1]; dummy_atr: Byte; chunk: tCHUNK; _row_bckg, _row_bckg2, _row_fgnd: Byte; _no_block_tracing: Boolean; function PRED1(value: Longint): Longint; begin If (value > 1) then PRED1 := PRED(value) else PRED1 := 1; end; procedure _set_attr(chan: Byte; chunk: tCHUNK; _bckg,_fix_note,_note,_note0,_note_hid,_inst,_inst0: Byte; var attr: Word; var attr2: Byte); begin If (chunk.note <> 0) then If (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then attr := attr+(_bckg+_fix_note) SHL 8 else attr := attr+(_bckg+_note) SHL 8 else attr := attr+(_bckg+_note0) SHL 8; If (chunk.instr_def <> 0) then attr2 := _bckg+_inst else attr2 := _bckg+_inst0; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_page_refresh'; {$ENDIF} For temp := SUCC(songdata.nm_tracks) to MAX_TRACKS do begin show_str(08+(temp-1)*15,10,patt_tab_str[0], pattern_bckg+pattern_border); show_str(11+(temp-1)*15,09,ExpStrL('',10,' '), pattern_bckg+pattern_border); end; PATTERN_tabs_refresh; If (page > PRED(songdata.patt_len)) then page := PRED(songdata.patt_len); If (pattern_page > PRED(songdata.patt_len)) then pattern_page := PRED(songdata.patt_len); While NOT ((chan_pos <= last_chan_pos) and (pattern_hpos <= last_hpos)) do If (pattern_hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); If (pattern_hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(pattern_hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(pattern_hpos,temp); end else If (chan_pos > 1) then begin Dec(chan_pos); If (pattern_hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(pattern_hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(pattern_hpos,temp); end else If cycle_pattern then begin chan_pos := last_chan_pos; pattern_hpos := last_hpos; end; If (page < PRED(MAX_PATTERN_ROWS DIV 2)) then spos := PRED(MAX_PATTERN_ROWS DIV 2)-page else spos := 0; If (page > INTEGER(PRED(songdata.patt_len))-PRED(MAX_PATTERN_ROWS DIV 2)-1) then epos := page-(INTEGER(PRED(songdata.patt_len))-PRED(MAX_PATTERN_ROWS DIV 2)-1) else epos := 0; If (spos <> 0) or (epos <> 0) then For temp2 := chan_pos to chan_pos+MAX_TRACKS-1 do begin If (temp2-PRED(chan_pos) <> MAX_TRACKS) then dummy_str := #179 else dummy_str := ''; If (spos <> 0) then For temp3 := 1 to spos do begin show_str(03,10+temp3,ExpStrL('',4,' ')+#186,pattern_bckg+pattern_border); show_str(MAX_COLUMNS-8,10+temp3,#186+ExpStrL('',4,' '),pattern_bckg+pattern_border); show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp3,ExpStrL('',14,' ')+ dummy_str,pattern_bckg+pattern_border); end; If (epos <> 0) then For temp3 := MAX_PATTERN_ROWS downto MAX_PATTERN_ROWS-epos+1 do begin show_str(03,10+temp3,ExpStrL('',4,' ')+#186,pattern_bckg+pattern_border); show_str(MAX_COLUMNS-8,10+temp3,#186+ExpStrL('',4,' '),pattern_bckg+pattern_border); show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp3,ExpStrL('',14,' ')+ dummy_str,pattern_bckg+pattern_border); end; end; _no_block_tracing := discard_block or (tracing and (pattern_patt <> tracing_block_pattern)); show_str(17+(MAX_COLUMNS-19) DIV 2,08,byte2hex(pattern_patt),pattern_bckg+pattern_border); For temp1 := 1+spos to MAX_PATTERN_ROWS-epos do begin If tracing and (play_status <> isStopped) then begin If (temp1 <> MAX_PATTERN_ROWS DIV 2) then _row_bckg := BYTE_NULL else begin _row_bckg := pattern_row_bckg_p; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_line_p; end end else If NOT ((pattern_patt = current_pattern) and (page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1 = current_line) and (play_status <> isStopped)) then _row_bckg := BYTE_NULL else begin _row_bckg := pattern_row_bckg_p; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_line_p; end; If NOT ((mark_line <> 0) and mark_lines) then begin If (temp1 <> MAX_PATTERN_ROWS DIV 2) or (marking and (NOT _no_block_tracing or discard_block)) then begin If (temp1 <> MAX_PATTERN_ROWS DIV 2) then begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_line; end; show_cstr(03,10+temp1,' '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~ '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_border; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17+'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end; end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_row_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_hi_line; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17+'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end; end else begin If (temp1 <> MAX_PATTERN_ROWS DIV 2) or (marking and (NOT _no_block_tracing or discard_block)) then If ((page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1 = 0) or ((page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1) MOD mark_line = 0)) and (mark_line <> 0) then begin If NOT marking or (marking and NOT discard_block and _no_block_tracing) then begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_row_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_hi_line; end; show_cstr(03,10+temp1,' '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~ '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else If (temp1 <> MAX_PATTERN_ROWS DIV 2) then begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_hi_line; end; show_cstr(03,10+temp1,' '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~ '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_border; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17+'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end; end else If (temp1 <> MAX_PATTERN_ROWS DIV 2) then begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_line; end; show_cstr(03,10+temp1,' '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~ '+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+' ', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_bckg; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_border; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17+'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end else begin If (_row_bckg = BYTE_NULL) then begin _row_bckg := pattern_row_bckg_m; _row_bckg2 := pattern_bckg; _row_fgnd := pattern_hi_line_m; end; show_cstr(03,10+temp1,#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17'~'#186'~', _row_bckg+_row_fgnd, _row_bckg2+pattern_border); show_cstr(MAX_COLUMNS-8,10+temp1,'~'#186'~'#16+byte2hex(page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1)+#17, _row_bckg+_row_fgnd, _row_bckg2+pattern_border); end; end; For temp2 := chan_pos to chan_pos+MAX_TRACKS-1 do begin get_chunk(pattern_patt,page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1,temp2,chunk); If marking and ( (NOT tracing and is_in_block(temp2,page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1, count_channel(pattern_hpos),page)) or (NOT discard_block and tracing and NOT _no_block_tracing and is_in_block(temp2,page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1, tracing_block_xend,tracing_block_yend)) or (discard_block and (temp2 = block_xstart) and (page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1 = block_ystart))) then begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then attr := pattern_block_bckg+pattern_cmnd_b else attr := pattern_block_bckg+pattern_cmnd0_b; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then attr3 := pattern_block_bckg+pattern_cmnd_b else attr3 := pattern_block_bckg+pattern_cmnd0_b; _set_attr(temp2,chunk,pattern_block_bckg,pattern_fix_note_b, pattern_note_b,pattern_note0_b,pattern_note_hid_b, pattern_inst_b,pattern_inst0_b,attr,attr2); end else If (NOT marking or (marking and NOT discard_block and _no_block_tracing)) and (temp1 = 1+PRED(MAX_PATTERN_ROWS DIV 2)) then begin If NOT ((mark_line <> 0) and mark_lines) then begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then attr := pattern_row_bckg+pattern_hi_cmnd else attr := pattern_row_bckg+pattern_hi_cmnd0; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then attr3 := pattern_row_bckg+pattern_hi_cmnd else attr3 := pattern_row_bckg+pattern_hi_cmnd0; _set_attr(temp2,chunk,pattern_row_bckg,pattern_hi_fx_note, pattern_hi_note,pattern_hi_note0,pattern_hi_note_h, pattern_hi_inst,pattern_hi_inst0,attr,attr2); end else begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then attr := pattern_row_bckg_m+pattern_cmnd_m else attr := pattern_row_bckg_m+pattern_cmnd0_m; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then attr3 := pattern_row_bckg_m+pattern_cmnd_m else attr3 := pattern_row_bckg_m+pattern_cmnd0_m; _set_attr(temp2,chunk,pattern_row_bckg_m,pattern_fix_note_m, pattern_note_m,pattern_note0_m,pattern_note_hid_m, pattern_inst_m,pattern_inst0_m,attr,attr2); end; end else If ((page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1 = 0) or ((page+temp1-PRED(MAX_PATTERN_ROWS DIV 2)-1) MOD mark_line = 0)) and (mark_line <> 0) and (NOT marking or (marking and NOT discard_block and _no_block_tracing)) and mark_lines then begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then attr := pattern_row_bckg+pattern_hi_cmnd else attr := pattern_row_bckg+pattern_hi_cmnd0; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then attr3 := pattern_row_bckg+pattern_hi_cmnd else attr3 := pattern_row_bckg+pattern_hi_cmnd0; _set_attr(temp2,chunk,pattern_row_bckg,pattern_hi_fx_note, pattern_hi_note,pattern_hi_note0,pattern_hi_note_h, pattern_hi_inst,pattern_hi_inst0,attr,attr2); end else begin If NOT ((chunk.effect_def = 0) and (chunk.effect = 0)) then begin If NOT highlight_controls or NOT ((chunk.effect_def in [ef_PositionJump, ef_PatternBreak, ef_SetSpeed, ef_SetTempo]) or ((chunk.effect_def = ef_Extended) and (chunk.effect DIV 16 in [ef_ex_PatternLoop, ef_ex_PatternLoopRec]))) then attr := pattern_bckg+pattern_cmnd else attr := pattern_bckg+pattern_cmnd_ctrl end else attr := pattern_bckg+pattern_cmnd0; If NOT ((chunk.effect_def2 = 0) and (chunk.effect2 = 0)) then begin If NOT highlight_controls or NOT ((chunk.effect_def2 in [ef_PositionJump, ef_PatternBreak, ef_SetSpeed, ef_SetTempo]) or ((chunk.effect_def2 = ef_Extended) and (chunk.effect2 DIV 16 in [ef_ex_PatternLoop, ef_ex_PatternLoopRec]))) then attr3 := pattern_bckg+pattern_cmnd else attr3 := pattern_bckg+pattern_cmnd_ctrl end else attr3 := pattern_bckg+pattern_cmnd0; _set_attr(temp2,chunk,pattern_bckg,pattern_fix_note, pattern_note,pattern_note0,pattern_note_hid, pattern_inst,pattern_inst0,attr,attr2); end; dummy_atr := attr3 AND $0f0+pattern_border; If (temp2-PRED(chan_pos) <> MAX_TRACKS) and (NOT (marking and (temp2 >= block_x1)) or (marking and _no_block_tracing)) then begin dummy_str := #179; If marking and discard_block then dummy_atr := pattern_bckg+pattern_border; end else If marking and (temp2-PRED(chan_pos) <> MAX_TRACKS) and NOT _no_block_tracing then begin dummy_str := #179; dummy_atr := pattern_bckg+pattern_border; end else dummy_str := ''; If (temp2 > max(chan_pos+MAX_TRACKS-1,songdata.nm_tracks)) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,' ',HI(attr)) else Case pattern_layout of 0: Case chunk.note of 0: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#250#250#250' ',HI(attr)); 1..12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note]+' ',HI(attr)); fixed_note_flag+ 1.. fixed_note_flag+ 12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note-fixed_note_flag]+' ',HI(attr)); BYTE_NULL: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#254#254#254' ',HI(attr)); end; 1: Case chunk.note of 0: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#250#250#250' ',HI(attr)); 1..12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note]+' ',HI(attr)); fixed_note_flag+ 1.. fixed_note_flag+ 12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note-fixed_note_flag]+' ',HI(attr)); BYTE_NULL: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#205#205#205' ',HI(attr)); end; 2: Case chunk.note of 0: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,#250#250#250' ',HI(attr)); 1..12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note]+' ',HI(attr)); fixed_note_flag+ 1.. fixed_note_flag+ 12*8+1: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,note_layout[chunk.note-fixed_note_flag]+' ',HI(attr)); BYTE_NULL: show_str(08+pos3[(temp2-PRED(chan_pos))*4-3],10+temp1,'^^'#250' ',HI(attr)); end; end; If (temp2 > max(chan_pos+MAX_TRACKS-1,songdata.nm_tracks)) then begin show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1,' ',attr2); show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1,' ',LO(attr)); show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4], 10+temp1,' '+ #10+dummy_str+#10,attr3,dummy_atr); end else Case pattern_layout of 0: begin If (chunk.instr_def = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1,#249#249' ',attr2) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1, ExpStrL(Num2str(chunk.instr_def,16),2,#249)+' ',attr2); If (chunk.effect_def = 0) and (chunk.effect = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1,#250#250#250' ',LO(attr)) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1, fx_digits[chunk.effect_def]+byte2hex(chunk.effect)+' ',LO(attr)); If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1,#250#250#250+ #10+dummy_str+#10,attr3,dummy_atr) else show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1, fx_digits[chunk.effect_def2]+byte2hex(chunk.effect2)+ #10+dummy_str+#10,attr3,dummy_atr); end; 1: begin If (chunk.instr_def = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1,#250#250' ',attr2) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1, ExpStrL(Num2str(chunk.instr_def,16),2,#250)+' ',attr2); If (chunk.effect_def = 0) and (chunk.effect = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1,#249#249#249' ',LO(attr)) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1, fx_digits[chunk.effect_def]+byte2hex(chunk.effect)+' ',LO(attr)); If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1,#249#249#249+ #10+dummy_str+#10,attr3,dummy_atr) else show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1, fx_digits[chunk.effect_def2]+byte2hex(chunk.effect2)+ #10+dummy_str+#10,attr3,dummy_atr); end; 2: begin If (chunk.instr_def = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1,#250#250' ',attr2) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-2],10+temp1, ExpStrL(Num2str(chunk.instr_def,16),2,#250)+' ',attr2); If (chunk.effect_def = 0) and (chunk.effect = 0) then show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1,#250#249#249' ',LO(attr)) else show_str(08+pos3[(temp2-PRED(chan_pos))*4-1],10+temp1, fx_digits[chunk.effect_def]+byte2hex(chunk.effect)+' ',LO(attr)); If (chunk.effect_def2 = 0) and (chunk.effect2 = 0) then show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1,#250#249#249+ #10+dummy_str+#10,attr3,dummy_atr) else show_cstr_alt(08+pos3[(temp2-PRED(chan_pos))*4],10+temp1, fx_digits[chunk.effect_def2]+byte2hex(chunk.effect2)+ #10+dummy_str+#10,attr3,dummy_atr); end; end; end; end; {$IFNDEF GO32V2} chanrec_indicator_attr[TRUE] := main_behavior SHL 4 AND $0f0; If (play_status = isPlaying) then chanrec_indicator_attr[FALSE] := pattern_bckg+pattern_border else chanrec_indicator_attr[FALSE] := main_behavior SHL 4 AND $0f0; {$ENDIF} STATUS_LINE_refresh; For temp1 := chan_pos to chan_pos+MAX_TRACKS-1 do begin If NOT is_4op_chan(temp1) then temps := '~ ~'+ExpStrR(Num2str(temp1,10),2,' ')+'~ ~' else If (temp1 in _4op_tracks_hi) then temps := '~'#244'~'+ExpStrR(Num2str(temp1,10),2,' ')+'~ ~' else temps := '~'#245'~'+ExpStrR(Num2str(temp1,10),2,' ')+'~ ~'; {$IFNDEF GO32V2} If opl3_channel_recording_mode and opl3_record_channel[temp1] then chan_attr := chanrec_indicator_attr[_NRECM_blink_flag] else {$ENDIF} If track_notes and (temp1 >= track_chan_start) and (temp1 <= track_chan_start+nm_track_chan-1) then chan_attr := main_behavior SHL 4 and $0f0 else chan_attr := pattern_bckg+pattern_border; show_cstr(08+(temp1-PRED(chan_pos)-1)*15,09,temps, chan_attr, pattern_bckg+pattern_4op_indic); end; If scroll_bars then begin scroll_pos2 := vscroll_bar(MAX_COLUMNS-2,08,MAX_PATTERN_ROWS+4,PRED1(songdata.patt_len), page,scroll_pos2, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos3 := hscroll_bar(MAX_COLUMNS-14,MAX_PATTERN_ROWS+12,13,PRED1(songdata.nm_tracks),PRED(count_channel(pattern_hpos)), scroll_pos3, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); If (pattern_patt <= PRED(max_patterns)) then scroll_pos4 := vscroll_bar(MAX_COLUMNS-1,08,MAX_PATTERN_ROWS+4,PRED(max_patterns), pattern_patt,scroll_pos4, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_2nd_mark) else scroll_pos4 := vscroll_bar(MAX_COLUMNS-1,08,MAX_PATTERN_ROWS+4,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); end else begin scroll_pos2 := vscroll_bar(MAX_COLUMNS-2,08,MAX_PATTERN_ROWS+4,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos3 := hscroll_bar(MAX_COLUMNS-14,MAX_PATTERN_ROWS+12,13,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); scroll_pos4 := vscroll_bar(MAX_COLUMNS-1,08,MAX_PATTERN_ROWS+4,1,1,BYTE_NULL, scrollbar_bckg+scrollbar_text, scrollbar_bckg+scrollbar_mark); end; end; procedure PATTERN_position_preview(pattern,line,channel,mode: Byte); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_position_preview'; {$ENDIF} If (mode = 0) then begin old_pattern_patt := pattern_patt; old_pattern_page := pattern_page; old_pattern_hpos := pattern_hpos; old_chan_pos := chan_pos; old_block_xstart := block_xstart; old_block_ystart := block_ystart; old_marking := marking; end else If (mode = 1) then begin pattern_patt := pattern; pattern_page := line; If (channel > chan_pos+MAX_TRACKS-1) then While (channel > chan_pos+MAX_TRACKS-1) do Inc(chan_pos) else While (channel < chan_pos) do Dec(chan_pos); While (channel > chan_pos+MAX_TRACKS-1) and (chan_pos < last_chan_pos) do Inc(chan_pos); If (count_channel(pattern_hpos) < channel) then While (count_channel(pattern_hpos) <> channel) do Inc(pattern_hpos) else While (count_channel(pattern_hpos) <> channel) do Dec(pattern_hpos); While (count_pos(pattern_hpos) <> 0) do Dec(pattern_hpos); block_xstart := count_channel(pattern_hpos); block_ystart := line; marking := TRUE; cancel_note_recorder; discard_block := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (mode = BYTE_NULL) then begin pattern_patt := old_pattern_patt; pattern_page := old_pattern_page; pattern_hpos := old_pattern_hpos; chan_pos := old_chan_pos; block_xstart := old_block_xstart; block_ystart := old_block_ystart; marking := old_marking; discard_block := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; function PATTERN_trace: Word; var old_pattord_page,old_pattord_hpos,old_pattord_vpos: Byte; old_pattern_patt,old_pattern_page,old_pattern_hpos: Byte; nope,flag,reset_pos: Boolean; temp,temp2,fkey2: Word; idx,idx2,track_ch,curr_ch: Byte; patt_nm,line_nm,dif1,dif2: Byte; track_ch_key: array[1..20] of Byte; old_hpos: Byte; temps: String; chunk,chunk2: tCHUNK; procedure pause_debugging; begin If debugging then begin debugging := FALSE; replay_forbidden := TRUE; play_status := isPaused; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; label _end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_trace'; {$ENDIF} If (play_status = isStopped) then EXIT; _traceprc_last_order := BYTE_NULL; _traceprc_last_pattern := BYTE_NULL; _traceprc_last_line := BYTE_NULL; HideCursor; old_pattord_page := pattord_page; old_pattord_hpos := pattord_hpos; old_pattord_vpos := pattord_vpos; old_pattern_patt := pattern_patt; old_pattern_page := pattern_page; old_pattern_hpos := pattern_hpos; reset_pos := TRUE; tracing := TRUE; If marking then begin tracing_block_pattern := pattern_patt; tracing_block_xend := count_channel(pattern_hpos); tracing_block_yend := pattern_page; end; Repeat nope := FALSE; trace_update_proc; If ctrl_pressed and alt_pressed then begin DEBUG_INFO; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; old_hpos := pattern_hpos; If keypressed then fkey2 := getkey else If NOT (seconds_counter >= ssaver_time) then GOTO _end //CONTINUE else begin screen_saver; GOTO _end; //CONTINUE; end; If track_notes and midiboard then begin curr_ch := track_chan_start; track_ch := 0; flag := FALSE; FillChar(track_ch_key,SizeOf(track_ch_key),BYTE_NULL); If NOT ctrl_pressed and NOT alt_pressed then For idx := 1 to 29 do If (scankey(board_scancodes[idx])) then begin flag := TRUE; If (track_ch < nm_track_chan) then Inc(track_ch) else BREAK; track_ch_key[track_ch] := idx; end; If (fkey2 = kWeird) or (flag AND track_notes) then begin idx2 := 1; For idx := 1 to nm_track_chan do begin If (fkey2 = kWeird) or ((track_ch_key[idx2] <> BYTE_NULL) and (track_ch_key[idx2]+12*(current_octave-1) in [1..12*8+1])) then begin If NOT (jump_mark_mode and mark_lines) and (rec_correction <> 0) then begin patt_nm := HI(play_pos_buf[rec_correction]); line_nm := LO(play_pos_buf[rec_correction]); end else begin patt_nm := current_pattern; line_nm := current_line; end; If (jump_mark_mode and mark_lines and (line_nm MOD mark_line <> 0)) then begin dif1 := line_nm; While (dif1 MOD mark_line <> 0) and (dif1 <= songdata.patt_len) do Inc(dif1); If (dif1 > songdata.patt_len) then dif1 := 0; dif2 := line_nm; While (dif2 MOD mark_line <> 0) and (dif2 > 0) do Dec(dif2); If (Abs(dif1-line_nm) <= Abs(line_nm-dif2)) then line_nm := dif1 else line_nm := dif2; end; get_chunk(patt_nm,line_nm,curr_ch+idx-1,chunk); If (fkey2 <> kWeird) then begin If NOT right_shift_pressed then chunk.note := track_ch_key[idx2]+12*(current_octave-1) else chunk.note := track_ch_key[idx2]+12*(current_octave-1)+fixed_note_flag; If NOT (chunk.effect_def in [ef_TonePortamento, ef_TPortamVolSlide]) then begin If track_notes_ins then chunk.instr_def := current_inst else chunk.instr_def := min(voice_table[curr_ch+idx-1],1); If is_4op_chan(curr_ch+idx-1) and (curr_ch+idx-1 in _4op_tracks_lo) then begin get_chunk(patt_nm,line_nm,PRED(curr_ch)+idx-1,chunk2); chunk2.note := 0; If NOT track_notes or track_notes_ins then If (HI(get_4op_to_test) <> 0) then chunk2.instr_def := HI(get_4op_to_test) else chunk2.instr_def := current_inst else chunk2.instr_def := min(voice_table[PRED(curr_ch)+idx-1],1); If channel_flag[PRED(curr_ch)+idx-1] then put_chunk(patt_nm,line_nm,PRED(curr_ch)+idx-1,chunk2); end else If is_4op_chan(curr_ch+idx-1) and (curr_ch+idx-1 in _4op_tracks_hi) then begin get_chunk(patt_nm,line_nm,SUCC(curr_ch)+idx-1,chunk2); chunk2.note := 0; If NOT track_notes or track_notes_ins then If (LO(get_4op_to_test) <> 0) then chunk2.instr_def := LO(get_4op_to_test) else chunk2.instr_def := current_inst else chunk2.instr_def := min(voice_table[SUCC(curr_ch)+idx-1],1); If channel_flag[SUCC(curr_ch)+idx-1] then put_chunk(patt_nm,line_nm,SUCC(curr_ch)+idx-1,chunk2); end; end; end else begin chunk.note := BYTE_NULL; chunk.instr_def := 0; end; If channel_flag[curr_ch+idx-1] and NOT ignore_note_once[curr_ch+idx-1] then begin ignore_note_once[curr_ch+idx-1] := TRUE; put_chunk(patt_nm,line_nm,curr_ch+idx-1,chunk); If (patt_nm <> current_pattern) or (line_nm <= current_line) then begin If (chunk.instr_def <> 0) then load_instrument(songdata.instr_data[chunk.instr_def],curr_ch+idx-1); If is_4op_chan(curr_ch+idx-1) then If (curr_ch+idx-1 in _4op_tracks_lo) then begin get_chunk(patt_nm,line_nm,PRED(curr_ch)+idx-1,chunk2); load_instrument(songdata.instr_data[chunk2.instr_def],PRED(curr_ch)+idx-1); end else begin get_chunk(patt_nm,line_nm,SUCC(curr_ch)+idx-1,chunk2); load_instrument(songdata.instr_data[chunk2.instr_def],SUCC(curr_ch)+idx-1); end; If (chunk.note <> BYTE_NULL) then output_note(chunk.note AND $7f,chunk.instr_def,curr_ch+idx-1,TRUE,TRUE); end; Inc(idx2); end; If (play_status = isPaused) then begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; end; end; end; keyboard_reset_buffer; end; end; Case fkey2 of kCtLbr: If NOT shift_pressed then If (current_inst > 1) then begin If NOT (marked_instruments = 2) then begin Dec(current_inst); reset_marked_instruments; end else If NOT ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then Dec(current_inst) else While (current_inst > 1) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) do Dec(current_inst); instrum_page := current_inst; keyboard_reset_buffer; end; kCtRbr: If NOT shift_pressed then If (current_inst < 255) then begin If NOT (marked_instruments = 2) then begin Inc(current_inst); reset_marked_instruments; end else If NOT ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then Inc(current_inst) else While (current_inst < 255) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) do Inc(current_inst); instrum_page := current_inst; keyboard_reset_buffer; end; kAstrsk, kNPastr: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} For temp := 1 to songdata.nm_tracks do begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltL: begin pause_debugging; LINE_MARKING_SETUP; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltM: If (mark_line <> 0) then begin mark_lines := NOT mark_lines; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltS: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) and NOT track_notes then {$ELSE} If NOT track_notes then {$ENDIF} begin For temp := 1 to songdata.nm_tracks do channel_flag[temp] := FALSE; For temp := 1 to songdata.nm_tracks do If (temp = count_channel(pattern_hpos)) then begin channel_flag[temp] := TRUE; If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then channel_flag[SUCC(temp)] := TRUE else channel_flag[PRED(temp)] := TRUE; end; For temp := 1 to songdata.nm_tracks do If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltR: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} FillChar(channel_flag,songdata.nm_tracks,BYTE(TRUE)); kAlt1.. kAlt0: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} If (fkey2 <> kAlt0) then begin If shift_pressed then temp := HI(fkey2)-$77+10 else temp := HI(fkey2)-$77; If (temp <= songdata.nm_tracks) then begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then begin channel_flag[SUCC(temp)] := channel_flag[temp]; If NOT channel_flag[SUCC(temp)] then reset_chan_data(SUCC(temp)); end else begin channel_flag[PRED(temp)] := channel_flag[temp]; If NOT channel_flag[PRED(temp)] then reset_chan_data(PRED(temp)); end; end; end else If shift_pressed or (10 in [chan_pos..chan_pos+MAX_TRACKS-1]) or (songdata.nm_tracks = 10) then begin channel_flag[10] := NOT channel_flag[10]; If NOT channel_flag[10] then reset_chan_data(10); If is_4op_chan(10) then begin channel_flag[11] := channel_flag[10]; If NOT channel_flag[11] then reset_chan_data(11); end; end else begin If NOT percussion_mode then temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$1~6~$1~7~$1~8~$1~9~$2~0~$' else temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$16 ~B~D$17 ~S~D$18 ~T~T$19 T~C~$20 ~H~H$'; temps := FlipStr(temps); For temp := 10 to 20 do If (temp > songdata.nm_tracks) then begin Delete(temps,Pos('~',temps),1); Delete(temps,Pos('~',temps),1); end; temps := FlipStr(temps); If (Pos('~',temps) <> 0) then begin chpos := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO TOGGLE TRACK ON/OFF$', temps, ' TRACK ON/OFF ',chpos); If (dl_environment.keystroke <> kESC) then begin channel_flag[9+chpos] := NOT channel_flag[9+chpos]; If NOT channel_flag[9+chpos] then reset_chan_data(9+chpos); If is_4op_chan(9+chpos) then If (9+chpos in [10,12,14]) then begin channel_flag[SUCC(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[SUCC(9+chpos)] then reset_chan_data(SUCC(9+chpos)); end else If (9+chpos in [11,13,15]) then begin channel_flag[PRED(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[PRED(9+chpos)] then reset_chan_data(PRED(9+chpos)); end; end; end; end; kUP: If shift_pressed and track_notes then If NOT (jump_mark_mode and mark_lines) and (rec_correction < 9) then Inc(rec_correction) else else If NOT shift_pressed and (track_notes or (NOT debugging and (play_status = isPlaying))) then rewind := TRUE; kDOWN: If shift_pressed and track_notes then If NOT (jump_mark_mode and mark_lines) and (rec_correction > 0) then Dec(rec_correction) else else If NOT shift_pressed and (track_notes or (NOT debugging and (play_status = isPlaying))) then fast_forward := TRUE; kCtLEFT: If track_notes then If NOT debugging and (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If track_notes then If NOT debugging and (play_status = isPlaying) then fast_forward := TRUE; kLEFT, kShTAB: If NOT track_notes then If (chan_pos > 1) then begin Dec(chan_pos); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (pattern_hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kRIGHT, kTAB: If NOT track_notes then If (chan_pos < last_chan_pos) then begin Inc(chan_pos); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (pattern_hpos <= last_hpos-_pattedit_lastpos DIV MAX_TRACKS) then begin Inc(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kCHmins, kNPmins, kCtHOME: If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp > 0) and NOT (songdata.pattern_order[temp-1] < $80) do begin Dec(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp > 0) then begin Dec(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (fkey2 = kCtHOME) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCHplus, kNPplus, kCtEND: If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp < $7f) and (songdata.pattern_order[SUCC(temp)] > $80) do begin Inc(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp < $7f) then begin Inc(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (fkey2 = kCtEND) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCtENTR: If play_single_patt then begin current_line := 0; PATTERN_ORDER_page_refresh(0); PATTERN_page_refresh(0); end else begin no_status_refresh := TRUE; fade_out_playback(FALSE); If (current_order < $7f) and (play_status <> isStopped) then If (songdata.pattern_order[SUCC(current_order)] < $80) then calibrate_player(SUCC(current_order),0,FALSE,FALSE) else If (calc_following_order(SUCC(current_order)) <> -1) then calibrate_player(calc_following_order(SUCC(current_order)),0,FALSE,FALSE) else else If (calc_following_order(0) <> -1) then calibrate_player(calc_following_order(0),0,FALSE,FALSE); no_status_refresh := FALSE; end; kCtrlT: begin pause_debugging; TRANSPOSE; keyboard_reset_buffer; end; kCtrlR: begin pause_debugging; REMAP; keyboard_reset_buffer; end; kCtrlB: begin pause_debugging; MESSAGE_BOARD; keyboard_reset_buffer; end; kCtrlD: begin pause_debugging; DEBUG_INFO; keyboard_reset_buffer; end; kCtrlO: begin pause_debugging; OCTAVE_CONTROL; keyboard_reset_buffer; end; kCtrlP: begin pause_debugging; If NOT ((play_status <> isStopped) and tracing) then PATTERN_LIST(pattern_patt+1) else begin PATTERN_LIST(old_pattern_patt+1); old_pattern_patt := pattern_list__page-1; end; keyboard_reset_buffer; end; kCtrlF: begin cancel_note_recorder; pause_debugging; SONG_VARIABLES; keyboard_reset_buffer; end; kCtrlH: begin pause_debugging; REPLACE; keyboard_reset_buffer; end; kCtrlI: begin pause_debugging; INSTRUMENT_CONTROL; keyboard_reset_buffer; end; kCtrlE: begin pause_debugging; INSTRUMENT_CONTROL_edit; keyboard_reset_buffer; end; kCtrlQ: begin pause_debugging; MACRO_EDITOR(current_inst,FALSE); keyboard_reset_buffer; end; kCtrlG: begin pause_debugging; MACRO_EDITOR(current_inst,TRUE); keyboard_reset_buffer; end; kCtrlM: begin pause_debugging; MACRO_BROWSER(TRUE,TRUE); keyboard_reset_buffer; end; kCtrlX: begin pause_debugging; REARRANGE; keyboard_reset_buffer; end; kF1: begin pause_debugging; {$IFDEF GO32V2} If track_notes then HELP('note_recorder') {$ELSE} If (sdl_opl3_emulator = 1) and ((play_status = isPlaying) or opl3_channel_recording_mode) then HELP('wav_recorder') else If track_notes then HELP('note_recorder') {$ENDIF} else HELP('general'); keyboard_reset_buffer; end; kF2, kShF2, kCtrlS: begin pause_debugging; If (fkey2 = kShF2) then quick_cmd := TRUE; FILE_save('a2m'); quick_cmd := FALSE; keyboard_reset_buffer; end; kCtrlF2: begin pause_debugging; FILE_save('a2t'); keyboard_reset_buffer; end; kF3, kShF3, kCtrlL: begin pause_debugging; If (fkey2 = kShF3) then quick_cmd := TRUE; FILE_open('*.a2m$*.a2t$*.a2p$*.amd$*.cff$*.dfm$*.fmk$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); quick_cmd := FALSE; keyboard_reset_buffer; end; kF4, kCtrlA: NUKE; kSPACE: If ctrl_pressed then begin {$IFNDEF GO32V2} If NOT opl3_channel_recording_mode then {$ENDIF} If NOT track_notes then track_notes := TRUE else cancel_note_recorder; If track_notes then begin track_notes_ins := TRUE; If debugging then begin debugging := FALSE; stop_playing; end; track_chan_start := count_channel(pattern_hpos); midiboard := TRUE; end; fkey2 := WORD_NULL; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If track_notes then If alt_pressed then track_notes_ins := FALSE else track_notes_ins := TRUE else If (play_status = isPaused) and NOT track_notes then begin debugging := TRUE; replay_forbidden := FALSE; play_status := isPlaying; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kF10: begin QUIT_request; If (fkey = kESC) then begin fkey2 := kF10; nope := TRUE; end; end; kENTER, kESC: begin nope := TRUE; debugging := FALSE; If (fkey2 = kESC) and track_notes then cancel_note_recorder else begin If (fkey2 = kENTER) or (shift_pressed and (fkey2 = kESC)) then begin reset_pos := FALSE; If (fkey2 = kENTER) then begin replay_forbidden := TRUE; play_status := isPaused; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; end; kF5, kAltF5, kShF5: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; If (NOT nosync_by_default and (fkey2 = kAltF5)) or (nosync_by_default and (fkey2 = kF5)) then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey2 = kAltF5)) or (nosync_by_default and (fkey2 = kF5)) then no_sync_playing := TRUE; end; end; kF6: Case play_status of isPlaying: begin If NOT debugging then begin replay_forbidden := TRUE; play_status := isPaused; end; debugging := FALSE; end; isPaused: begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; end; end; kShF6: begin If track_notes then cancel_note_recorder; debugging := TRUE; replay_forbidden := FALSE; play_status := isPlaying; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kF7: begin fade_out_playback(FALSE); debugging := FALSE; stop_playing; nope := TRUE; If (play_status <> isStopped) then FillChar(ai_table,SizeOf(ai_table),0); end; kF8, kAltF8, kShF8: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := FALSE; If (NOT nosync_by_default and (fkey2 = kAltF8)) or (nosync_by_default and (fkey2 = kF8)) then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; repeat_pattern := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey2 = kAltF8)) or (nosync_by_default and (fkey2 = kF8)) then no_sync_playing := TRUE; end; end; kF9, kAltF9, kShF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If (NOT nosync_by_default and (fkey2 = kAltF9)) or (nosync_by_default and (fkey2 = kF8)) then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey2 = kAltF9)) or (nosync_by_default and (fkey2 = kF9)) then no_sync_playing := TRUE; end; end; end; If track_notes and (pattern_hpos <> old_hpos) then cancel_note_recorder; _end: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} If scankey(SC_F11) and NOT ctrl_pressed and NOT alt_pressed and NOT shift_pressed then begin If (command_typing <> 0) then Case command_typing of 1: If cycle_pattern then begin command_typing := 2; cycle_pattern := FALSE; end else cycle_pattern := TRUE; 2: begin command_typing := 1; cycle_pattern := FALSE; end; end; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; If scankey(SC_F12) and NOT ctrl_pressed and NOT alt_pressed then begin If NOT shift_pressed then linefeed := NOT linefeed else jump_mark_mode := NOT jump_mark_mode; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; until (nope or (play_status = isStopped)) or _force_program_quit; PATTERN_trace := fkey2; If (fkey2 = kF10) or _force_program_quit then EXIT; ThinCursor; tracing := FALSE; If (play_status <> isStopped) then cancel_note_recorder; If nope and reset_pos then begin pattord_page := old_pattord_page; pattord_hpos := old_pattord_hpos; pattord_vpos := old_pattord_vpos; pattern_patt := old_pattern_patt; pattern_page := old_pattern_page; pattern_hpos := old_pattern_hpos; end; debugging := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; procedure _save_pattern_to_undo; begin pattern_undo_flag := TRUE; pattern_undo_patt := pattern_patt; Move(pattdata^[pattern_undo_patt DIV 8][pattern_undo_patt MOD 8], pattern_undo_data, SizeOf(pattern_undo_data)); end; procedure _restore_pattern_from_undo; begin If pattern_undo_flag then begin Move(pattern_undo_data, pattdata^[pattern_undo_patt DIV 8][pattern_undo_patt MOD 8], SizeOf(pattern_undo_data)); pattern_undo_flag := FALSE; end; end; procedure PATTERN_edit(var pattern,page,hpos: Byte); var temp1,temp2,temp3,fkey_X: Word; temp,chan: Byte; tstr,temps: String; nope: Boolean; chunk,chunk2: tCHUNK; old_order,old_pattern,old_line: Byte; old_speed,old_tempo: Byte; old_patt_page: Byte; flag,flag2: Boolean; idx,idx2,track_ch,curr_ch: Byte; track_ch_key: array[1..20] of Byte; old_hpos: Byte; function correct_range(fxdef: Byte; var fxdata: Byte): Boolean; var result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit:correct_range'; {$ENDIF} result := FALSE; Case fxdef of ef_Arpeggio, ef_FSlideUp, ef_FSlideDown, ef_FSlideUpFine, ef_FSlideDownFine, ef_FSlideUpVSlide, ef_FSlUpVSlF, ef_FSlideDownVSlide, ef_FSlDownVSlF, ef_FSlUpFineVSlide, ef_FSlUpFineVSlF, ef_FSlDownFineVSlide, ef_FSlDownFineVSlF, ef_TonePortamento, ef_TPortamVolSlide, ef_TPortamVSlideFine, ef_Vibrato, ef_VibratoVolSlide, ef_VibratoVSlideFine, ef_VolSlide, ef_VolSlideFine, ef_ArpggVSlide, ef_ArpggVSlideFine, ef_Tremolo, ef_Tremor, ef_ExtraFineVibrato, ef_ExtraFineTremolo, ef_SwapArpeggio, ef_SwapVibrato, ef_SetCustomSpeedTab, ef_GlobalFSlideUp, ef_GlobalFSlideDown: result := TRUE; ef_SetSpeed, ef_SetTempo, ef_ExtraFineArpeggio, ef_RetrigNote, ef_MultiRetrigNote: If (fxdata in [1..255]) then result := TRUE else If (command_typing <> 0) then begin If (fxdef <> ef_MultiRetrigNote) then fxdata := 1 else fxdata := $10; result := TRUE; end; ef_SetCarrierVol, ef_SetModulatorVol, ef_SetInsVolume, ef_ForceInsVolume, ef_SetGlobalVolume: If (fxdata in [0..63]) then result := TRUE else If (command_typing <> 0) then begin fxdata := 0; result := TRUE; end; ef_PatternBreak: result := TRUE; ef_PositionJump: If (fxdata in [0..127]) then result := TRUE else If (command_typing <> 0) then begin fxdata := 0; result := TRUE; end; ef_SetWaveform: If (fxdata DIV 16 in [0..7,$0f]) and (fxdata MOD 16 in [0..7,$0f]) then result := TRUE else If (command_typing <> 0) then begin If (fxdata DIV 16 in [0..7,$0f]) then fxdata := fxdata AND $f0 else If (fxdata MOD 16 in [0..7,$0f]) then fxdata := fxdata AND $0f else fxdata := 0; result := TRUE; end; ef_Extended: If (fxdata in [$00..$01,$10..$11, $20..$2f,$30..$3f, $40..$4f,$50..$5f, $60..$6f,$70..$7f, $80..$8f,$90..$9f, $a0..$a7,$b0..$b2, $c0..$cf,$d0..$df, $e0..$e7,$f0..$ff]) then result := TRUE else If (command_typing <> 0) then begin fxdata := fxdata AND $f0; result := TRUE; end; ef_Extended2: If (fxdata in [$01..$0f,$11..$1f, $21..$2f,$31..$3f, $41..$4f,$51..$5f, $61..$6f,$71..$7f, $81..$8f,$91..$9f, $a1..$af,$b1..$bf, $c1..$cf,$d1..$df, $e1..$ef,$f1..$ff]) then result := TRUE else If (command_typing <> 0) then begin fxdata := fxdata AND $f0+1; result := TRUE; end; ef_Extended3: If (fxdata in [$00..$01,$10..$1f, $20..$23,$30..$31, $40..$41,$50..$51, $60..$61,$70..$7f, $80..$83,$90..$91, $a0..$a1,$b0..$b1, $c0..$c1]) then result := TRUE else If (command_typing <> 0) then begin If (fxdata DIV 16 in [0..$0c]) then fxdata := fxdata AND $f0+1 else fxdata := 1; result := TRUE; end; end; correct_range := result; end; procedure copy_object; var chan: Byte; temp1,temp2: Word; temp3: tCOPY_OBJECT; chunk: tCHUNK; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit:copy_object'; {$ENDIF} chan := count_channel(hpos); If clipboard.object_type in [ objPatternDef,objPatternTable, objInstrument,objInstrumentBank, objNote,objInstrumentDef,objEffect,objEffect2, objLine,objTrack,objPattern,objMarkedBlock] then begin temp3 := clipboard.object_type; FillChar(clipboard,SizeOf(clipboard),0); clipboard.object_type := temp3; end; Case clipboard.object_type of objNote, objInstrumentDef, objEffect, objEffect2: begin get_chunk(pattern,page,chan,chunk); clipboard.pattern[1][0] := chunk; end; objLine: For temp1 := 1 to songdata.nm_tracks do begin get_chunk(pattern,page,temp1,chunk); clipboard.pattern[temp1][0] := chunk; end; objTrack: For temp1 := 0 to PRED(songdata.patt_len) do begin get_chunk(pattern,temp1,chan,chunk); clipboard.pattern[1][temp1] := chunk; end; objPattern: begin For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp2,temp1,chunk); clipboard.pattern[temp1][temp2] := chunk; end; clipboard._string := Copy(songdata.pattern_names[pattern],9,33); end; objMarkedBlock: begin clipboard.block_hsize := block_x1-block_x0; clipboard.block_vsize := block_y1-block_y0; For temp2 := block_y0 to block_y1 do For temp1 := block_x0 to block_x1 do begin get_chunk(pattern,temp2,temp1,chunk); clipboard.pattern[SUCC(temp1-block_x0)][temp2-block_y0] := chunk; end; end; end; end; procedure paste_object; var chan: Byte; temp1,temp2: Word; chunk: tCHUNK; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit:paste_object'; {$ENDIF} _save_pattern_to_undo; chan := count_channel(hpos); Case clipboard.object_type of objNote: begin get_chunk(pattern,page,chan,chunk); chunk.note := clipboard.pattern[1][0].note; put_chunk(pattern,page,chan,chunk); If linefeed then If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; end; objInstrumentDef: begin get_chunk(pattern,page,chan,chunk); chunk.instr_def := clipboard.pattern[1][0].instr_def; put_chunk(pattern,page,chan,chunk); If linefeed then If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; end; objEffect: begin get_chunk(pattern,page,chan,chunk); chunk.effect_def := clipboard.pattern[1][0].effect_def; chunk.effect := clipboard.pattern[1][0].effect; put_chunk(pattern,page,chan,chunk); If linefeed then If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; end; objEffect2: begin get_chunk(pattern,page,chan,chunk); chunk.effect_def2 := clipboard.pattern[1][0].effect_def2; chunk.effect2 := clipboard.pattern[1][0].effect2; put_chunk(pattern,page,chan,chunk); If linefeed then If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; end; objLine: begin For temp1 := 1 to songdata.nm_tracks do put_chunk(pattern,page,temp1, clipboard.pattern[temp1][0]); If linefeed then If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; end; objTrack: For temp1 := 0 to PRED(songdata.patt_len) do put_chunk(pattern,temp1,chan, clipboard.pattern[1][temp1]); objPattern: begin For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do put_chunk(pattern,temp2,temp1, clipboard.pattern[temp1][temp2]); songdata.pattern_names[pattern] := Copy(songdata.pattern_names[pattern],1,8)+ clipboard._string; end; objMarkedBlock: If shift_pressed then begin For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do If (temp1 <= songdata.nm_tracks) and (temp2 <= PRED(songdata.patt_len)) then begin get_chunk(pattern,temp2,temp1,chunk); If (command_typing <> 0) then Case count_pos(hpos) of 0, 1: chunk.note := clipboard.pattern[SUCC(temp1-chan)][temp2-page].note; 2, 3: chunk.instr_def := clipboard.pattern[SUCC(temp1-chan)][temp2-page].instr_def; 4,5, 6: begin chunk.effect_def := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect_def; chunk.effect := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect; end; 7,8, 9: begin chunk.effect_def2 := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect_def2; chunk.effect2 := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect2; end; end else Case count_pos(hpos) of 0: chunk.note := clipboard.pattern[SUCC(temp1-chan)][temp2-page].note; 1: chunk.instr_def := clipboard.pattern[SUCC(temp1-chan)][temp2-page].instr_def; 2: begin chunk.effect_def := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect_def; chunk.effect := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect; end; 3: begin chunk.effect_def2 := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect_def2; chunk.effect2 := clipboard.pattern[SUCC(temp1-chan)][temp2-page].effect2; end; end; put_chunk(pattern,temp2,temp1,chunk); end; end else For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do If (temp1 <= songdata.nm_tracks) and (temp2 <= PRED(songdata.patt_len)) then put_chunk(pattern,temp2,temp1, clipboard.pattern[SUCC(temp1-chan)][temp2-page]); end; end; procedure paste_object_alt(pattern: Byte); var temp1,temp2: Word; chunk: tCHUNK; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit:paste_object_alt'; {$ENDIF} Case clipboard.object_type of objNote: begin get_chunk(pattern,page,chan,chunk); chunk.note := clipboard.pattern[1][0].note; put_chunk(pattern,page,chan,chunk); end; objInstrumentDef: begin get_chunk(pattern,page,chan,chunk); chunk.instr_def := clipboard.pattern[1][0].instr_def; put_chunk(pattern,page,chan,chunk); end; objEffect: begin get_chunk(pattern,page,chan,chunk); chunk.effect_def := clipboard.pattern[1][0].effect_def; chunk.effect := clipboard.pattern[1][0].effect; put_chunk(pattern,page,chan,chunk); end; objEffect2: begin get_chunk(pattern,page,chan,chunk); chunk.effect_def2 := clipboard.pattern[1][0].effect_def2; chunk.effect2 := clipboard.pattern[1][0].effect2; put_chunk(pattern,page,chan,chunk); end; objLine: begin For temp1 := 1 to songdata.nm_tracks do put_chunk(pattern,page,temp1, clipboard.pattern[temp1][0]); end; objTrack: For temp1 := 0 to PRED(songdata.patt_len) do put_chunk(pattern,temp1,chan, clipboard.pattern[1][temp1]); objPattern: For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to songdata.nm_tracks do put_chunk(pattern,temp2,temp1, clipboard.pattern[temp1][temp2]); objMarkedBlock: For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do If (temp1 <= songdata.nm_tracks) and (temp2 <= PRED(songdata.patt_len)) then put_chunk(pattern,temp2,temp1, clipboard.pattern[SUCC(temp1-chan)][temp2-page]); end; end; function FX(chr: Char): Byte; begin FX := PRED(Pos(UpCase(chr),fx_digits)); end; function update_block_volume(block_x0,block_y0,block_x1,block_y1: Byte; volume_commands: tByteSet; shift: Integer; var fx_found_flag: Boolean; update_values: Boolean): Boolean; var temp1,temp2: Byte; begin _save_pattern_to_undo; fx_found_flag := FALSE; For temp2 := block_y0 to block_y1 do For temp1 := block_x0 to block_x1 do begin get_chunk(pattern,temp2,temp1,chunk); If (chunk.effect_def in volume_commands) then begin fx_found_flag := TRUE; If (shift >= 0) then If (chunk.effect+shift <= 63) then Inc(chunk.effect,shift) else begin update_block_volume := FALSE; EXIT; end else If (chunk.effect+shift >= 0) then Inc(chunk.effect,shift) else begin update_block_volume := FALSE; EXIT; end; end; If (chunk.effect_def2 in volume_commands) then begin fx_found_flag := TRUE; If (shift >= 0) then If (chunk.effect2+shift <= 63) then Inc(chunk.effect2,shift) else begin update_block_volume := FALSE; EXIT; end else If (chunk.effect2+shift >= 0) then Inc(chunk.effect2,shift) else begin update_block_volume := FALSE; EXIT; end; end; If update_values then put_chunk(pattern,temp2,temp1,chunk); end; update_block_volume := fx_found_flag; end; procedure enter_debug_mode(pattern,page: Byte); begin cancel_note_recorder; If NOT replay_forbidden then begin debugging := TRUE; play_status := isPlaying; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If NOT play_single_patt and (calc_pattern_pos(pattern) <> BYTE_NULL) then begin fade_out_playback(FALSE); calibrate_player(calc_pattern_pos(pattern),page,TRUE,TRUE); If (play_status <> isStopped) then begin debugging := TRUE; play_status := isPlaying; replay_forbidden := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else If (calc_pattern_pos(pattern) = BYTE_NULL) then begin fade_out_playback(FALSE); play_single_patt := TRUE; no_sync_playing := TRUE; start_pattern := pattern_patt; start_line := pattern_page; start_playing; debugging := TRUE; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; label _end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:PATTERN_edit'; {$ENDIF} fkey_X := WORD_NULL; chan := count_channel(hpos); Repeat If (page > PRED(songdata.patt_len)) then page := PRED(songdata.patt_len); While NOT ((chan_pos <= last_chan_pos) and (hpos <= last_hpos)) do If (hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(hpos,_pattedit_lastpos DIV MAX_TRACKS); If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end else If (chan_pos > 1) then begin Dec(chan_pos); If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end else If cycle_pattern then begin chan_pos := last_chan_pos; hpos := last_hpos; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(page); If (command_typing <> 0) then GotoXY(08+pos4[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)) else GotoXY(08+pos3[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)); If tracing then fkey := PATTERN_trace else ThinCursor; nope := FALSE; If ctrl_pressed and alt_pressed then begin DEBUG_INFO; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; old_patt_page := page; old_hpos := hpos; If keypressed then fkey := getkey else If NOT (seconds_counter >= ssaver_time) then GOTO _end //CONTINUE else begin screen_saver; GOTO _end; //CONTINUE; end; If (fkey <> kAltQ) then quick_mark_type := 0; If NOT shift_pressed and NOT (marking and ((fkey = kAltC) or (fkey = kCtrlN) or (fkey = kCtrlB) or (fkey = kCtrlD) or (fkey = kCtrlC) or (fkey = kCtrlV) or (fkey = kCtrlX) or (fkey = kCtPgUP) or (fkey = kCtrlM) or (fkey = kCtPgDN) or (fkey = kCtrlT) or (fkey = kCtrlR) or (fkey = kCtrlH) or (fkey = kAltQ) or (fkey = kCtrlD) or (fkey = kCtrlZ) or (fkey = kAltM) or (fkey = kAltL) or (fkey = kF5) or (fkey = kAltF5) or (fkey = kF6) or (fkey = kAltF6) or (fkey = kF7) or (fkey = kF8) or (fkey = kAltF8) or (fkey = kCtrlF8) or (fkey = kF9) or (fkey = kAltF9) or (fkey = kCtrlF9) or (fkey = kCtLeft) or (fkey = kCtRght) or (fkey = kCtENTR) or (fkey = kAltB) or (fkey = kAltV) or (fkey = kCHmins) or (fkey = kNPplus) or (fkey = kNPmins))) or (shift_pressed and NOT ((fkey = kLEFT) or (fkey = kRIGHT) or (fkey = kUP) or (fkey = kDOWN) or (fkey = kPgUP) or (fkey = kPgDOWN) or (fkey = kNPPgUP) or (fkey = kNPPgDN) or (fkey = kHOME) or (fkey = kEND) or (fkey = kNPHOME) or (fkey = kNPEND) or (marking and ((fkey = kAltF5) or (fkey = kShF5) or (fkey = kAltF6) or (fkey = kShF6) or (fkey = kAltF8) or (fkey = kShF8) or (fkey = kCtrlF8) or (fkey = kAltF9) or (fkey = kShF9) or (fkey = kCtrlF9) or (fkey = kCtLEFT) or (fkey = kCtRGHT) or (fkey = kCHplus))) or (fkey = kCtENTR))) then begin If marking and NOT (((fkey = kENTER) and shift_pressed) or (fkey = kF1)) then begin old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; fkey := WORD_NULL; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(page); If (command_typing <> 0) then GotoXY(08+pos4[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)) else GotoXY(08+pos3[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2)); end; end else If NOT marking and NOT track_notes and (fkey <> kPgUP) and (fkey <> kPgDOWN) and (fkey <> kNPPgUP) and (fkey <> kNPPgDN) and (fkey <> kHOME) and (fkey <> kEND) and (fkey <> kNPHOME) and (fkey <> kNPEND) then begin old_chan_pos := chan_pos; old_hpos := hpos; old_page := page; marking := TRUE; cancel_note_recorder; fkey := WORD_NULL; block_xstart := chan; block_ystart := page; end; Case fkey of kCHlbrk, kCtLbr: If NOT shift_pressed then If (current_inst > 1) then begin If NOT (marked_instruments = 2) then begin Dec(current_inst); reset_marked_instruments; end else If NOT ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then Dec(current_inst) else While (current_inst > 1) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) do Dec(current_inst); instrum_page := current_inst; keyboard_reset_buffer; end; kCHrbrk, kCtRbr: If NOT shift_pressed then If (current_inst < 255) then begin If NOT (marked_instruments = 2) then begin Inc(current_inst); reset_marked_instruments; end else If NOT ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) then Inc(current_inst) else While (current_inst < 255) and ((current_inst = HI(get_4op_to_test)) or (current_inst = LO(get_4op_to_test))) do Inc(current_inst); instrum_page := current_inst; keyboard_reset_buffer; end; kLEFT: If marking then begin If (hpos > _pattedit_lastpos DIV MAX_TRACKS) then Dec(hpos,_pattedit_lastpos DIV MAX_TRACKS) else If (chan_pos > 1) then Dec(chan_pos); end else If hpos > 1 then Dec(hpos) else If (chan_pos > 1) then begin Dec(chan_pos); hpos := _pattedit_lastpos DIV MAX_TRACKS; end else If cycle_pattern then begin chan_pos := last_chan_pos; hpos := last_hpos; end; kRIGHT: If marking then begin If (hpos <= last_hpos-_pattedit_lastpos DIV MAX_TRACKS) then Inc(hpos,_pattedit_lastpos DIV MAX_TRACKS) else If (chan_pos < last_chan_pos) then Inc(chan_pos); end else If hpos < last_hpos then Inc(hpos) else If (chan_pos < last_chan_pos) then begin Inc(chan_pos); hpos := last_hpos-PRED(_pattedit_lastpos DIV MAX_TRACKS); end else If cycle_pattern then begin chan_pos := 1; hpos := 1; end; kUP: If shift_pressed and track_notes then If NOT (jump_mark_mode and mark_lines) and (rec_correction < 9) then Inc(rec_correction) else else If (page > 0) then Dec(page) else If NOT marking and cycle_pattern then page := PRED(songdata.patt_len); kDOWN: If shift_pressed and track_notes then If NOT (jump_mark_mode and mark_lines) and (rec_correction > 0) then Dec(rec_correction) else else If (page < PRED(songdata.patt_len)) then Inc(page) else If NOT marking and cycle_pattern then page := 0; kCHplus, kNPplus: If NOT marking then If pattern < PRED(max_patterns) then Inc(pattern) else else begin If update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetInsVolume,ef_ForceInsVolume],+1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetInsVolume,ef_ForceInsVolume],+1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetModulatorVol],+1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetModulatorVol],+1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetCarrierVol],+1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetCarrierVol],+1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetGlobalVolume],+1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetGlobalVolume],+1,flag2,TRUE); PATTERN_page_refresh(pattern_page); end; kCHmins, kNPmins: If NOT marking then If pattern > 0 then Dec(pattern) else else begin If update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetInsVolume,ef_ForceInsVolume],-1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetInsVolume,ef_ForceInsVolume],-1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetModulatorVol],-1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetModulatorVol],-1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetCarrierVol],-1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetCarrierVol],-1,flag2,TRUE) else If NOT flag2 and update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetGlobalVolume],-1,flag2,FALSE) then update_block_volume(block_x0,block_y0,block_x1,block_y1, [ef_SetGlobalVolume],-1,flag2,TRUE); PATTERN_page_refresh(pattern_page); end; kPgUP: If NOT shift_pressed or marking then begin If page > max(16,songdata.patt_len) then Dec(page,max(16,songdata.patt_len)) else page := 0; end else If pattern > 0 then Dec(pattern); kPgDOWN: If NOT shift_pressed or marking then begin If page < PRED(songdata.patt_len)-max(16,songdata.patt_len) then Inc(page,max(16,songdata.patt_len)) else page := PRED(songdata.patt_len); end else If pattern < PRED(max_patterns) then Inc(pattern); kNPUp, kNPDown: If NumLock then nope := TRUE; kNPPgUP: If NumLock then nope := TRUE else If shift_pressed then If NOT marking and (pattern > 0) then Dec(pattern) else If marking then begin If page > max(16,songdata.patt_len) then Dec(page,max(16,songdata.patt_len)) else page := 0; end; kNPPgDN: If NumLock then nope := TRUE else If shift_pressed then If NOT marking and (pattern < PRED(max_patterns)) then Inc(pattern) else If marking then begin If page < PRED(songdata.patt_len)-max(16,songdata.patt_len) then Inc(page,max(16,songdata.patt_len)) else page := PRED(songdata.patt_len); end; kCtHOME: If pattern > 0 then begin Dec(pattern); page := PRED(songdata.patt_len); end; kCtEND: If pattern < PRED(max_patterns) then begin Inc(pattern); page := 0; end; kHOME: If NOT shift_pressed or marking then If (page <> 0) then page := 0 else begin chan_pos := 1; hpos := 1; end else If (chan_pos+hpos-1 <> 1) then begin chan_pos := 1; hpos := 1; end else If (page <> 0) then page := 0 else pattern := 0; kEND: If NOT shift_pressed or marking then If (page <> PRED(songdata.patt_len)) then page := PRED(songdata.patt_len) else begin chan_pos := last_chan_pos; hpos := last_hpos; end else If (chan_pos+hpos <> last_chan_pos+last_hpos) then begin chan_pos := last_chan_pos; hpos := last_hpos; end else If (page <> PRED(songdata.patt_len)) then page := PRED(songdata.patt_len) else pattern := PRED(max_patterns); kNPHOME: If NumLock then nope := TRUE else If shift_pressed then If NOT marking then begin If (chan_pos+hpos-1 <> 1) then begin chan_pos := 1; hpos := 1; end else If (page <> 0) then page := 0 else pattern := 0; end else If (page <> 0) then page := 0 else begin chan_pos := 1; hpos := 1; end; kNPEND: If NumLock then nope := TRUE else If shift_pressed then If NOT marking then begin If (chan_pos+hpos <> last_chan_pos+last_hpos) then begin chan_pos := last_chan_pos; hpos := last_hpos; end else If (page <> PRED(songdata.patt_len)) then page := PRED(songdata.patt_len) else pattern := PRED(max_patterns); end else If (page <> PRED(songdata.patt_len)) then page := PRED(songdata.patt_len) else begin chan_pos := last_chan_pos; hpos := last_hpos; end; kAstrsk, kNPastr: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} For temp1 := 1 to songdata.nm_tracks do begin channel_flag[temp1] := NOT channel_flag[temp1]; If NOT channel_flag[temp1] then reset_chan_data(temp1); end; kAltL: begin LINE_MARKING_SETUP; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltM: If (mark_line <> 0) then begin mark_lines := NOT mark_lines; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kAltS: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) and NOT track_notes then {$ELSE} If NOT track_notes then {$ENDIF} begin For temp := 1 to songdata.nm_tracks do channel_flag[temp] := FALSE; For temp := 1 to songdata.nm_tracks do If (temp = count_channel(pattern_hpos)) then begin channel_flag[temp] := TRUE; If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then channel_flag[SUCC(temp)] := TRUE else channel_flag[PRED(temp)] := TRUE; end; For temp := 1 to songdata.nm_tracks do If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltR: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} FillChar(channel_flag,songdata.nm_tracks,BYTE(TRUE)); kAlt1.. kAlt0: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} If (fkey <> kAlt0) then begin If shift_pressed then temp := HI(fkey)-$77+10 else temp := HI(fkey)-$77; If (temp <= songdata.nm_tracks) then begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then begin channel_flag[SUCC(temp)] := channel_flag[temp]; If NOT channel_flag[SUCC(temp)] then reset_chan_data(SUCC(temp)); end else begin channel_flag[PRED(temp)] := channel_flag[temp]; If NOT channel_flag[PRED(temp)] then reset_chan_data(PRED(temp)); end; end; end else If shift_pressed or (10 in [chan_pos..chan_pos+MAX_TRACKS-1]) or (songdata.nm_tracks = 10) then begin channel_flag[10] := NOT channel_flag[10]; If NOT channel_flag[10] then reset_chan_data(10); If is_4op_chan(10) then begin channel_flag[11] := channel_flag[10]; If NOT channel_flag[11] then reset_chan_data(11); end; end else begin If NOT percussion_mode then temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$1~6~$1~7~$1~8~$1~9~$2~0~$' else temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$16 ~B~D$17 ~S~D$18 ~T~T$19 T~C~$20 ~H~H$'; temps := FlipStr(temps); For temp := 10 to 20 do If (temp > songdata.nm_tracks) then begin Delete(temps,Pos('~',temps),1); Delete(temps,Pos('~',temps),1); end; temps := FlipStr(temps); If (Pos('~',temps) <> 0) then begin chpos := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO TOGGLE TRACK ON/OFF$', temps, ' TRACK ON/OFF ',chpos); If (dl_environment.keystroke <> kESC) then begin channel_flag[9+chpos] := NOT channel_flag[9+chpos]; If NOT channel_flag[9+chpos] then reset_chan_data(9+chpos); If is_4op_chan(9+chpos) then If (9+chpos in [10,12,14]) then begin channel_flag[SUCC(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[SUCC(9+chpos)] then reset_chan_data(SUCC(9+chpos)); end else If (9+chpos in [11,13,15]) then begin channel_flag[PRED(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[PRED(9+chpos)] then reset_chan_data(PRED(9+chpos)); end; end; end; end; kShTAB: If (hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(hpos,_pattedit_lastpos DIV MAX_TRACKS); If NOT keep_track_pos then begin If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end end else If (chan_pos > 1) then begin Dec(chan_pos); If NOT keep_track_pos then begin If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end end else If cycle_pattern then begin chan_pos := last_chan_pos; If NOT keep_track_pos then hpos := last_hpos; end; kTAB: If (hpos <= last_hpos-_pattedit_lastpos DIV MAX_TRACKS) then begin Inc(hpos,_pattedit_lastpos DIV MAX_TRACKS); If NOT keep_track_pos then begin If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end end else If (chan_pos < last_chan_pos) then begin Inc(chan_pos); If NOT keep_track_pos then begin If (hpos MOD (_pattedit_lastpos DIV MAX_TRACKS) > 0) then temp := PRED(hpos MOD (_pattedit_lastpos DIV MAX_TRACKS)) else temp := PRED(_pattedit_lastpos DIV MAX_TRACKS); Dec(hpos,temp); end end else If cycle_pattern then begin chan_pos := 1; If NOT keep_track_pos then hpos := 1; end; kSPACE: If ctrl_pressed and NOT shift_pressed and NOT alt_pressed then begin {$IFNDEF GO32V2} If NOT opl3_channel_recording_mode then {$ENDIF} If NOT track_notes then track_notes := TRUE else cancel_note_recorder; If track_notes and (play_status <> isStopped) then stop_playing; If track_notes then begin track_notes_ins := TRUE; If debugging then begin debugging := FALSE; stop_playing; end; track_chan_start := chan; nm_track_chan := 1; midiboard := TRUE; end; fkey := WORD_NULL; end else If track_notes then If alt_pressed then track_notes_ins := FALSE else track_notes_ins := TRUE else If NOT ctrl_pressed and shift_pressed and NOT alt_pressed then begin midiboard := NOT midiboard; fkey := WORD_NULL; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then If NOT midiboard then If page < PRED(songdata.patt_len) then If linefeed or NOT lf_in_mboard_mode then Inc(page) else else If cycle_pattern then page := 0; kINSERT: If NOT shift_pressed then begin _save_pattern_to_undo; For temp1 := PRED(songdata.patt_len)-1 downto page do begin get_chunk(pattern,temp1,chan,chunk); put_chunk(pattern,temp1+1,chan,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,page,chan,chunk); end else begin _save_pattern_to_undo; For temp1 := PRED(songdata.patt_len)-1 downto page do For temp2 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp1,temp2,chunk); put_chunk(pattern,temp1+1,temp2,chunk); end; For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,page,temp1,chunk); end; end; kDELETE: If NOT shift_pressed then begin _save_pattern_to_undo; For temp1 := page to PRED(songdata.patt_len)-1 do begin get_chunk(pattern,temp1+1,chan,chunk); put_chunk(pattern,temp1,chan,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),chan,chunk); end else begin _save_pattern_to_undo; For temp1 := page to PRED(songdata.patt_len)-1 do For temp2 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp1+1,temp2,chunk); put_chunk(pattern,temp1,temp2,chunk); end; For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),temp1,chunk); end; end; kNPins: If NumLock then nope := TRUE else If shift_pressed then begin _save_pattern_to_undo; For temp1 := PRED(songdata.patt_len)-1 downto page do For temp2 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp1,temp2,chunk); put_chunk(pattern,temp1+1,temp2,chunk); end; For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,page,temp1,chunk); end; end; kNPdel: If NumLock then nope := TRUE else If shift_pressed then begin _save_pattern_to_undo; For temp1 := page to PRED(songdata.patt_len)-1 do For temp2 := 1 to songdata.nm_tracks do begin get_chunk(pattern,temp1+1,temp2,chunk); put_chunk(pattern,temp1,temp2,chunk); end; For temp1 := 1 to songdata.nm_tracks do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),temp1,chunk); end; end; kAltB: If marking then begin old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; chan_pos := old_chan_pos; hpos := old_hpos; page := old_page; marking := FALSE; end else begin old_chan_pos := chan_pos; old_hpos := hpos; old_page := page; hpos := old_block_patt_hpos; page := old_block_patt_page; chan_pos := old_block_chan_pos; marking := TRUE; cancel_note_recorder; end; kAltQ: If track_notes then If (old_nm_track_chan <> 0) and (old_track_chan_start <> 0) and (old_track_chan_start+old_nm_track_chan-1 <= songdata.nm_tracks) then begin nm_track_chan := old_nm_track_chan; track_chan_start := old_track_chan_start; chan_pos := track_chan_start; hpos := 1; While (chan < chan_pos) do Inc(hpos); old_hpos := hpos; end else else Case quick_mark_type of 0: begin old_chan_pos := chan_pos; old_hpos := hpos; old_page := page; page := 0; marking := TRUE; cancel_note_recorder; block_xstart := chan; block_ystart := PRED(songdata.patt_len); quick_mark_type := 1; end; 1: begin marking := TRUE; cancel_note_recorder; chan_pos := 1; hpos := 1; page := 0; block_xstart := songdata.nm_tracks; block_ystart := PRED(songdata.patt_len); quick_mark_type := 2; end; 2: begin old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; chan_pos := old_chan_pos; hpos := old_hpos; page := old_page; marking := FALSE; quick_mark_type := 0; end; end; kCtrlK: If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,pattern_page,track_chan_start+idx-1,chunk); chunk.note := BYTE_NULL; chunk.instr_def := 0; put_chunk(pattern,pattern_page,track_chan_start+idx-1,chunk); keyboard_reset_buffer; end; If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; end else begin get_chunk(pattern,pattern_page,chan,chunk); chunk.note := BYTE_NULL; chunk.instr_def := 0; put_chunk(pattern,pattern_page,chan,chunk); If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; end; kBkSPC: If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,pattern_page,track_chan_start+idx-1,chunk); If (command_typing <> 0) then Case count_pos(hpos) of 0, 1: begin chunk.note := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; If midiboard then begin chunk.instr_def := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; end; end; 2, 3: begin chunk.instr_def := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; end; 4,5, 6: begin chunk.effect_def := 0; chunk.effect := 0; end; 7,8, 9: begin chunk.effect_def2 := 0; chunk.effect2 := 0; end; end else Case count_pos(hpos) of 0: begin chunk.note := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; If midiboard then begin chunk.instr_def := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; end; end; 1: begin chunk.instr_def := 0; If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(track_chan_start+idx-1),chunk2); end else If is_4op_chan(track_chan_start+idx-1) and (track_chan_start+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(track_chan_start+idx-1),chunk2); end; end; 2: begin chunk.effect_def := 0; chunk.effect := 0; end; 3: begin chunk.effect_def2 := 0; chunk.effect2 := 0; end; end; put_chunk(pattern,pattern_page,track_chan_start+idx-1,chunk); end; Case backspace_dir of 1: If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; 2: If page > 0 then Dec(page) else If cycle_pattern then page := PRED(songdata.patt_len); end; end else begin get_chunk(pattern,pattern_page,chan,chunk); If (command_typing <> 0) then Case count_pos(hpos) of 0, 1: begin chunk.note := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; If midiboard then begin chunk.instr_def := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; end; end; 2, 3: begin chunk.instr_def := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; end; 4,5, 6: begin chunk.effect_def := 0; chunk.effect := 0; end; 7,8, 9: begin chunk.effect_def2 := 0; chunk.effect2 := 0; end; end else Case count_pos(hpos) of 0: begin chunk.note := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; If midiboard then begin chunk.instr_def := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; end; end; 1: begin chunk.instr_def := 0; If is_4op_chan(chan) and (chan in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,PRED(chan),chunk2); end else If is_4op_chan(chan) and (chan in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(chan),chunk2); chunk2.note := 0; chunk2.instr_def := 0; put_chunk(pattern,pattern_page,SUCC(chan),chunk2); end; end; 2: begin chunk.effect_def := 0; chunk.effect := 0; end; 3: begin chunk.effect_def2 := 0; chunk.effect2 := 0; end; end; put_chunk(pattern,pattern_page,chan,chunk); Case backspace_dir of 1: If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; 2: If page > 0 then Dec(page) else If cycle_pattern then page := PRED(songdata.patt_len); end; end; kCtPgUP: begin _save_pattern_to_undo; If marking then transpose_custom_area(ttTransposeUp, ttTransposeAllIns, pattern,pattern,block_x0,block_x1,block_y0,block_y1, 1) else transpose_custom_area(ttTransposeUp, ttTransposeAllIns, pattern,pattern,chan,chan,page,page, 1); end; kCtPgDN: begin _save_pattern_to_undo; If marking then transpose_custom_area(ttTransposeDown, ttTransposeAllIns, pattern,pattern,block_x0,block_x1,block_y0,block_y1, 1) else transpose_custom_area(ttTransposeDown, ttTransposeAllIns, pattern,pattern,chan,chan,page,page, 1); end; kCtrlC: begin If marking then clipboard.object_type := objMarkedBlock else If (command_typing <> 0) then Case count_pos(hpos) of 0, 1: clipboard.object_type := objNote; 2, 3: clipboard.object_type := objInstrumentDef; 4,5, 6: clipboard.object_type := objEffect; 7,8, 9: clipboard.object_type := objEffect2; end else Case count_pos(hpos) of 0: clipboard.object_type := objNote; 1: clipboard.object_type := objInstrumentDef; 2: clipboard.object_type := objEffect; 3: clipboard.object_type := objEffect2; end; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; copy_object; end; kAltP: If shift_pressed then begin temp := PATTERN_LIST_alt(pattern_list__page); If (temp <> BYTE_NULL) then If (_patts_marked <> 0) then begin For temp := 0 to PRED(max_patterns) do If (songdata.pattern_names[temp][1] <> ' ') then paste_object_alt(temp); end else paste_object_alt(temp-1); end else paste_object; kCtrlV: paste_object; kAltV: If (clipboard.object_type = objMarkedBlock) then begin _save_pattern_to_undo; If NOT shift_pressed then For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do begin get_chunk(pattern,temp2,temp1,chunk); If (chunk.note = 0) then begin chunk.note := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].note; chunk.instr_def := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].instr_def; end; If (chunk.effect_def = 0) then chunk.effect_def := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].effect_def; If (chunk.effect = 0) then chunk.effect := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].effect; If (chunk.effect_def2 = 0) then chunk.effect_def2 := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].effect_def2; If (chunk.effect2 = 0) then chunk.effect2 := clipboard.pattern[SUCC(temp1-chan)] [temp2-page].effect2; put_chunk(pattern,temp2,temp1,chunk); end else For temp2 := page to page+clipboard.block_vsize do For temp1 := chan to chan+clipboard.block_hsize do put_chunk(pattern,temp2,temp1, clipboard.pattern[SUCC(temp1-chan)][clipboard.block_vsize-(temp2-page)]); end; kCtrlZ: _restore_pattern_from_undo; kCtrlX: If NOT marking then REARRANGE else begin _save_pattern_to_undo; clipboard.object_type := objMarkedBlock; clipboard.block_hsize := block_x1-block_x0; clipboard.block_vsize := block_y1-block_y0; For temp2 := block_y0 to block_y1 do For temp1 := block_x0 to block_x1 do begin get_chunk(pattern,temp2,temp1,chunk); clipboard.pattern[SUCC(temp1-block_x0)] [temp2-block_y0] := chunk; end; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; For temp2 := block_x0 to block_x1 do For temp1 := block_y0 to block_y1 do begin For temp3 := block_y0 to PRED(songdata.patt_len) do begin get_chunk(pattern,temp3+1,temp2,chunk); put_chunk(pattern,temp3,temp2,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),temp2,chunk); end; end; kCtrlN: If marking then begin _save_pattern_to_undo; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; For temp2 := block_y0 to block_y1 do For temp1 := block_x0 to block_x1 do begin FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,temp2,temp1,chunk); end; end; kAltC: begin mn_setting.cycle_moves := TRUE; If NOT marking then copy_menu_str2[12] := copy_marked_str[1] else copy_menu_str2[12] := copy_marked_str[2]; temp1 := Menu(copy_menu_str2,01,01,copypos2,30,15,15,' COPY OBJECT '); If (mn_environment.keystroke <> kESC) then begin copypos2 := temp1; If marking and (tCOPY_OBJECT(temp1) = objMarkedBlock) then clipboard.object_type := objMarkedBlock else If (tCOPY_OBJECT(temp1) <> objMarkedBlock) then clipboard.object_type := tCOPY_OBJECT(temp1) else GOTO _end; //CONTINUE; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; copy_object; end; end; kCtrlB: If NOT marking then MESSAGE_BOARD else begin _save_pattern_to_undo; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; For temp2 := block_x0 to block_x1 do For temp1 := block_y0 to block_y1 do begin For temp3 := PRED(songdata.patt_len)-1 downto block_y0 do begin get_chunk(pattern,temp3,temp2,chunk); put_chunk(pattern,temp3+1,temp2,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,block_y0,temp2,chunk); end; end; kCtrlD: If NOT marking then DEBUG_INFO else begin _save_pattern_to_undo; old_block_chan_pos := chan_pos; old_block_patt_hpos := hpos; old_block_patt_page := page; marking := FALSE; For temp2 := block_x0 to block_x1 do For temp1 := block_y0 to block_y1 do begin For temp3 := block_y0 to PRED(songdata.patt_len)-1 do begin get_chunk(pattern,temp3+1,temp2,chunk); put_chunk(pattern,temp3,temp2,chunk); end; FillChar(chunk,SizeOf(chunk),0); put_chunk(pattern,PRED(songdata.patt_len),temp2,chunk); end; end; kCtrlT: TRANSPOSE; kCtrlR: REMAP; kCtrlO: OCTAVE_CONTROL; kCtrlP: If NOT ((play_status <> isStopped) and tracing) then PATTERN_LIST(pattern_patt+1) else begin PATTERN_LIST(old_pattern_patt+1); old_pattern_patt := pattern_list__page-1; end; kCtrlF: begin cancel_note_recorder; SONG_VARIABLES; end; kCtrlH: REPLACE; kCtrlI: INSTRUMENT_CONTROL; kCtrlE: INSTRUMENT_CONTROL_edit; kCtrlQ: MACRO_EDITOR(current_inst,FALSE); kCtrlG: MACRO_EDITOR(current_inst,TRUE); kCtrlM: MACRO_BROWSER(TRUE,TRUE); kCtLEFT: If track_notes then begin If (track_chan_start = chan) and (nm_track_chan > 1) then Dec(nm_track_chan) else If (track_chan_start > chan_pos) then begin Dec(track_chan_start); Inc(nm_track_chan); end; end else If NOT debugging and (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If track_notes then begin If (track_chan_start = chan) and (track_chan_start+nm_track_chan-chan_pos < max(MAX_TRACKS,songdata.nm_tracks)) then Inc(nm_track_chan) else If (track_chan_start < chan) then begin Inc(track_chan_start); Dec(nm_track_chan); end; end else If (play_status = isPlaying) then fast_forward := TRUE; kCtENTR: If play_single_patt then current_line := 0 else begin no_status_refresh := TRUE; fade_out_playback(FALSE); If (current_order < $7f) and (play_status <> isStopped) then If (songdata.pattern_order[SUCC(current_order)] < $80) then calibrate_player(SUCC(current_order),0,FALSE,FALSE) else If (calc_following_order(SUCC(current_order)) <> -1) then calibrate_player(calc_following_order(SUCC(current_order)),0,FALSE,FALSE) else else If debugging and (play_status = isStopped) then enter_debug_mode(SUCC(pattern),0); no_status_refresh := FALSE; end; kF1: begin If marking then temps := 'block_operations' else If NOT (command_typing <> 0) and (count_pos(hpos) in [2,3]) then temps := 'effects_page1' else If (command_typing <> 0) and (count_pos(hpos) in [4..9]) then temps := 'effects_page1' else If debugging and (play_status = isStopped) then temps := 'midiboard' else temps := 'pattern_editor'; {$IFDEF GO32V2} If track_notes then HELP('note_recorder') {$ELSE} If NOT marking and (sdl_opl3_emulator = 1) and opl3_channel_recording_mode then HELP('wav_recorder') else If track_notes then HELP('note_recorder') {$ENDIF} else begin get_chunk(pattern,page,chan,chunk); If NOT marking and ((NOT (command_typing <> 0) and (count_pos(hpos) = 2)) or ((command_typing <> 0) and (count_pos(hpos) in [4,5,6]))) then temp1 := chunk.effect_def+(chunk.effect DIV 16) SHL 8 else If NOT marking and ((NOT (command_typing <> 0) and (count_pos(hpos) = 3)) or ((command_typing <> 0) and (count_pos(hpos) in [7,8,9]))) then temp1 := chunk.effect_def2+(chunk.effect2 DIV 16) SHL 8 else temp1 := WORD_NULL; If (temp1 <> WORD_NULL) then Case LO(temp1) of ef_Arpeggio..ef_SetWaveform: temps := 'effects_page1'; ef_VolSlideFine..ef_FSlDownFineVSlF: temps := 'effects_page2'; ef_Extended: Case HI(temp1) of ef_ex_SetTremDepth..ef_ex_PatternLoopRec: temps := 'effects_page3' else temps := 'effects_page4'; end; ef_Extended3: temps := 'effects_page5'; ef_Extended2: temps := 'effects_page6'; else temps := 'effects_page7'; end; HELP(temps); end; end; kF2, kShF2, kCtrlS: begin If (fkey = kShF2) then quick_cmd := TRUE; FILE_save('a2m'); quick_cmd := FALSE; end; kAltF2: FILE_save('a2p'); kCtrlF2: FILE_save('a2t'); kF3, kShF3, kCtrlL: begin If (fkey = kShF3) then quick_cmd := TRUE; FILE_open('*.a2m$*.a2t$*.a2p$*.amd$*.cff$*.dfm$*.fmk$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); quick_cmd := FALSE; end; kF4, kCtrlA: NUKE; kF5, kAltF5, kShF5: begin cancel_note_recorder; If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; isStopped: begin If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; start_playing; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF5)) or (nosync_by_default and (fkey = kF5)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; end; kF6: Case play_status of isPlaying: begin replay_forbidden := TRUE; play_status := isPaused; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; end; end; kShF6: enter_debug_mode(pattern,page); kAltF6: If NOT play_single_patt then begin start_pattern := pattern; play_single_patt := TRUE; no_sync_playing := TRUE; start_playing; repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; kF7: begin fade_out_playback(FALSE); stop_playing; If (play_status <> isStopped) then FillChar(ai_table,SizeOf(ai_table),0); end; kF8, kAltF8, kShF8: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin stop_playing; debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; calibrate_player(calc_pattern_pos(pattern),0,TRUE,FALSE); repeat_pattern := FALSE; end; end; isStopped: If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; calibrate_player(calc_pattern_pos(pattern),0,TRUE,FALSE); repeat_pattern := FALSE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF8)) or (nosync_by_default and (fkey = kF8)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kCtrlF8: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := FALSE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin stop_playing; calibrate_player(calc_pattern_pos(pattern),pattern_page,TRUE,FALSE); end; end; isStopped: If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin debugging := FALSE; calibrate_player(calc_pattern_pos(pattern),pattern_page,TRUE,FALSE); repeat_pattern := FALSE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end end; isPaused: begin debugging := FALSE; repeat_pattern := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF9, kAltF9, kShF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin stop_playing; calibrate_player(calc_pattern_pos(pattern),0,TRUE,FALSE); repeat_pattern := TRUE; end; end; isStopped: If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin debugging := FALSE; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; calibrate_player(calc_pattern_pos(pattern),0,TRUE,FALSE); repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If (NOT nosync_by_default and (fkey = kAltF9)) or (nosync_by_default and (fkey = kF9)) then no_sync_playing := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kCtrlF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin stop_playing; calibrate_player(calc_pattern_pos(pattern),pattern_page,TRUE,FALSE); repeat_pattern := TRUE; end; end; isStopped: If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin debugging := FALSE; calibrate_player(calc_pattern_pos(pattern),pattern_page,TRUE,FALSE); repeat_pattern := TRUE; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If (shift_pressed and NOT trace_by_default) or (NOT shift_pressed and trace_by_default) then begin temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end; end; end; kF10, kESC: begin If (fkey = kESC) and track_notes then cancel_note_recorder else begin QUIT_request; If (fkey = kESC) then nope := TRUE; end; end; kENTER: If NOT shift_pressed then nope := TRUE else begin _save_pattern_to_undo; If marking then For temp2 := block_x0 to block_x1 do For temp1 := block_y0 to block_y1 do begin get_chunk(pattern,temp1,temp2,chunk); If (chunk.note in [1..12*8+1]) then chunk.note := chunk.note+fixed_note_flag else If (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then chunk.note := chunk.note-fixed_note_flag; put_chunk(pattern,temp1,temp2,chunk); end else begin get_chunk(pattern,page,chan,chunk); If (chunk.note in [1..12*8+1]) then chunk.note := chunk.note+fixed_note_flag else If (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then chunk.note := chunk.note-fixed_note_flag; put_chunk(pattern,page,chan,chunk); end; end; else If NOT scankey(SC_F11) and NOT scankey(SC_F12) then nope := TRUE; end; If (nope or (fkey = kSPACE) or (fkey = kWeird)) and midiboard then begin nope := FALSE; If track_notes then curr_ch := track_chan_start else curr_ch := chan; track_ch := 0; flag := FALSE; FillChar(track_ch_key,SizeOf(track_ch_key),BYTE_NULL); If NOT ctrl_pressed and NOT alt_pressed then For idx := 1 to 29 do If (scankey(board_scancodes[idx])) then begin flag := TRUE; If NOT track_notes or NOT (track_ch < nm_track_chan) then begin track_ch_key[1] := idx; BREAK; end else begin Inc(track_ch); track_ch_key[track_ch] := idx; end; end; fkey_X := fkey; If ((fkey = kSPACE) or (((fkey = kWeird) or (flag AND (count_pos(hpos) = 0))) and (NOT ((fkey = kWeird) and (count_pos(hpos) >= 2))) or track_notes)) then begin If track_notes then temp1 := nm_track_chan else temp1 := 1; idx2 := 1; If track_notes and NOT ((NOT (command_typing <> 0) and (count_pos(hpos) = 0)) or ((command_typing <> 0) and (count_pos(hpos) < 2))) then If (fkey <> kSPACE) and (fkey <> kENTER) then nope := TRUE; If NOT nope and (fkey <> kSPACE) then For idx := 1 to temp1 do If (fkey = kWeird) or ((track_ch_key[idx2] <> BYTE_NULL) and (track_ch_key[idx2]+12*(current_octave-1) in [1..12*8+1])) then begin If (fkey <> kSPACE) and NOT (track_notes and mark_lines and (pattern_page MOD mark_line <> 0)) then begin get_chunk(pattern,pattern_page,curr_ch+idx-1,chunk); If (fkey <> kWeird) then begin If NOT right_shift_pressed then chunk.note := track_ch_key[idx2]+12*(current_octave-1) else chunk.note := track_ch_key[idx2]+12*(current_octave-1)+fixed_note_flag; If NOT (chunk.effect_def in [ef_TonePortamento, ef_TPortamVolSlide]) then begin If NOT (get_4op_to_test <> 0) then chunk.instr_def := current_inst else If (curr_ch+idx-1 in _4op_tracks_lo) then chunk.instr_def := LO(get_4op_to_test) else chunk.instr_def := HI(get_4op_to_test); If is_4op_chan(curr_ch+idx-1) and (curr_ch+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern,pattern_page,PRED(curr_ch)+idx-1,chunk2); chunk2.note := 0; If NOT track_notes or track_notes_ins then If (HI(get_4op_to_test) <> 0) then chunk2.instr_def := HI(get_4op_to_test) else chunk2.instr_def := current_inst else chunk2.instr_def := min(voice_table[PRED(curr_ch)+idx-1],1); If channel_flag[PRED(curr_ch)+idx-1] then put_chunk(pattern,pattern_page,PRED(curr_ch)+idx-1,chunk2); end else If is_4op_chan(curr_ch+idx-1) and (curr_ch+idx-1 in _4op_tracks_hi) then begin get_chunk(pattern,pattern_page,SUCC(curr_ch)+idx-1,chunk2); chunk2.note := 0; If NOT track_notes or track_notes_ins then If (LO(get_4op_to_test) <> 0) then chunk2.instr_def := LO(get_4op_to_test) else chunk2.instr_def := current_inst else chunk2.instr_def := min(voice_table[SUCC(curr_ch)+idx-1],1); If channel_flag[SUCC(curr_ch)+idx-1] then put_chunk(pattern,pattern_page,SUCC(curr_ch)+idx-1,chunk2); end; end; end else begin chunk.note := BYTE_NULL; chunk.instr_def := 0; end; If channel_flag[curr_ch+idx-1] and NOT ignore_note_once[curr_ch+idx-1] then begin ignore_note_once[curr_ch+idx-1] := TRUE; put_chunk(pattern_patt,pattern_page,curr_ch+idx-1,chunk); If (chunk.instr_def <> 0) then load_instrument(songdata.instr_data[chunk.instr_def],curr_ch+idx-1); If is_4op_chan(curr_ch+idx-1) then If (curr_ch+idx-1 in _4op_tracks_lo) then begin get_chunk(pattern_patt,pattern_page,PRED(curr_ch)+idx-1,chunk2); load_instrument(songdata.instr_data[chunk2.instr_def],PRED(curr_ch)+idx-1); end else begin get_chunk(pattern_patt,pattern_page,SUCC(curr_ch)+idx-1,chunk2); load_instrument(songdata.instr_data[chunk2.instr_def],SUCC(curr_ch)+idx-1); end; If (chunk.note <> BYTE_NULL) then output_note(chunk.note AND $7f,chunk.instr_def,curr_ch+idx-1,TRUE,TRUE); Inc(idx2); end; end; end; If NOT nope then begin fkey := kSPACE; If track_notes then begin If (calc_pattern_pos(pattern) <> BYTE_NULL) then begin fade_out_playback(FALSE); calibrate_player(calc_pattern_pos(pattern),page,TRUE,TRUE); end else begin start_pattern := pattern; start_line := page; play_single_patt := TRUE; no_sync_playing := TRUE; start_playing; repeat_pattern := TRUE; end; temp1 := PATTERN_trace; If (temp1 = kF10) then begin fkey := temp1; nope := TRUE; end; end else If (songdata.pattern_order[pattern] <> BYTE_NULL) and NOT ((play_status <> isStopped) and (fkey_X = kSPACE)) then begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; If (status_backup.play_status <> isStopped) then begin replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; Move(event_table,event_table_backup,SizeOf(event_table)); Move(voice_table,voice_table_backup,SizeOf(voice_table)); Move(volume_table,volume_table_backup,SizeOf(volume_table)); Move(pan_lock,pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); reset_player; Move(fmpar_table,fmpar_table_backup,SizeOf(fmpar_table_backup)); Move(freq_table,freq_table_backup,SizeOf(freq_table)); Move(freqtable2,freqtable2_backup,SizeOf(freqtable2)); Move(keyoff_loop,keyoff_loop_backup,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); end; If NOT (debugging and (play_status = isStopped)) then begin init_player; debugging := TRUE; end; old_order := current_order; old_pattern := current_pattern; old_line := current_line; old_speed := speed; old_tempo := tempo; current_order := 0; current_pattern := pattern; current_line := page; single_play := TRUE; poll_proc; single_play := FALSE; current_order := old_order; current_pattern := old_pattern; current_line := old_line; speed := old_speed; tempo := old_tempo; play_status := isStopped; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(page); If (status_backup.play_status <> isStopped) then begin Move(event_table_backup,event_table,SizeOf(event_table)); Move(voice_table_backup,voice_table,SizeOf(voice_table)); Move(volume_table_backup,volume_table,SizeOf(volume_table)); Move(fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(panning_table_backup,panning_table,SizeOf(panning_table)); reset_player; Move(pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(peak_lock_backup,peak_lock,SizeOf(volume_lock)); Move(freq_table_backup,freq_table,SizeOf(freq_table)); Move(freqtable2_backup,freqtable2,SizeOf(freqtable2)); Move(keyoff_loop_backup,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; debugging := FALSE; end; If (page < PRED(songdata.patt_len)) then If linefeed or NOT lf_in_mboard_mode then Inc(page) else else If cycle_pattern then page := 0; If (left_shift_pressed or jump_mark_mode) and (mark_line <> 0) and mark_lines then begin old_line := page; While (page MOD mark_line <> 0) do If (page < PRED(songdata.patt_len)) then Inc(page) else If cycle_pattern then page := 0 else begin page := old_line; BREAK; end; end; end else If (page < PRED(songdata.patt_len)) then If linefeed or NOT lf_in_mboard_mode then Inc(page) else else If cycle_pattern then page := 0; end; end else If (fkey <> kUp) and (fkey <> kDown) and (fkey <> kHome) and (fkey <> kEnd) and (fkey <> kLeft) and (fkey <> kRight) and (fkey <> kPgUp) and (fkey <> kPgDown) and (fkey <> kCtPgUp) and (fkey <> kCtPgDn) and (fkey <> kTAB) and (fkey <> kShTAB) and (fkey <> kCtLbr) and (fkey <> kCtRbr) and (fkey <> kCHlbrk) and (fkey <> kCHrbrk) and (fkey <> kCtHome) and (fkey <> kCtEnd) and (fkey <> kAltM) and (fkey <> kAltL) and (fkey <> kCtEntr) and (fkey <> kF1) and NOT (shift_pressed and ((fkey = kHome) or (fkey = kNPHome) or (fkey = kPgUp) or (fkey = kNPPgUp) or (fkey = kEnd) or (fkey = kNPEnd) or (fkey = kPgDown) or (fkey = kNPPgDn))) then begin nope := TRUE; debugging := FALSE; end; end else If (fkey <> kUp) and (fkey <> kDown) and (fkey <> kHome) and (fkey <> kEnd) and (fkey <> kLeft) and (fkey <> kRight) and (fkey <> kPgUp) and (fkey <> kPgDown) and (fkey <> kCtPgUp) and (fkey <> kCtPgDn) and (fkey <> kTAB) and (fkey <> kShTAB) and (fkey <> kCtLbr) and (fkey <> kCtRbr) and (fkey <> kCHlbrk) and (fkey <> kCHrbrk) and (fkey <> kCtHome) and (fkey <> kCtEnd) and (fkey <> kAltM) and (fkey <> kAltL) and (fkey <> kCtEntr) and (fkey <> kF1) and NOT (shift_pressed and ((fkey = kHome) or (fkey = kNPHome) or (fkey = kPgUp) or (fkey = kNPPgUp) or (fkey = kEnd) or (fkey = kNPEnd) or (fkey = kPgDown) or (fkey = kNPPgDn))) then begin debugging := FALSE; end; If track_notes and (chan <> count_channel(old_hpos)) then cancel_note_recorder; If (page <> old_patt_page) or (NOT linefeed and lf_in_mboard_mode) then For idx := 1 to 20 do ignore_note_once[idx] := FALSE; chan := count_channel(hpos); If nope and NOT midiboard and (count_pos(hpos) = 0) and (UpCase(CHAR(LO(fkey))) in ['A',UpCase(b_note),'C'..'G']) then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['1'..'9','a',b_note,'c'..'g', 'A',UpCase(b_note),'C'..'F','#','-']; is_environment.locate_pos := 2; tstr := CHAR(LO(fkey)); is_setting.terminate_keys[3] := kTAB; Repeat tstr := InputStr(tstr,08+pos3[1+(chan-PRED(chan_pos)-1)*4], 11+PRED(MAX_PATTERN_ROWS DIV 2),3,3, pattern_input_bckg+pattern_input, pattern_input_warn+pattern_input); is_setting.append_enabled := TRUE; If (UpCase(tstr[1]) in ['A',UpCase(b_note),'C'..'G']) and ((is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB)) then begin nope := FALSE; If (Length(tstr) = 2) then If tstr[2] in ['1'..'9'] then Insert('-',tstr,2) else If tstr[2] in ['-','#'] then tstr := tstr+Num2str(current_octave,10); If (Length(tstr) = 1) then tstr := tstr+'-'+Num2str(current_octave,10); For temp1 := 1 to 12*8+1 do If (Upper(tstr) = note_layout[temp1]) then begin nope := TRUE; get_chunk(pattern,page,chan,chunk); chunk.note := temp1; put_chunk(pattern,page,chan,chunk); If is_4op_chan(chan) then If (chan in _4op_tracks_hi) then begin get_chunk(pattern,page,SUCC(chan),chunk2); chunk2.note := 0; put_chunk(pattern,page,SUCC(chan),chunk2); end else begin get_chunk(pattern,page,PRED(chan),chunk2); chunk2.note := 0; put_chunk(pattern,page,PRED(chan),chunk2); end; BREAK; end; If NOT nope and (Length(tstr) = 2) then For temp1 := 1 to 12*8+1 do If (Copy(Upper(tstr),1,2) = Copy(note_layout[temp1],1,2)) then begin nope := TRUE; get_chunk(pattern,page,chan,chunk); chunk.note := temp1; put_chunk(pattern,page,chan,chunk); If is_4op_chan(chan) then If (chan in _4op_tracks_hi) then begin get_chunk(pattern,page,SUCC(chan),chunk2); chunk2.note := 0; put_chunk(pattern,page,SUCC(chan),chunk2); end else begin get_chunk(pattern,page,PRED(chan),chunk2); chunk2.note := 0; put_chunk(pattern,page,PRED(chan),chunk2); end; BREAK; end; If nope and linefeed and (is_environment.keystroke = kENTER) then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; If (tstr = '') then nope := TRUE; If nope and (is_environment.keystroke = kTAB) and (hpos+1 <= last_hpos) then Inc(hpos); end; until (is_environment.keystroke = kESC) or nope; is_setting.terminate_keys[3] := 0; nope := FALSE; end; If NOT (command_typing <> 0) and nope and (count_pos(hpos) = 1) and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := HEX_NUM_CHARSET; is_environment.locate_pos := 2; tstr := CHAR(LO(fkey)); is_setting.terminate_keys[3] := kTAB; If (pattern_layout = 1) then temp := 1 else temp := 0; Repeat tstr := InputStr(tstr,08+pos3[hpos]-temp,11+PRED(MAX_PATTERN_ROWS DIV 2),2,2, pattern_input_bckg+pattern_input, pattern_input_warn+pattern_input); is_setting.append_enabled := TRUE; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then If (tstr = '') then nope := TRUE else If Str2num(tstr,16) in [0..$0fa] then begin nope := TRUE; If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); chunk.instr_def := Str2num(tstr,16); put_chunk(pattern,page,track_chan_start+idx-1,chunk); If (chunk.instr_def <> 0) and update_ins then begin current_inst := chunk.instr_def; instrum_page := current_inst; reset_marked_instruments; end; end; end else begin get_chunk(pattern,page,chan,chunk); chunk.instr_def := Str2num(tstr,16); put_chunk(pattern,page,chan,chunk); If (chunk.instr_def <> 0) and update_ins then begin current_inst := chunk.instr_def; instrum_page := current_inst; reset_marked_instruments; end; end; end; If nope and linefeed and (is_environment.keystroke = kENTER) then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; If nope and (is_environment.keystroke = kTAB) and (hpos+1 <= last_hpos) then Inc(hpos); until (is_environment.keystroke = kESC) or nope; is_setting.terminate_keys[3] := 0; nope := FALSE; end; If NOT (command_typing <> 0) and nope and (count_pos(hpos) = 2) and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<']) then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['0'..'9','a'..'z','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<']; is_environment.locate_pos := 2; tstr := CHAR(LO(fkey)); is_setting.terminate_keys[3] := kTAB; Repeat tstr := InputStr(tstr,08+pos3[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2),3,3, pattern_input_bckg+pattern_input, pattern_input_warn+pattern_input); is_setting.append_enabled := TRUE; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then If (tstr = '') then nope := TRUE else begin If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then If (idx > 1) then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); get_chunk(pattern,page,track_chan_start,chunk2); chunk.effect_def := chunk2.effect_def; chunk.effect := chunk2.effect; put_chunk(pattern,page,track_chan_start+idx-1,chunk); end else begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); chunk.effect_def := FX(tstr[1]); temp := Str2num(Copy(tstr,2,Length(tstr)),16); If correct_range(chunk.effect_def,temp) or (tstr = '') then begin nope := TRUE; tstr := Copy(tstr,2,Length(tstr)); If (tstr <> '') then chunk.effect := Str2num(tstr,16) else chunk.effect := 0; put_chunk(pattern,page,track_chan_start+idx-1,chunk); end; end; end else begin get_chunk(pattern,page,chan,chunk); chunk.effect_def := FX(tstr[1]); temp := Str2num(Copy(tstr,2,Length(tstr)),16); If correct_range(chunk.effect_def,temp) or (tstr = '') then begin nope := TRUE; tstr := Copy(tstr,2,Length(tstr)); If (tstr <> '') then chunk.effect := Str2num(tstr,16) else chunk.effect := 0; put_chunk(pattern,page,chan,chunk) end; end; end; If nope and linefeed and (is_environment.keystroke = kENTER) then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; If nope and (is_environment.keystroke = kTAB) and (hpos+1 <= last_hpos) then Inc(hpos); until (is_environment.keystroke = kESC) or nope; is_setting.terminate_keys[3] := 0; nope := FALSE; end; If NOT (command_typing <> 0) and nope and (count_pos(hpos) = 3) and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<']) then begin nope := FALSE; is_setting.append_enabled := FALSE; is_setting.character_set := ['0'..'9','a'..'z','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<']; is_environment.locate_pos := 2; tstr := CHAR(LO(fkey)); is_setting.terminate_keys[3] := kTAB; Repeat tstr := InputStr(tstr,08+pos3[hpos],11+PRED(MAX_PATTERN_ROWS DIV 2),3,3, pattern_input_bckg+pattern_input, pattern_input_warn+pattern_input); is_setting.append_enabled := TRUE; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then If (tstr = '') then nope := TRUE else begin If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then If (idx > 1) then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); get_chunk(pattern,page,track_chan_start,chunk2); chunk.effect_def2 := chunk2.effect_def2; chunk.effect2 := chunk2.effect2; put_chunk(pattern,page,track_chan_start+idx-1,chunk); end else begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); chunk.effect_def2 := FX(tstr[1]); temp := Str2num(Copy(tstr,2,Length(tstr)),16); If correct_range(chunk.effect_def2,temp) or (tstr = '') then begin nope := TRUE; tstr := Copy(tstr,2,Length(tstr)); If (tstr <> '') then chunk.effect2 := Str2num(tstr,16) else chunk.effect2 := 0; put_chunk(pattern,page,track_chan_start+idx-1,chunk); end; end; end else begin get_chunk(pattern,page,chan,chunk); chunk.effect_def2 := FX(tstr[1]); temp := Str2num(Copy(tstr,2,Length(tstr)),16); If correct_range(chunk.effect_def2,temp) or (tstr = '') then begin nope := TRUE; tstr := Copy(tstr,2,Length(tstr)); If (tstr <> '') then chunk.effect2 := Str2num(tstr,16) else chunk.effect2 := 0; put_chunk(pattern,page,chan,chunk); end; end; end; If nope and linefeed and (is_environment.keystroke = kENTER) then If page < PRED(songdata.patt_len) then Inc(page) else If cycle_pattern then page := 0; If nope and (is_environment.keystroke = kTAB) and (hpos+1 <= last_hpos) then Inc(hpos); until (is_environment.keystroke = kESC) or nope; is_setting.terminate_keys[3] := 0; nope := FALSE; end; If NOT marking and nope then If (command_typing <> 0) and ((count_pos(hpos) > 0) and (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<'])) then begin Case count_pos(hpos) of 1: If NOT (UpCase(CHAR(LO(fkey))) in ['1'..'9']) then nope := FALSE else begin nope := TRUE; get_chunk(pattern,page,chan,chunk); If (chunk.note in [1..12*8+1]) then chunk.note := ((chunk.note-1) MOD 12)+1+ 12*(Str2num(CHAR(LO(fkey)),10)-1) else If (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1]) then chunk.note := ((chunk.note-1) MOD 12)+1+ 12*(Str2num(CHAR(LO(fkey)),10)-1)+fixed_note_flag; If (chunk.note in [1..12*8+1,fixed_note_flag+1..fixed_note_flag+12*8+1]) then put_chunk(pattern,page,chan,chunk) else nope := FALSE; end; 2, 3: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else begin nope := TRUE; If track_notes then begin For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); If (idx > 1) then begin get_chunk(pattern,page,track_chan_start,chunk2); chunk.instr_def := chunk2.instr_def; end; Case count_pos(hpos) of 2: chunk.instr_def := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.instr_def AND $0f; 3: chunk.instr_def := Str2num(CHAR(LO(fkey)),16)+ chunk.instr_def AND $f0; end; If (chunk.instr_def <= 255) and NOT shift_pressed then begin put_chunk(pattern,page,track_chan_start+idx-1,chunk); If (chunk.instr_def <> 0) and update_ins then begin current_inst := chunk.instr_def; instrum_page := current_inst; reset_marked_instruments; end; end else nope := FALSE; end; end else begin get_chunk(pattern,page,chan,chunk); Case count_pos(hpos) of 2: chunk.instr_def := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.instr_def AND $0f; 3: chunk.instr_def := Str2num(CHAR(LO(fkey)),16)+ chunk.instr_def AND $f0; end; If (chunk.instr_def <= 255) and NOT shift_pressed then begin put_chunk(pattern,page,chan,chunk); If (chunk.instr_def <> 0) and update_ins then begin current_inst := chunk.instr_def; instrum_page := current_inst; reset_marked_instruments; end; end else nope := FALSE; end; end; 4,5, 6: begin nope := TRUE; If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); If (idx > 1) then begin get_chunk(pattern,page,track_chan_start,chunk2); chunk.effect_def := chunk2.effect_def; chunk.effect := chunk2.effect; end; Case count_pos(hpos) of 4: begin chunk.effect_def := FX(CHAR(LO(fkey))); If (chunk.effect_def in [ef_SetSpeed,ef_SetTempo]) and (chunk.effect = 0) then Case chunk.effect_def of ef_SetSpeed: chunk.effect := songdata.speed; ef_SetTempo: chunk.effect := songdata.tempo; end; end; 5: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.effect AND $0f; 6: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect := Str2num(CHAR(LO(fkey)),16)+ chunk.effect AND $f0; end; If correct_range(chunk.effect_def,chunk.effect) and NOT (shift_pressed and NOT (FX(CHAR(LO(fkey))) in [ef_Extended2,ef_Extended3,ef_SetGlobalVolume, ef_ExtraFineArpeggio,ef_ExtraFineVibrato,ef_ExtraFineTremolo, ef_ForceInsVolume,ef_SwapArpeggio,ef_SwapVibrato, ef_SetCustomSpeedTab,ef_GlobalFSlideUp,ef_GlobalFSlideDown])) then put_chunk(pattern,page,track_chan_start+idx-1,chunk) else nope := FALSE; end; end else begin get_chunk(pattern,page,chan,chunk); Case count_pos(hpos) of 4: begin chunk.effect_def := FX(CHAR(LO(fkey))); If (chunk.effect_def in [ef_SetSpeed,ef_SetTempo]) and (chunk.effect = 0) then Case chunk.effect_def of ef_SetSpeed: chunk.effect := songdata.speed; ef_SetTempo: chunk.effect := songdata.tempo; end; end; 5: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.effect AND $0f; 6: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect := Str2num(CHAR(LO(fkey)),16)+ chunk.effect AND $f0; end; If correct_range(chunk.effect_def,chunk.effect) and NOT (shift_pressed and NOT (FX(CHAR(LO(fkey))) in [ef_Extended2,ef_Extended3,ef_SetGlobalVolume, ef_ExtraFineArpeggio,ef_ExtraFineVibrato,ef_ExtraFineTremolo, ef_ForceInsVolume,ef_SwapArpeggio,ef_SwapVibrato, ef_SetCustomSpeedTab,ef_GlobalFSlideUp,ef_GlobalFSlideDown])) then put_chunk(pattern,page,chan,chunk) else nope := FALSE; end; end; 7,8, 9: begin nope := TRUE; If track_notes then begin If (nm_track_chan > 1) then _save_pattern_to_undo; For idx := 1 to nm_track_chan do If channel_flag[track_chan_start+idx-1] then begin get_chunk(pattern,page,track_chan_start+idx-1,chunk); If (idx > 1) then begin get_chunk(pattern,page,track_chan_start,chunk2); chunk.effect_def2 := chunk2.effect_def2; chunk.effect2 := chunk2.effect2; end; Case count_pos(hpos) of 7: begin chunk.effect_def2 := FX(CHAR(LO(fkey))); If (chunk.effect_def2 in [ef_SetSpeed,ef_SetTempo]) and (chunk.effect2 = 0) then Case chunk.effect_def2 of ef_SetSpeed: chunk.effect2 := songdata.speed; ef_SetTempo: chunk.effect2 := songdata.tempo; end; end; 8: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect2 := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.effect2 AND $0f; 9: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect2 := Str2num(CHAR(LO(fkey)),16)+ chunk.effect2 AND $f0; end; If correct_range(chunk.effect_def2,chunk.effect2) and NOT (shift_pressed and NOT (FX(CHAR(LO(fkey))) in [ef_Extended2,ef_Extended3,ef_SetGlobalVolume, ef_ExtraFineArpeggio,ef_ExtraFineVibrato,ef_ExtraFineTremolo, ef_ForceInsVolume,ef_SwapArpeggio,ef_SwapVibrato, ef_SetCustomSpeedTab,ef_GlobalFSlideUp,ef_GlobalFSlideDown])) then put_chunk(pattern,page,track_chan_start+idx-1,chunk) else nope := FALSE; end; end else begin get_chunk(pattern,page,chan,chunk); Case count_pos(hpos) of 7: begin chunk.effect_def2 := FX(CHAR(LO(fkey))); If (chunk.effect_def2 in [ef_SetSpeed,ef_SetTempo]) and (chunk.effect2 = 0) then Case chunk.effect_def2 of ef_SetSpeed: chunk.effect2 := songdata.speed; ef_SetTempo: chunk.effect2 := songdata.tempo; end; end; 8: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect2 := Str2num(CHAR(LO(fkey)),16)*$10+ chunk.effect2 AND $0f; 9: If NOT (UpCase(CHAR(LO(fkey))) in ['0'..'9','A'..'F']) then nope := FALSE else chunk.effect2 := Str2num(CHAR(LO(fkey)),16)+ chunk.effect2 AND $f0; end; If correct_range(chunk.effect_def2,chunk.effect2) and NOT (shift_pressed and NOT (FX(CHAR(LO(fkey))) in [ef_Extended2,ef_Extended3,ef_SetGlobalVolume, ef_ExtraFineArpeggio,ef_ExtraFineVibrato,ef_ExtraFineTremolo, ef_ForceInsVolume,ef_SwapArpeggio,ef_SwapVibrato, ef_SetCustomSpeedTab,ef_GlobalFSlideUp,ef_GlobalFSlideDown])) then put_chunk(pattern,page,chan,chunk) else nope := FALSE; end; end; end; If (command_typing = 2) and (count_pos(hpos) in [2,5,8]) then Inc(hpos) else If nope and linefeed then begin If (command_typing = 2) and (count_pos(hpos) in [3,6,9]) then Dec(hpos); If page < PRED(songdata.patt_len) then If linefeed then Inc(page) else else If cycle_pattern then page := 0; end; end; fkey_X := WORD_NULL; _end: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} If scankey(SC_F11) and NOT ctrl_pressed and NOT alt_pressed and NOT shift_pressed then begin If (command_typing <> 0) then Case command_typing of 1: If cycle_pattern then begin command_typing := 2; cycle_pattern := FALSE; end else cycle_pattern := TRUE; 2: begin command_typing := 1; cycle_pattern := FALSE; end; end; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; If scankey(SC_F12) and NOT ctrl_pressed and NOT alt_pressed then begin If NOT shift_pressed then linefeed := NOT linefeed else jump_mark_mode := NOT jump_mark_mode; status_refresh; wait_until_F11_F12_released; keyboard_reset_buffer; end; until (nope and ((fkey = kENTER) or (fkey = kESC) or (fkey = kF10))) or _force_program_quit; If track_notes then begin cancel_note_recorder; stop_playing; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(page); end; adlibtracker2-2.4.24/makefile.cross320000644000000000000000000000273613411003760016012 0ustar rootroot.PHONY: clean release release_ all: adtrack2 release: release_ rm -rf release/adtrack-*/ echo -e "\n\n\nyour files are ready at release/\n" release_: all rm -rf release mkdir release mkdir release/src cp -r *.pas *.inc Makefile TODO *.bat sdl.dll sdl utils package release/src/ cp -r package release/bin cp adtrack2 release/bin/ rm -f release/bin/techinfo.* cd release; \ echo "which minor version is this? NOTE that i assume 2.4.xx and that you're on debian wheezy x86!"; \ read ver; \ mv src adtrack-2.4.$${ver}-linux-src; \ mv bin adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86; \ tar cvzf adtrack-2.4.$${ver}-linux-src.tar.gz adtrack-2.4.$${ver}-linux-src; \ tar cvzf adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86.tar.gz adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86; clean: rm -f *.o *.s *.res *.ppu *.map *.fpd *.sym *.cfg adtrack2 rm -f sdl/*.o sdl/*.ppu mrproper: clean rm -rf bin/ mkdir bin/ rm -rf release/ adtrack2: adt2data.pas adt2ext2.pas adt2ext3.pas adt2ext4.pas adt2ext5.pas adt2extn.pas adt2keyb.pas adt2opl3.pas adt2pack.pas adt2sys.pas adt2text.pas adt2unit.pas adt2vesa.pas adtrack2.pas depackio.pas dialogio.pas iloaders.inc iloadins.inc instedit.inc ipattern.inc ipattord.inc iss_tim.pas menulib1.pas menulib2.pas opl3emu.pas parserio.pas realtime.inc stringio.pas txtscrio.pas typcons1.inc typcons2.inc ppcross386 -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Fusdl -Fl/usr/lib32 -Fl/usr/lib/gcc/x86_64-linux-gnu/4.7.2/32 adtrack2.pas -oadtrack2 adlibtracker2-2.4.24/opl3emu.pas0000644000000000000000000010551213411003760015102 0ustar rootroot// 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 . // // ------------------------------------------------------------------ // OPL3 EMULATOR // Based on NukedOPL3 1.6 by Nuke.YKT (Alexey Khokholov) // Special thanks to insane/Altair for initial C to Pascal conversion // ------------------------------------------------------------------ unit OPL3EMU; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface procedure OPL3EMU_init; procedure OPL3EMU_WriteReg(reg: Word; data: Byte); procedure OPL3EMU_PollProc(p_data: pDword; var ch_table); implementation const LOG_SIN_VAL: array[0..255] of Word = ( $859,$6c3,$607,$58b,$52e,$4e4,$4a6,$471,$443,$41a,$3f5,$3d3,$3b5,$398,$37e,$365, $34e,$339,$324,$311,$2ff,$2ed,$2dc,$2cd,$2bd,$2af,$2a0,$293,$286,$279,$26d,$261, $256,$24b,$240,$236,$22c,$222,$218,$20f,$206,$1fd,$1f5,$1ec,$1e4,$1dc,$1d4,$1cd, $1c5,$1be,$1b7,$1b0,$1a9,$1a2,$19b,$195,$18f,$188,$182,$17c,$177,$171,$16b,$166, $160,$15b,$155,$150,$14b,$146,$141,$13c,$137,$133,$12e,$129,$125,$121,$11c,$118, $114,$10f,$10b,$107,$103,$0ff,$0fb,$0f8,$0f4,$0f0,$0ec,$0e9,$0e5,$0e2,$0de,$0db, $0d7,$0d4,$0d1,$0cd,$0ca,$0c7,$0c4,$0c1,$0be,$0bb,$0b8,$0b5,$0b2,$0af,$0ac,$0a9, $0a7,$0a4,$0a1,$09f,$09c,$099,$097,$094,$092,$08f,$08d,$08a,$088,$086,$083,$081, $07f,$07d,$07a,$078,$076,$074,$072,$070,$06e,$06c,$06a,$068,$066,$064,$062,$060, $05e,$05c,$05b,$059,$057,$055,$053,$052,$050,$04e,$04d,$04b,$04a,$048,$046,$045, $043,$042,$040,$03f,$03e,$03c,$03b,$039,$038,$037,$035,$034,$033,$031,$030,$02f, $02e,$02d,$02b,$02a,$029,$028,$027,$026,$025,$024,$023,$022,$021,$020,$01f,$01e, $01d,$01c,$01b,$01a,$019,$018,$017,$017,$016,$015,$014,$014,$013,$012,$011,$011, $010,$00f,$00f,$00e,$00d,$00d,$00c,$00c,$00b,$00a,$00a,$009,$009,$008,$008,$007, $007,$007,$006,$006,$005,$005,$005,$004,$004,$004,$003,$003,$003,$002,$002,$002, $002,$001,$001,$001,$001,$001,$001,$001,$000,$000,$000,$000,$000,$000,$000,$000); EXP_VAL: array[0..255] of Word = ( $000,$003,$006,$008,$00b,$00e,$011,$014,$016,$019,$01c,$01f,$022,$025,$028,$02a, $02d,$030,$033,$036,$039,$03c,$03f,$042,$045,$048,$04b,$04e,$051,$054,$057,$05a, $05d,$060,$063,$066,$069,$06c,$06f,$072,$075,$078,$07b,$07e,$082,$085,$088,$08b, $08e,$091,$094,$098,$09b,$09e,$0a1,$0a4,$0a8,$0ab,$0ae,$0b1,$0b5,$0b8,$0bb,$0be, $0c2,$0c5,$0c8,$0cc,$0cf,$0d2,$0d6,$0d9,$0dc,$0e0,$0e3,$0e7,$0ea,$0ed,$0f1,$0f4, $0f8,$0fb,$0ff,$102,$106,$109,$10c,$110,$114,$117,$11b,$11e,$122,$125,$129,$12c, $130,$134,$137,$13b,$13e,$142,$146,$149,$14d,$151,$154,$158,$15c,$160,$163,$167, $16b,$16f,$172,$176,$17a,$17e,$181,$185,$189,$18d,$191,$195,$199,$19c,$1a0,$1a4, $1a8,$1ac,$1b0,$1b4,$1b8,$1bc,$1c0,$1c4,$1c8,$1cc,$1d0,$1d4,$1d8,$1dc,$1e0,$1e4, $1e8,$1ec,$1f0,$1f5,$1f9,$1fd,$201,$205,$209,$20e,$212,$216,$21a,$21e,$223,$227, $22b,$230,$234,$238,$23c,$241,$245,$249,$24e,$252,$257,$25b,$25f,$264,$268,$26d, $271,$276,$27a,$27f,$283,$288,$28c,$291,$295,$29a,$29e,$2a3,$2a8,$2ac,$2b1,$2b5, $2ba,$2bf,$2c4,$2c8,$2cd,$2d2,$2d6,$2db,$2e0,$2e5,$2e9,$2ee,$2f3,$2f8,$2fd,$302, $306,$30b,$310,$315,$31a,$31f,$324,$329,$32e,$333,$338,$33d,$342,$347,$34c,$351, $356,$35b,$360,$365,$36a,$370,$375,$37a,$37f,$384,$38a,$38f,$394,$399,$39f,$3a4, $3a9,$3ae,$3b4,$3b9,$3bf,$3c4,$3c9,$3cf,$3d4,$3da,$3df,$3e4,$3ea,$3ef,$3f5,$3fa); MULT_VAL: array[0..15] of Byte = (1,2,4,6,8,10,12,14,16,18,20,20,24,24,30,30); KSL_VAL: array[0..15] of Byte = (0,32,40,45,48,51,53,55,56,58,59,60,61,62,63,64); KSL_SHIFT: array[0..3] of Byte = (8,1,2,0); SL_VAL: array[0..15] of Byte = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,31); VIB_SHIFT: array[0..7] of Byte = (3,1,0,1,3,1,0,1); VIB_S_SHIFT: array[0..7] of Shortint = (1,1,1,1,-1,-1,-1,-1); EG_IDX: array[0..15] of Byte =(0,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2); EG_SHIFT: array[0..15] of Shortint = (0,11,10,9,8,7,6,5,4,3,2,1,0,0,-1,-2); EG_VAL: array[0..2,0..3,0..7] of Byte = (((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)), ((0,1,0,1,0,1,0,1),(0,1,0,1,1,1,0,1),(0,1,1,1,0,1,1,1),(0,1,1,1,1,1,1,1)), ((1,1,1,1,1,1,1,1),(2,2,1,1,1,1,1,1),(2,2,1,1,2,2,1,1),(2,2,2,2,2,2,1,1))); CH_5BIT_MASK: array[0..31] of Byte = (1,2,3,4,5,6,0,0,7,8,9,10,11,12,0,0,13,14,15,16,17,18,0,0,0,0,0,0,0,0,0,0); CH_SLOT_IDX: array[0..17] of Byte = (0,1,2,6,7,8,12,13,14,18,19,20,24,25,26,30,31,32); CH_4OP_MASK: array[0..17] of Byte = (4,5,6,1,2,3,0,0,0,13,14,15,10,11,12,0,0,0); CH_4OP_IDX: array[0..5] of Byte = (0,1,2,9,10,11); CH_MAPPING: array[0..17] of Byte = ( 3,0, // 2OP | 4OP #1 4,1, // 2OP | 4OP #2 5,2, // 2OP | 4OP #3 6, // 2OP | RHYTHM: BD 7, // 2OP | RHYTHM: HH + SD 8, // 2OP | RHYTHM: TT + TC 12,9, // 2OP | 4OP #4 13,10, // 2OP | 4OP #5 14,11, // 2OP | 4OP #6 15, // 2OP 16, // 2OP 17); // 2OP NOISE_HASH_VAL = $306600; NOISE_XOR = $800302; WORD_NULL = WORD(NOT 0); type OPL3_CHAN_TYPE = (CH_2OP,CH_4OP_1,CH_4OP_2,CH_RHYTHM); EG_GEN_STATE = (EG_OFF,EG_ATTACK,EG_DECAY,EG_SUSTAIN,EG_RELEASE); CHAN_PTR_TABLE = array[0..17] of pDword; P_OPL3_CHIP = ^OPL3_CHIP; P_OPL3_SLOT = ^OPL3_SLOT; P_OPL3_CHAN = ^OPL3_CHAN; OPL3_SLOT = Record p_chan: P_OPL3_CHAN; p_chip: P_OPL3_CHIP; p_mod: pSmallint; p_trem: pByte; fb_out, prev_out, output: Smallint; pg_phase: Dword; eg_state: EG_GEN_STATE; eg_rout, eg_out: Smallint; eg_inc, eg_rate, eg_ksl: Byte; reg_vib, reg_type, reg_ksr, reg_mult, reg_ksl, reg_tl, reg_ar, reg_dr, reg_sl, reg_rr, reg_wf, key: Byte; end; OPL3_CHAN = Record p_slot: array[0..1] of P_OPL3_SLOT; p_chan: P_OPL3_CHAN; p_chip: P_OPL3_CHIP; p_out: array[0..3] of ^Smallint; ch_type: OPL3_CHAN_TYPE; fnum: Word; block, fb, con, alg, ksr: Byte; out_l, out_r: Word; end; OPL3_CHIP = Record chan: array[0..17] of OPL3_CHAN; slot: array[0..35] of OPL3_SLOT; timer: Word; nts_bit, dva_bit, dvb_bit: 0..1; rhy_flag: Byte; trem_dir: 0..1; trem_pos, trem_val, vib_pos: Byte; noise: Dword; output: array[0..1] of Longint; out_l: array[0..17] of Smallint; out_r: array[0..17] of Smallint; out_null: Smallint; end; var opl3: OPL3_CHIP; function limit_value(value,lo_bound,hi_bound: Longint): Longint; begin If (value > hi_bound) then value := hi_bound else If (value < lo_bound) then value := lo_bound; limit_value := value; end; function envelope_calc_sin(wf: Byte; phase: Word; eg_out: Smallint): Smallint; var output, level, invert: Word; begin phase := phase AND $3ff; output := 0; invert := 0; Case wf of // Sine 0: begin If (phase AND $200 <> 0) then invert := NOT invert; If (phase AND $100 <> 0) then output := LOG_SIN_VAL[(phase AND $0ff) XOR $0ff] else output := LOG_SIN_VAL[phase and $0ff]; end; // Half-Sine 1: begin If (phase AND $200 <> 0) then output := $1000 else If (phase AND $100 <> 0) then output := LOG_SIN_VAL[(phase AND $0ff) xor $0ff] else output := LOG_SIN_VAL[phase AND $0ff]; end; // Abs-Sine 2: begin If (phase AND $100 <> 0) then output := LOG_SIN_VAL[(phase AND $0ff) XOR $0ff] else output := LOG_SIN_VAL[phase AND $0ff]; end; // Pulse-Sine 3: begin If (phase AND $100 <> 0) then output := $1000 else output := LOG_SIN_VAL[phase AND $0ff]; end; // Sine (EPO) 4: begin If (phase AND $300 = $100) then invert := NOT invert; If (phase AND $200 <> 0) then output := $1000 else If (phase AND $80 <> 0) then output := LOG_SIN_VAL[((phase XOR $0ff) SHL 1) AND $0ff] else output := LOG_SIN_VAL[(phase SHL 1) AND $0ff]; end; // Abs-Sine (EPO) 5: begin If (phase AND $200 <> 0) then output := $1000 else If (phase AND $80 <> 0) then output := LOG_SIN_VAL[((phase XOR $0ff) SHL 1) AND $0ff] else output := LOG_SIN_VAL[(phase SHL 1) AND $0ff]; end; // Square 6: begin If (phase AND $200 <> 0) then invert := WORD_NULL; output := 0; end; // Derived Square 7: begin If (phase AND $200 <> 0) then begin invert := NOT invert; phase := (phase AND $1ff) XOR $1ff; end; output := phase SHL 3; end; end; level := limit_value(output + (eg_out SHL 3),0,$1fff); envelope_calc_sin := SMALLINT(((EXP_VAL[(level AND $0ff) XOR $0ff] OR $400) SHL 1) SHR (level SHR 8)) XOR invert; end; function envelope_calc_rate(p_slot: P_OPL3_SLOT; reg_rate: Byte): Byte; var rate: Byte; begin If (reg_rate = 0) then begin envelope_calc_rate := 0; EXIT; end; rate := (reg_rate SHL 2); If (p_slot^.reg_ksr <> 0) then Inc(rate,p_slot^.p_chan^.ksr) else Inc(rate,(p_slot^.p_chan^.ksr SHR 2)); envelope_calc_rate := limit_value(rate,0,60); end; procedure envelope_update_ksl(p_slot: P_OPL3_SLOT); var ksl: Smallint; begin ksl := (KSL_VAL[p_slot^.p_chan^.fnum SHR 6] SHL 2) - (8 - p_slot^.p_chan^.block) SHL 5; p_slot^.eg_ksl := limit_value(ksl,0,255); end; procedure envelope_update_rate(p_slot: P_OPL3_SLOT); begin Case p_slot^.eg_state of EG_OFF: p_slot^.eg_rate := 0; EG_ATTACK: p_slot^.eg_rate := envelope_calc_rate(p_slot,p_slot^.reg_ar); EG_DECAY: p_slot^.eg_rate := envelope_calc_rate(p_slot,p_slot^.reg_dr); EG_SUSTAIN, EG_RELEASE: p_slot^.eg_rate := envelope_calc_rate(p_slot,p_slot^.reg_rr); end; end; procedure envelope_calc(p_slot: P_OPL3_SLOT); var rate_hi, rate_lo: Byte; begin rate_hi := p_slot^.eg_rate SHR 2; rate_lo := p_slot^.eg_rate AND 3; // calculate increment step for output If (EG_SHIFT[rate_hi] > 0) then begin If ((p_slot^.p_chip^.timer AND ((1 SHL EG_SHIFT[rate_hi]) - 1)) = 0) then p_slot^.eg_inc := EG_VAL[EG_IDX[rate_hi],rate_lo, ((p_slot^.p_chip^.timer) SHR EG_SHIFT[rate_hi]) AND 7] else p_slot^.eg_inc := 0; end else p_slot^.eg_inc := EG_VAL[EG_IDX[rate_hi],rate_lo, p_slot^.p_chip^.timer AND 7] SHL Abs(EG_SHIFT[rate_hi]); p_slot^.eg_out := p_slot^.eg_rout + p_slot^.reg_tl SHL 2 + p_slot^.eg_ksl SHR KSL_SHIFT[p_slot^.reg_ksl] + p_slot^.p_trem^; // apply LFO tremolo Case p_slot^.eg_state of EG_OFF: p_slot^.eg_rout := $1ff; EG_ATTACK: If (p_slot^.eg_rout <> 0) then begin Inc(p_slot^.eg_rout,((NOT p_slot^.eg_rout) * p_slot^.eg_inc) SHR 3); limit_value(p_slot^.eg_rout,0,$1ff); end else begin // continue with decay if max. level is reached p_slot^.eg_state := EG_DECAY; envelope_update_rate(p_slot); end; EG_DECAY: If (p_slot^.eg_rout < SMALLINT(p_slot^.reg_sl) SHL 4) then Inc(p_slot^.eg_rout,p_slot^.eg_inc) else begin // sustain level was reached p_slot^.eg_state := EG_SUSTAIN; envelope_update_rate(p_slot); end; EG_SUSTAIN, EG_RELEASE: If (p_slot^.eg_state = EG_SUSTAIN) and (p_slot^.reg_type <> 0) then // sustain phase else If (p_slot^.eg_rout < $1ff) then Inc(p_slot^.eg_rout,p_slot^.eg_inc) else begin // switch off generator if min. level is reached p_slot^.eg_state := EG_OFF; p_slot^.eg_rout := $1ff; envelope_update_rate(p_slot); end; end; end; procedure eg_key_on_off(p_slot: P_OPL3_SLOT; key_on: Boolean); begin If key_on then begin If (p_slot^.key = 0) then begin p_slot^.eg_state := EG_ATTACK; envelope_update_rate(p_slot); If (p_slot^.eg_rate SHR 2 = $0f) then begin p_slot^.eg_state := EG_DECAY; envelope_update_rate(p_slot); p_slot^.eg_rout := 0; end; p_slot^.pg_phase := 0; end; If (p_slot^.p_chan^.ch_type <> CH_RHYTHM) then p_slot^.key := p_slot^.key OR 1 else p_slot^.key := p_slot^.key OR 2; If (p_slot^.reg_ar = 0) then begin // faked decay prevents restart of envelope if AR=0 p_slot^.eg_state := EG_DECAY; Inc(p_slot^.eg_rout); end; end else // key off If (p_slot^.key <> 0) then begin If (p_slot^.p_chan^.ch_type <> CH_RHYTHM) then p_slot^.key := p_slot^.key AND $0fe else p_slot^.key := p_slot^.key AND $0fd; If (p_slot^.key = 0) then begin p_slot^.eg_state := EG_RELEASE; envelope_update_rate(p_slot); end; end; end; procedure pg_generate(p_slot: P_OPL3_SLOT); var fnum: Word; fnum_hi: Byte; begin fnum := p_slot^.p_chan^.fnum; If (p_slot^.reg_vib <> 0) then begin // apply LFO vibrato fnum_hi := fnum SHR (7 + VIB_SHIFT[(p_slot^.p_chip^.timer SHR 10) AND 7] + (1 - p_slot^.p_chip^.dvb_bit)); Inc(fnum,fnum_hi * VIB_S_SHIFT[(p_slot^.p_chip^.timer SHR 10) AND 7]); end; Inc(p_slot^.pg_phase,(((fnum SHL p_slot^.p_chan^.block) SHR 1) * MULT_VAL[p_slot^.reg_mult]) SHR 1); end; procedure update_lfo_eg_ksr_mult(p_slot: P_OPL3_SLOT; data: Byte); begin // assign LFO tremolo If ((data SHR 7) AND 1 <> 0) then p_slot^.p_trem := @p_slot^.p_chip^.trem_val else p_slot^.p_trem := @p_slot^.p_chip^.out_null; p_slot^.reg_vib := (data SHR 6) AND 1; p_slot^.reg_type := (data SHR 5) AND 1; p_slot^.reg_ksr := (data SHR 4) AND 1; p_slot^.reg_mult := data AND $0f; envelope_update_rate(p_slot); end; procedure update_ksl_tl(p_slot: P_OPL3_SLOT; data: Byte); begin p_slot^.reg_ksl := (data SHR 6) AND 3; p_slot^.reg_tl := data AND $3f; envelope_update_ksl(p_slot); end; procedure update_ar_dr(p_slot: P_OPL3_SLOT; data: Byte); begin p_slot^.reg_ar := (data SHR 4) AND $0f; p_slot^.reg_dr := data AND $0f; envelope_update_rate(p_slot); end; procedure update_sl_rr(p_slot: P_OPL3_SLOT; data: Byte); begin p_slot^.reg_sl := SL_VAL[(data SHR 4) AND $0f]; p_slot^.reg_rr := data AND $0f; envelope_update_rate(p_slot); end; procedure slot_generate(p_slot: P_OPL3_SLOT; phase: Word); begin If (phase = WORD_NULL) then phase := WORD(p_slot^.pg_phase SHR 9) + p_slot^.p_mod^; p_slot^.output := envelope_calc_sin(p_slot^.reg_wf,phase,p_slot^.eg_out); end; procedure slot_calc_fb(p_slot: P_OPL3_SLOT); begin If (p_slot^.p_chan^.fb <> 0) then p_slot^.fb_out := (p_slot^.prev_out + p_slot^.output) SHR (9 - p_slot^.p_chan^.fb) else p_slot^.fb_out := 0; p_slot^.prev_out := p_slot^.output; end; procedure chan_set_alg(p_chan: P_OPL3_CHAN); begin Case p_chan^.ch_type of CH_2OP: Case (p_chan^.alg AND 1) of 0: begin // FM p_chan^.p_slot[0]^.p_mod := @p_chan^.p_slot[0]^.fb_out; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; p_chan^.p_out[0] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[1] := @p_chan^.p_chip^.out_null; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; 1: begin // AM p_chan^.p_slot[0]^.p_mod := @p_chan^.p_slot[0]^.fb_out; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_out[0] := @p_chan^.p_slot[0]^.output; p_chan^.p_out[1] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; end; CH_4OP_2: begin p_chan^.p_chan^.p_out[0] := @p_chan^.p_chip^.out_null; p_chan^.p_chan^.p_out[1] := @p_chan^.p_chip^.out_null; p_chan^.p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; Case (p_chan^.alg AND 3) of 0: begin // FM-FM p_chan^.p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.fb_out; p_chan^.p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.output; p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[1]^.output; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; p_chan^.p_out[0] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[1] := @p_chan^.p_chip^.out_null; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; 1: begin // FM-AM p_chan^.p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.fb_out; p_chan^.p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.output; p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; p_chan^.p_out[0] := @p_chan^.p_chan^.p_slot[1]^.output; p_chan^.p_out[1] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; 2: begin // AM-AM p_chan^.p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.fb_out; p_chan^.p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[1]^.output; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; p_chan^.p_out[0] := @p_chan^.p_chan^.p_slot[0]^.output; p_chan^.p_out[1] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[2] := @p_chan^.p_chip^.out_null; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; 3: begin // AM-FM p_chan^.p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[0]^.fb_out; p_chan^.p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_slot[0]^.p_mod := @p_chan^.p_chan^.p_slot[1]^.output; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; p_chan^.p_out[0] := @p_chan^.p_chan^.p_slot[0]^.output; p_chan^.p_out[1] := @p_chan^.p_slot[0]^.output; p_chan^.p_out[2] := @p_chan^.p_slot[1]^.output; p_chan^.p_out[3] := @p_chan^.p_chip^.out_null; end; end; end; CH_RHYTHM: Case (p_chan^.alg AND 1) of 0: begin // FM p_chan^.p_slot[0]^.p_mod := @p_chan^.p_slot[0]^.fb_out; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_slot[0]^.output; end; 1: begin // AM p_chan^.p_slot[0]^.p_mod := @p_chan^.p_slot[0]^.fb_out; p_chan^.p_slot[1]^.p_mod := @p_chan^.p_chip^.out_null; end; end; end; end; procedure chan_update_rhythm(p_chip: P_OPL3_CHIP; data: Byte); begin p_chip^.rhy_flag := data AND $3f; If (p_chip^.rhy_flag AND $20 <> 0) then begin // BD p_chip^.chan[6].ch_type := CH_RHYTHM; p_chip^.chan[6].p_out[0] := @p_chip^.chan[6].p_slot[1]^.output; p_chip^.chan[6].p_out[1] := @p_chip^.chan[6].p_slot[1]^.output; p_chip^.chan[6].p_out[2] := @p_chip^.out_null; p_chip^.chan[6].p_out[3] := @p_chip^.out_null; chan_set_alg(@p_chip^.chan[6]); eg_key_on_off(p_chip^.chan[6].p_slot[0],p_chip^.rhy_flag AND $10 <> 0); eg_key_on_off(p_chip^.chan[6].p_slot[1],p_chip^.rhy_flag AND $10 <> 0); // HH + SD p_chip^.chan[7].ch_type := CH_RHYTHM; p_chip^.chan[7].p_out[0] := @p_chip^.chan[7].p_slot[0]^.output; p_chip^.chan[7].p_out[1] := @p_chip^.chan[7].p_slot[0]^.output; p_chip^.chan[7].p_out[2] := @p_chip^.chan[7].p_slot[1]^.output; p_chip^.chan[7].p_out[3] := @p_chip^.chan[7].p_slot[1]^.output; eg_key_on_off(p_chip^.chan[7].p_slot[0],p_chip^.rhy_flag AND 1 <> 0); eg_key_on_off(p_chip^.chan[7].p_slot[1],p_chip^.rhy_flag AND 8 <> 0); // TT + TC p_chip^.chan[8].ch_type := CH_RHYTHM; p_chip^.chan[8].p_out[0] := @p_chip^.chan[8].p_slot[0]^.output; p_chip^.chan[8].p_out[1] := @p_chip^.chan[8].p_slot[0]^.output; p_chip^.chan[8].p_out[2] := @p_chip^.chan[8].p_slot[1]^.output; p_chip^.chan[8].p_out[3] := @p_chip^.chan[8].p_slot[1]^.output; eg_key_on_off(p_chip^.chan[8].p_slot[0],p_chip^.rhy_flag AND 4 <> 0); eg_key_on_off(p_chip^.chan[8].p_slot[1],p_chip^.rhy_flag AND 2 <> 0); end else begin // reset chan. 6/7/8 to 2OP p_chip^.chan[6].ch_type := CH_2OP; chan_set_alg(@p_chip^.chan[6]); p_chip^.chan[7].ch_type := CH_2OP; chan_set_alg(@p_chip^.chan[7]); p_chip^.chan[8].ch_type := CH_2OP; chan_set_alg(@p_chip^.chan[8]); end; end; procedure update_fnum_block_ksr(p_chan: P_OPL3_CHAN; data: Byte; msb_flag: Boolean); begin If (p_chan^.ch_type = CH_4OP_2) then EXIT; If msb_flag then begin // update upper bits p_chan^.fnum := (p_chan^.fnum AND $300) OR data; p_chan^.ksr := (p_chan^.block SHL 1) OR ((p_chan^.fnum SHR (9 - p_chan^.p_chip^.nts_bit)) AND 1); end else begin // update lower bits p_chan^.fnum := (p_chan^.fnum AND $0ff) OR ((data AND 3) SHL 8); p_chan^.block := (data shr 2) AND 7; p_chan^.ksr := (p_chan^.block SHL 1) OR ((p_chan^.fnum SHR (9 - p_chan^.p_chip^.nts_bit)) AND 1); end; envelope_update_ksl(p_chan^.p_slot[0]); envelope_update_ksl(p_chan^.p_slot[1]); envelope_update_rate(p_chan^.p_slot[0]); envelope_update_rate(p_chan^.p_slot[1]); If (p_chan^.ch_type = CH_4OP_1) then begin p_chan^.p_chan^.fnum := p_chan^.fnum; p_chan^.p_chan^.ksr := p_chan^.ksr; If msb_flag then p_chan^.p_chan^.block := p_chan^.block; envelope_update_ksl(p_chan^.p_chan^.p_slot[0]); envelope_update_ksl(p_chan^.p_chan^.p_slot[1]); envelope_update_rate(p_chan^.p_chan^.p_slot[0]); envelope_update_rate(p_chan^.p_chan^.p_slot[1]); end; end; procedure update_fb_con(p_chan: P_OPL3_CHAN; data: Byte); begin p_chan^.fb := (data AND $0e) SHR 1; p_chan^.con := data AND 1; p_chan^.alg := p_chan^.con; Case p_chan^.ch_type of CH_2OP, CH_RHYTHM: chan_set_alg(p_chan); CH_4OP_1: begin p_chan^.p_chan^.alg := 4 OR (p_chan^.con SHL 1) OR (p_chan^.p_chan^.con); chan_set_alg(p_chan^.p_chan); end; CH_4OP_2: begin p_chan^.alg := 4 OR (p_chan^.p_chan^.con SHL 1) OR (p_chan^.con); chan_set_alg(p_chan); end; end; // trigger output to left If ((data SHR 4) AND 1 <> 0) then p_chan^.out_l := WORD_NULL else p_chan^.out_l := 0; // trigger output to right If ((data SHR 5) AND 1 <> 0) then p_chan^.out_r := WORD_NULL else p_chan^.out_r := 0; end; procedure generate_rhythm_slots(p_chip: P_OPL3_CHIP); var p_slot: P_OPL3_SLOT; phase,phase_lo,phase_hi,phase_bit: Word; procedure calc_phase_slot7_slot8; begin phase_lo := (p_chip^.chan[7].p_slot[0]^.pg_phase SHR 9) AND $3ff; phase_hi := (p_chip^.chan[8].p_slot[1]^.pg_phase SHR 9) AND $3ff; If ((phase_lo AND 8) OR (((phase_lo SHR 5) XOR phase_lo) AND 4) OR (((phase_hi SHR 2) XOR phase_hi) AND 8) <> 0) then phase_bit := 1 else phase_bit := 0; end; begin // BD p_slot := p_chip^.chan[6].p_slot[0]; slot_generate(p_slot,WORD(p_slot^.pg_phase SHR 9) + (p_slot^.p_mod^)); p_slot := p_chip^.chan[6].p_slot[1]; slot_generate(p_slot,WORD(p_slot^.pg_phase SHR 9) + (p_slot^.p_mod^)); // HH p_slot := p_chip^.chan[7].p_slot[0]; calc_phase_slot7_slot8; phase := (phase_bit SHL 9) OR WORD($34 SHL ((phase_bit XOR (p_chip^.noise AND 1) SHL 1))); slot_generate(p_slot,phase); // TT p_slot := p_chip^.chan[8].p_slot[0]; slot_generate(p_slot,WORD(p_slot^.pg_phase SHR 9)); // SD p_slot := p_chip^.chan[7].p_slot[1]; calc_phase_slot7_slot8; phase := ($100 SHL ((phase_lo SHR 8) AND 1)) XOR WORD((p_chip^.noise AND 1) SHL 8); slot_generate(p_slot,phase); // TC p_slot := p_chip^.chan[8].p_slot[1]; phase := $100 OR (phase_bit SHL 9); slot_generate(p_slot,phase); end; procedure update_key(p_chan: P_OPL3_CHAN; key_on: Boolean); begin Case p_chan^.ch_type of CH_2OP, CH_4OP_1, CH_RHYTHM: begin eg_key_on_off(p_chan^.p_slot[0],key_on); eg_key_on_off(p_chan^.p_slot[1],key_on); If (p_chan^.ch_type = CH_4OP_1) then begin eg_key_on_off(p_chan^.p_chan^.p_slot[0],key_on); eg_key_on_off(p_chan^.p_chan^.p_slot[1],key_on); end; end; end; end; procedure chan_update_4op(p_chip: P_OPL3_CHIP; data: Byte); var bit_num: Byte; begin For bit_num := 0 to 5 do If ((data SHR bit_num) AND 1 <> 0) then begin // set chan. to 4OP p_chip^.chan[CH_4OP_IDX[bit_num]].ch_type := CH_4OP_1; p_chip^.chan[CH_4OP_IDX[bit_num]+3].ch_type := CH_4OP_2; end else begin // reset chan. to 2OP p_chip^.chan[CH_4OP_IDX[bit_num]].ch_type := CH_2OP; p_chip^.chan[CH_4OP_IDX[bit_num]+3].ch_type := CH_2OP; end; end; function chip_generate(p_chip: P_OPL3_CHIP): Dword; var slot_num: Byte; accm: Smallint; lr_mix: array[0..1] of Smallint; begin // generate slot data For slot_num := 0 to 35 do begin slot_calc_fb(@p_chip^.slot[slot_num]); pg_generate(@p_chip^.slot[slot_num]); envelope_calc(@p_chip^.slot[slot_num]); slot_generate(@p_chip^.slot[slot_num],WORD_NULL); end; // rhythm mode If (p_chip^.rhy_flag AND $20 <> 0) then generate_rhythm_slots(p_chip); // update channel mixer lr_mix[1] := limit_value(p_chip^.output[1],-$7fff,$7fff); lr_mix[0] := limit_value(p_chip^.output[0],-$7fff,$7fff); p_chip^.output[0] := 0; p_chip^.output[1] := 0; // left output For slot_num := 0 to 17 do begin accm := p_chip^.chan[slot_num].p_out[0]^ + p_chip^.chan[slot_num].p_out[1]^ + p_chip^.chan[slot_num].p_out[2]^ + p_chip^.chan[slot_num].p_out[3]^; Inc(p_chip^.output[0],SMALLINT(accm AND p_chip^.chan[slot_num].out_l)); p_chip^.out_l[slot_num] := SMALLINT(accm AND p_chip^.chan[slot_num].out_l); end; // right output For slot_num := 0 to 17 do begin accm := p_chip^.chan[slot_num].p_out[0]^ + p_chip^.chan[slot_num].p_out[1]^ + p_chip^.chan[slot_num].p_out[2]^ + p_chip^.chan[slot_num].p_out[3]^; Inc(p_chip^.output[1],SMALLINT(accm AND p_chip^.chan[slot_num].out_r)); p_chip^.out_r[slot_num] := SMALLINT(accm AND p_chip^.chan[slot_num].out_r); end; // update LFO tremolo If (p_chip^.timer AND $3f = $3f) then begin If (p_chip^.trem_dir = 0) then begin If (p_chip^.trem_pos < 105) then Inc(p_chip^.trem_pos) else begin Dec(p_chip^.trem_pos); p_chip^.trem_dir := 1; end end else begin If (p_chip^.trem_pos > 0) then Dec(p_chip^.trem_pos) else begin Inc(p_chip^.trem_pos); p_chip^.trem_dir := 0; end; end; p_chip^.trem_val := (p_chip^.trem_pos SHR 2) SHR ((1 - p_chip^.dva_bit) SHL 1); end; // update noise generator If (p_chip^.noise AND 1 <> 0) then p_chip^.noise := p_chip^.noise XOR NOISE_XOR; p_chip^.noise := p_chip^.noise SHR 1; Inc(p_chip^.timer); chip_generate := (WORD(lr_mix[1]) SHL 16) OR WORD(lr_mix[0]); end; procedure OPL3EMU_init; var slot_num, chan_num: Byte; begin // initialize slot data For slot_num := 0 to 35 do begin opl3.slot[slot_num].p_chip := @opl3; opl3.slot[slot_num].p_mod := @opl3.out_null; opl3.slot[slot_num].eg_rout := $1ff; opl3.slot[slot_num].eg_out := $1ff; opl3.slot[slot_num].eg_state := EG_OFF; opl3.slot[slot_num].p_trem := @opl3.out_null; end; // initialize chan. data For chan_num := 0 to 17 do begin opl3.out_l[chan_num] := 0; opl3.out_r[chan_num] := 0; opl3.chan[chan_num].out_l := WORD_NULL; opl3.chan[chan_num].out_r := WORD_NULL; opl3.chan[chan_num].p_chip := @opl3; opl3.chan[chan_num].ch_type := CH_2OP; opl3.chan[chan_num].p_out[0] := @opl3.out_null; opl3.chan[chan_num].p_out[1] := @opl3.out_null; opl3.chan[chan_num].p_out[2] := @opl3.out_null; opl3.chan[chan_num].p_out[3] := @opl3.out_null; opl3.chan[chan_num].p_slot[0] := @opl3.slot[CH_SLOT_IDX[chan_num]]; opl3.chan[chan_num].p_slot[1] := @opl3.slot[CH_SLOT_IDX[chan_num]+3]; opl3.slot[CH_SLOT_IDX[chan_num]].p_chan := @opl3.chan[chan_num]; opl3.slot[CH_SLOT_IDX[chan_num]+3].p_chan := @opl3.chan[chan_num]; If (CH_4OP_MASK[chan_num] <> 0) then opl3.chan[chan_num].p_chan := @opl3.chan[PRED(CH_4OP_MASK[chan_num])]; chan_set_alg(@opl3.chan[chan_num]); end; // initialize chip data opl3.noise := NOISE_HASH_VAL; opl3.timer := 0; opl3.nts_bit := 0; opl3.dva_bit := 0; opl3.dvb_bit := 0; opl3.rhy_flag := 0; opl3.vib_pos := 0; opl3.trem_dir := 0; opl3.trem_pos := 0; opl3.trem_val := 0; opl3.output[0] := 0; opl3.output[1] := 0; end; procedure OPL3EMU_WriteReg(reg: Word; data: Byte); var reg_hi, reg_lo: Byte; begin reg := reg AND $1ff; reg_hi := (reg SHR 8) AND 1; reg_lo := reg AND $0ff; Case reg_lo of // misc. registers $01..$08: If (reg_hi <> 0) then begin If (reg_lo AND $0f = 4) then // 4OP con. sel. chan_update_4op(@opl3,data); end else If (reg_lo AND $0f = 8) then // bit 'NTS' // 0 -> LSB for key is bit 10 of Fnum // 1 -> LSB for key is bit 9 of Fnum opl3.nts_bit := (data SHR 6) AND 1; // AM/VIB/EGT/KSR/MULT $20..$35: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then update_lfo_eg_ksr_mult(@opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])], data); // KSL/TL $40..$55: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then update_ksl_tl(@opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])], data); // AR/DR $60..$75: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then update_ar_dr(@opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])], data); // SL/RR $80..$95: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then update_sl_rr(@opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])], data); // Fnum/block/KSR $0a0..$a8: update_fnum_block_ksr(@opl3.chan[9 * reg_hi + (reg_lo AND $0f)], data,TRUE); // MSB part // Fnum/block/KSR $0b0..$0b8: begin // Fnum/block/KSR update_fnum_block_ksr(@opl3.chan[9 * reg_hi + (reg_lo AND $0f)], data,FALSE); // LSB part // key on/off update_key(@opl3.chan[9 * reg_hi + (reg_lo AND $0f)],data AND $20 <> 0); end; // LFO/rhythm $0bd: If (reg_hi = 0) then begin // bit 'DAM' (LFO tremolo) opl3.dva_bit := data SHR 7; // bit 'DVB' (LFO vibrato) opl3.dvb_bit := (data SHR 6) AND 1; // rhythm mode flag chan_update_rhythm(@opl3,data); end; // slot/feedback/con. $0c0..$0c8: update_fb_con(@opl3.chan[9 * reg_hi + (reg_lo AND $0f)], data); // waveform sel. $0e0..$0f5: If (CH_5BIT_MASK[reg_lo AND $1f] <> 0) then opl3.slot[18 * reg_hi + PRED(CH_5BIT_MASK[reg_lo AND $1f])].reg_wf := data AND 7; end; end; procedure OPL3EMU_PollProc(p_data: pDword; var ch_table); var chan_num: Byte; temp: Dword; begin // assign main output p_data^ := chip_generate(@opl3); // assign per-channel output For chan_num := 0 to 17 do CHAN_PTR_TABLE(ch_table)[chan_num]^:= (WORD(opl3.out_r[CH_MAPPING[chan_num]]) SHL 16) OR WORD(opl3.out_l[CH_MAPPING[chan_num]]); // sort rhythm channels as last If (opl3.rhy_flag AND $20 <> 0) then begin temp := CHAN_PTR_TABLE(ch_table)[15]^; CHAN_PTR_TABLE(ch_table)[15]^ := CHAN_PTR_TABLE(ch_table)[6]^; CHAN_PTR_TABLE(ch_table)[6]^ := temp; temp := CHAN_PTR_TABLE(ch_table)[16]^; CHAN_PTR_TABLE(ch_table)[16]^ := CHAN_PTR_TABLE(ch_table)[7]^; CHAN_PTR_TABLE(ch_table)[7]^ := temp; temp := CHAN_PTR_TABLE(ch_table)[17]^; CHAN_PTR_TABLE(ch_table)[17]^ := CHAN_PTR_TABLE(ch_table)[8]^; CHAN_PTR_TABLE(ch_table)[8]^ := temp; end; end; end. adlibtracker2-2.4.24/adt2ext3.pas0000644000000000000000000006765713411003760015175 0ustar rootroot// 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 AdT2ext3; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface procedure a2m_file_loader; procedure a2t_file_loader; procedure a2p_file_loader; procedure a2i_file_loader; procedure a2f_file_loader; procedure amd_file_loader; procedure cff_file_loader; procedure dfm_file_loader; procedure fmk_file_loader; procedure hsc_file_loader; procedure mtk_file_loader; procedure rad_file_loader; procedure s3m_file_loader; procedure sat_file_loader; procedure sa2_file_loader; procedure cif_file_loader; procedure fin_file_loader; procedure ins_file_loader; procedure sbi_file_loader; procedure sgi_file_loader; procedure fselect_external_proc; procedure import_standard_instrument_alt(var data); procedure test_instrument_alt(chan: Byte; fkey: Word; loadMacros: Boolean; bankSelector: Boolean; loadArpVib: Boolean; test_ins1,test_ins2: Byte); procedure test_instrument_alt2(chan: Byte; fkey: Word); implementation uses DOS, AdT2opl3,AdT2sys,AdT2keyb,AdT2unit,AdT2extn,AdT2ext2,AdT2ext4,AdT2ext5,AdT2text,AdT2pack, StringIO,DialogIO,ParserIO,TxtScrIO,DepackIO; {$i iloadins.inc} {$i iloaders.inc} procedure a2i_file_loader; type tOLD_HEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Byte; end; type tHEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Word; end; const id = '_A2ins_'; var f: File; header: tOLD_HEADER; header2: tHEADER; temp,temp2: Longint; ins_4op: Word; crc: Word; temp_ins,temp_ins2: tADTRACK2_INS; temp_str,temp_str2: String; _4op_ins_flag: Boolean; _4op_ins_idx: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:a2i_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2I]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; init_old_songdata; If (header.ffver in [1..4]) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf2,header.b0len,crc); If (crc <> header.crc16) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; Case header.ffver of 4: Move(buf2,buf3,header.b0len); 3: LZSS_decompress(buf2,buf3,header.b0len); 2: LZW_decompress(buf2,buf3); 1: SIXPACK_decompress(buf2,buf3,header.b0len); end; Move(buf3, old_songdata.instr_data[1], SizeOf(old_songdata.instr_data[1])); Move(buf3[SizeOf(old_songdata.instr_data[1])], temp_str, buf3[SizeOf(old_songdata.instr_data[1])]+1); old_songdata.instr_data[1].panning := 0; If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); old_songdata.instr_names[1] := Copy(old_songdata.instr_names[1],1,9)+truncate_string(temp_str); import_single_old_instrument(Addr(old_songdata),current_inst,1); end; If (header.ffver in [5..8]) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf2,header.b0len,crc); If (crc <> header.crc16) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; Case header.ffver of 8: Move(buf2,buf3,header.b0len); 7: LZSS_decompress(buf2,buf3,header.b0len); 6: LZW_decompress(buf2,buf3); 5: SIXPACK_decompress(buf2,buf3,header.b0len); end; Move(buf3, old_songdata.instr_data[1], SizeOf(old_songdata.instr_data[1])); Move(buf3[SizeOf(old_songdata.instr_data[1])], temp_str, buf3[SizeOf(old_songdata.instr_data[1])]+1); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); old_songdata.instr_names[1] := Copy(old_songdata.instr_names[1],1,9)+truncate_string(temp_str); import_single_old_instrument(Addr(old_songdata),current_inst,1); end; If (header.ffver = 9) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; BlockReadF(f,buf2,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; crc := WORD_NULL; crc := Update16(header2.b0len,1,crc); crc := Update16(buf2,header2.b0len,crc); If (crc <> header2.crc16) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; APACK_decompress(buf2,buf3); Move(buf3, songdata.instr_data[current_inst], SizeOf(songdata.instr_data[current_inst])); Move(buf3[SizeOf(songdata.instr_data[current_inst])], temp_str, buf3[SizeOf(songdata.instr_data[current_inst])]+1); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+truncate_string(temp_str); end; If (header.ffver = FFVER_A2I) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; BlockReadF(f,buf2,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; crc := WORD_NULL; crc := Update16(header2.b0len,1,crc); crc := Update16(buf2,header2.b0len,crc); If (crc <> header2.crc16) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2i LOADER ',1); EXIT; end; _4op_ins_flag := FALSE; progress_num_steps := 0; temp := 0; temp2 := LZH_decompress(buf2,buf3,header2.b0len); Move(buf3[temp],temp_ins,SizeOf(temp_ins)); Inc(temp,SizeOf(temp_ins)); // instrument data Move(buf3[temp],temp_str,SUCC(buf3[temp])); Inc(temp,SUCC(buf3[temp])); // instrument name If (temp < temp2) then // more data present => 4op instrument begin _4op_ins_flag := TRUE; Move(buf3[temp],temp_ins2,SizeOf(temp_ins2)); Inc(temp,SizeOf(temp_ins2)); Move(buf3[temp],temp_str2,SUCC(buf3[temp])); Inc(temp,SUCC(buf3[temp])); end; If NOT _4op_ins_flag then begin ins_4op := check_4op_to_test; If (ins_4op <> 0) then begin reset_4op_flag(HI(ins_4op)); update_4op_flag_marks; end; Move(temp_ins,songdata.instr_data[current_inst],SizeOf(temp_ins)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+truncate_string(temp_str); end else begin _4op_ins_idx := current_inst; set_4op_flag(current_inst); update_4op_flag_marks; If (_4op_ins_idx = 255) then Dec(_4op_ins_idx); // 4OP 1/2 Move(temp_ins,songdata.instr_data[_4op_ins_idx],SizeOf(temp_ins)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source))+' [4OP 1/2]'; songdata.instr_names[_4op_ins_idx] := Copy(songdata.instr_names[_4op_ins_idx],1,9)+truncate_string(temp_str); // 4OP 2/2 Move(temp_ins2,songdata.instr_data[SUCC(_4op_ins_idx)],SizeOf(temp_ins2)); If (temp_str2 = '') then temp_str2 := Lower(NameOnly(instdata_source))+' [4OP 2/2]'; songdata.instr_names[SUCC(_4op_ins_idx)] := Copy(songdata.instr_names[SUCC(_4op_ins_idx)],1,9)+truncate_string(temp_str2); end; end; CloseF(f); load_flag := 1; end; procedure a2f_file_loader; type tHEADER = Record ident: array[1..18] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; const id = '_a2ins_w/fm-macro_'; var f: File; header: tHEADER; crc,temp,temp2: Longint; ins_4op: Word; temp_ins,temp_ins2: tADTRACK2_INS; temp_str,temp_str2: String; temp_macro: tREGISTER_TABLE; temp_macro2: tREGISTER_TABLE; temp_dis_fmreg_col: tDIS_FMREG_COL; temp_dis_fmreg_col2: tDIS_FMREG_COL; _4op_ins_flag: Boolean; _4op_ins_idx: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:a2f_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2F]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; If (header.ffver = 1) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,1,crc); crc := Update32(buf2,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; APACK_decompress(buf2,buf3); Move(buf3, songdata.instr_data[current_inst], SizeOf(songdata.instr_data[current_inst])); Move(buf3[SizeOf(songdata.instr_data[current_inst])], temp_str, buf3[SizeOf(songdata.instr_data[current_inst])]+1); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+truncate_string(temp_str); Move(buf3[SizeOf(songdata.instr_data[current_inst])+ buf3[SizeOf(songdata.instr_data[current_inst])]+1], songdata.instr_macros[current_inst], SizeOf(songdata.instr_macros[current_inst])); Move(buf3[SizeOf(songdata.instr_data[current_inst])+ buf3[SizeOf(songdata.instr_data[current_inst])]+1+ SizeOf(songdata.instr_macros[current_inst])], songdata.dis_fmreg_col[current_inst], SizeOf(songdata.dis_fmreg_col[current_inst])); end; If (header.ffver = FFVER_A2F) then begin BlockReadF(f,buf2,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; crc := DWORD_NULL; crc := Update32(header.b0len,1,crc); crc := Update32(buf2,header.b0len,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2F LOADER ',1); EXIT; end; _4op_ins_flag := FALSE; progress_num_steps := 0; temp := 0; temp2 := LZH_decompress(buf2,buf3,header.b0len); Move(buf3[temp],temp_ins,SizeOf(temp_ins)); Inc(temp,SizeOf(temp_ins)); // instrument data Move(buf3[temp],temp_str,SUCC(buf3[temp])); Inc(temp,SUCC(buf3[temp])); // instrument name Move(buf3[temp],temp_macro,SizeOf(temp_macro)); Inc(temp,SizeOf(temp_macro)); // FM-macro data Move(buf3[temp],temp_dis_fmreg_col,SizeOf(temp_dis_fmreg_col)); Inc(temp,SizeOf(temp_dis_fmreg_col)); // disabled FM-macro column data If (temp < temp2) then // more data present => 4op instrument begin _4op_ins_flag := TRUE; Move(buf3[temp],temp_ins2,SizeOf(temp_ins2)); Inc(temp,SizeOf(temp_ins2)); Move(buf3[temp],temp_str2,SUCC(buf3[temp])); Inc(temp,SUCC(buf3[temp])); Move(buf3[temp],temp_macro2,SizeOf(temp_macro2)); Inc(temp,SizeOf(temp_macro2)); Move(buf3[temp],temp_dis_fmreg_col2,SizeOf(temp_dis_fmreg_col2)); end; If NOT _4op_ins_flag then begin ins_4op := check_4op_to_test; If (ins_4op <> 0) then begin reset_4op_flag(HI(ins_4op)); update_4op_flag_marks; end; Move(temp_ins,songdata.instr_data[current_inst],SizeOf(temp_ins)); Move(temp_macro,songdata.instr_macros[current_inst],SizeOf(temp_macro)); Move(temp_dis_fmreg_col,songdata.dis_fmreg_col[current_inst],SizeOf(temp_dis_fmreg_col)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+truncate_string(temp_str); end else begin _4op_ins_idx := current_inst; set_4op_flag(current_inst); update_4op_flag_marks; If (_4op_ins_idx = 255) then Dec(_4op_ins_idx); // 4OP 1/2 Move(temp_ins,songdata.instr_data[_4op_ins_idx],SizeOf(temp_ins)); Move(temp_macro,songdata.instr_macros[_4op_ins_idx],SizeOf(temp_macro)); Move(temp_dis_fmreg_col,songdata.dis_fmreg_col[_4op_ins_idx],SizeOf(temp_dis_fmreg_col)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source))+' [4OP 1/2]'; songdata.instr_names[_4op_ins_idx] := Copy(songdata.instr_names[_4op_ins_idx],1,9)+truncate_string(temp_str); // 4OP 2/2 Move(temp_ins2,songdata.instr_data[SUCC(_4op_ins_idx)],SizeOf(temp_ins2)); Move(temp_macro2,songdata.instr_macros[SUCC(_4op_ins_idx)],SizeOf(temp_macro2)); Move(temp_dis_fmreg_col2,songdata.dis_fmreg_col[SUCC(_4op_ins_idx)],SizeOf(temp_dis_fmreg_col2)); If (temp_str2 = '') then temp_str2 := Lower(NameOnly(instdata_source))+' [4OP 2/2]'; songdata.instr_names[SUCC(_4op_ins_idx)] := Copy(songdata.instr_names[SUCC(_4op_ins_idx)],1,9)+truncate_string(temp_str2); end; end; CloseF(f); load_flag := 1; end; procedure cif_file_loader; const id = ''+#26; type tCIF_DATA = Record ident: array[1..20] of Char; idata: tFM_INST_DATA; resrv: Byte; iname: array[1..20] of Char; end; var f: File; buffer: tCIF_DATA; temp: Longint; temp_str: String; const MIN_CIF_SIZE = SizeOf(buffer.ident)+ SizeOf(buffer.idata)+ SizeOf(buffer.resrv); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:cif_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CiF LOADER ',1); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If NOT ((temp >= MIN_CIF_SIZE) and (buffer.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CiF LOADER ',1); EXIT; end; import_hsc_instrument(current_inst,buffer.idata); songdata.instr_data[current_inst].fine_tune := 0; temp_str := truncate_string(buffer.iname); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+temp_str; CloseF(f); load_flag := 1; end; procedure fin_file_loader; var f: File; buffer: tFIN_DATA; temp: Longint; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:fin_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiN LOADER ',1); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If (temp <> SizeOf(buffer)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FiN LOADER ',1); EXIT; end; import_fin_instrument(current_inst,buffer.idata); If (Length(truncate_string(buffer.iname)) <= 32) then temp_str := truncate_string(buffer.iname) else temp_str := Lower(truncate_string(buffer.dname)); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+Copy(temp_str,1,32); CloseF(f); load_flag := 1; end; procedure ins_file_loader; type tINS_DATA = Record idata: tFM_INST_DATA; slide: Byte; _SAdT: array[0..18] of Byte; end; var f: File; buffer: tINS_DATA; temp: Longint; function correct_ins(var data): Boolean; var result: Boolean; begin result := TRUE; If NOT (tADTRACK2_INS(data).fm_data.WAVEFORM_modulator in [0..3]) then result := FALSE; If NOT (tADTRACK2_INS(data).fm_data.WAVEFORM_carrier in [0..3]) then result := FALSE; If NOT (tADTRACK2_INS(data).fm_data.FEEDBACK_FM in [0..15]) then result := FALSE; correct_ins := result; end; begin { ins_file_loader } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:ins_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iNS LOADER ',1); EXIT; end; If (FileSize(f) > SizeOf(buffer)) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT TYPE$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iNS LOADER ',1); EXIT; end; BlockReadF(f,buffer,FileSize(f),temp); If (temp <> FileSize(f)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' iNS LOADER ',1); EXIT; end; Case force_ins of 0: begin If (temp = 12) then import_standard_instrument(current_inst,buffer.idata); If (temp = 12) and NOT correct_ins(buffer.idata) then import_hsc_instrument(current_inst,buffer.idata) else If (temp > 12) then import_sat_instrument(current_inst,buffer.idata); end; 1: import_hsc_instrument(current_inst,buffer.idata); 2: import_sat_instrument(current_inst,buffer.idata); 3: import_standard_instrument(current_inst,buffer.idata); end; songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+ Lower(NameOnly(instdata_source)); CloseF(f); load_flag := 1; end; procedure sbi_file_loader; const id = 'SBI'+#26; type tSBI_DATA = Record ident: array[1..4] of Char; iname: array[1..32] of Char; idata: tFM_INST_DATA; dummy: array[1..5] of Byte; end; var f: File; buffer: tSBI_DATA; temp: Longint; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:sbi_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SBi LOADER ',1); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If NOT ((temp = SizeOf(buffer)) and (buffer.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SBi LOADER ',1); EXIT; end; import_standard_instrument(current_inst,buffer.idata); temp_str := truncate_string(buffer.iname); If (temp_str = '') then temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+Copy(temp_str,1,32); CloseF(f); load_flag := 1; end; procedure import_sgi_instrument(inst: Byte; var data); begin FillChar(songdata.instr_data[inst], SizeOf(songdata.instr_data[inst]),0); With songdata.instr_data[inst] do begin fm_data.ATTCK_DEC_modulator := (pBYTE(@data)[1] AND $0f)+ (pBYTE(@data)[0] AND $0f) SHL 4; fm_data.SUSTN_REL_modulator := (pBYTE(@data)[3] AND $0f)+ (pBYTE(@data)[2] AND $0f) SHL 4; fm_data.WAVEFORM_modulator := (pBYTE(@data)[4] AND 3); fm_data.KSL_VOLUM_modulator := (pBYTE(@data)[7] AND $3f)+ (pBYTE(@data)[6] AND 3) SHL 6; fm_data.AM_VIB_EG_modulator := (pBYTE(@data)[5] AND $0f)+ (pBYTE(@data)[8] AND 1) SHL 4+ (pBYTE(@data)[11] AND 1) SHL 5+ (pBYTE(@data)[10] AND 1) SHL 6+ (pBYTE(@data)[9] AND 1) SHL 7; fm_data.ATTCK_DEC_carrier := (pBYTE(@data)[13] AND $0f)+ (pBYTE(@data)[12] AND $0f) SHL 4; fm_data.SUSTN_REL_carrier := (pBYTE(@data)[15] AND $0f)+ (pBYTE(@data)[14] AND $0f) SHL 4; fm_data.WAVEFORM_carrier := (pBYTE(@data)[16] AND 3); fm_data.KSL_VOLUM_carrier := (pBYTE(@data)[19] AND $3f)+ (pBYTE(@data)[18] AND 3) SHL 6; fm_data.AM_VIB_EG_carrier := (pBYTE(@data)[17] AND $0f)+ (pBYTE(@data)[20] AND 1) SHL 4+ (pBYTE(@data)[23] AND 1) SHL 5+ (pBYTE(@data)[22] AND 1) SHL 6+ (pBYTE(@data)[21] AND 1) SHL 7; fm_data.FEEDBACK_FM := (pBYTE(@data)[25] AND 1)+ (pBYTE(@data)[24] AND 7) SHL 1; end; end; procedure sgi_file_loader; type tSGI_DATA = Record { 0} attack_m, { 1} decay_m, { 2} sustain_m, { 3} release_m, { 4} waveform_m, { 5} mfmult_m, { 6} ksl_m, { 7} volume_m, { 8} ksr_m, { 9} tremolo_m, {10} vibrato_m, {11} eg_type_m, {12} attack_c, {13} decay_c, {14} sustain_c, {15} release_c, {16} waveform_c, {17} mfmult_c, {18} ksl_c, {19} volume_c, {20} ksr_c, {21} tremolo_c, {22} vibrato_c, {23} eg_type_c, {24} feedback, {25} fm: Byte; end; var f: File; buffer: tSGI_DATA; temp: Longint; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT3.PAS:sgi_file_loader'; {$ENDIF} {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SGi LOADER ',1); EXIT; end; BlockReadF(f,buffer,SizeOf(buffer),temp); If (temp <> SizeOf(buffer)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SGi LOADER ',1); EXIT; end; import_sgi_instrument(current_inst,buffer); temp_str := Lower(NameOnly(instdata_source)); songdata.instr_names[current_inst] := Copy(songdata.instr_names[current_inst],1,9)+Copy(temp_str,1,32); CloseF(f); load_flag := 1; end; end. adlibtracker2-2.4.24/utils/0000755000000000000000000000000013414571004014151 5ustar rootrootadlibtracker2-2.4.24/utils/data.com0000644000000000000000000000164113411003760015560 0ustar rootroot¿o ;ür´LÍ!¾¿¹Îýó¥ü‹÷¿­­‹è²éåÿÿ¼´I´ º¶Í!¾€¬´ÿï“Æèq€<u çÇñç¸Lû‹Öèÿb‹ÞèVƸ=în·sàÞàÿ¿û࣮Ì‹òÿÿ¬<.t Àu÷ÆDÿ.ÇißnÇDcë#¾ ¾íþ£t´>‹€ïÌÇ» ùß»´<¹ ¦;àã1㣰´?÷Çé¹@º´ïºàOsé¬ ”ù‰Çÿ£²¾é½¿´¸ d?ð«¸d «ƒ>ëÛÆEÿÿþbë°,ª°0ª¬è¡°hãªÿæuíë1ëÜŠDèŠúè„úŸÿè~õèzƒÀÞÆÌÖƒ.¼·ùrMuϸ «´@`Üxr‹Ïy+ÊwGuå&Þï€éZÿC<œøÚ;ðÝ·;Ž èàØÉ"Êß tûNÃùwù¸SŠØÐëþüÿƒã$ŠŸžˆGêñÿЇ÷ª[ÃDATA V1.óÿ1 B ary Filÿøe AssemblòDataÿã Maker - bïShÿãayde/RealitñApxÄrÐ '944$ýUÀsage:ÖþǨíìb­f®Æn<Ëstö>¸®ÙàüÃxø§If "‡ÿß" is nôot given4hûwoutpýçto8ÀÖ©ïà.INC"¯DÑumpÓ×>wã;añrawçD ™ð""úªtîw. unit AdT2opl3; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface {$IFDEF GO32V2} const ___OPL3OUT_UNIT_DATA_START___: Dword = 0; {$ENDIF} procedure opl2out(reg,data: Word); procedure opl3out_proc(reg,data: Word); procedure opl3exp(data: Word); type tOPL3OUT_proc = procedure(reg,data: Word); const opl3out: tOPL3OUT_proc = opl3out_proc; {$IFDEF GO32V2} const opl3port: Word = 0; opl_latency: Byte = 0; function detect_OPL3: Boolean; {$ELSE} const renew_wav_files_flag: Boolean = TRUE; opl3_channel_recording_mode: Boolean = FALSE; opl3_record_channel: array[1..20] of Boolean = ( FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE, FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE); procedure flush_WAV_data; procedure opl3_init; procedure opl3_done; procedure snd_init; procedure snd_done; procedure snd_SetTimer(value: Longint); procedure update_recorded_channels; const opl3_flushmode: Boolean = FALSE; const WAV_BUFFER_SIZE = 18*512*1024; // cache buffer size -> 512k per file var wav_buffer_len: Longint; wav_buffer: array[0..18,0..PRED(WAV_BUFFER_SIZE)] of Byte; {$ENDIF} {$IFDEF GO32V2} const ___OPL3OUT_UNIT_DATA_END___: Dword = 0; {$ENDIF} implementation {$IFDEF GO32V2} uses GO32, AdT2sys, TxtScrIO; procedure ___OPL3OUT_IRQ_CODE_START___; begin end; var _opl_regs_cache: array[WORD] of Word; procedure opl2out(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(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; procedure ___OPL3OUT_IRQ_CODE_END___; begin end; function detect_OPL3: Boolean; var result: Boolean; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2OPL3.PAS:detect_OPL3'; asm push dword 04h push dword 80h push dword 04h push dword 60h call opl2out call WaitRetrace call opl2out call WaitRetrace mov dx,opl3port in al,dx and al,0e0h mov bl,al push dword 04h push dword 21h push dword 02h push dword 0ffh call opl2out call WaitRetrace call opl2out call WaitRetrace mov dx,opl3port in al,dx and al,0e0h mov bh,al cmp bx,0c000h jnz @@1 push dword 04h push dword 80h push dword 04h push dword 60h call opl2out call WaitRetrace call opl2out call WaitRetrace mov dx,opl3port in al,dx and al,6 or al,al jnz @@1 mov result,TRUE jmp @@2 @@1: mov result,FALSE @@2: end; detect_OPL3 := result; end; {$ELSE} uses MATH,SysUtils, AdT2unit,AdT2sys,TxtScrIO,StringIO, SDL_Types,SDL_Audio,OPL3EMU; const opl3_sample_buffer_ptr: Pointer = NIL; opl3_sample_buffer_chan_ptr: array[1..18] of Pointer = ( NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL,NIL); var sample_frame_size: Longint; sdl_audio_spec: SDL_AudioSpec; procedure flush_WAV_data; type tWAV_HEADER = Record file_desc: array[0..3] of Char; // =="RIFF" file_size: Dword; // ==filesize-8 wav_desc: array[0..3] of Char; // =="WAVE" format_desc: array[0..3] of Char; // =="fmt " wav_size: Dword; // ==16 wav_type: Word; // ==1 (PCM) num_channels: Word; // ==2 (Stereo) samples_sec: Dword; // sampling frequency bytes_sec: Dword; // ==num_channels*samples_sec*bits_sample/8 block_align: Word; // ==num_channels*bits_sample/8 bits_sample: Word; // ==16 data_desc: array[0..3] of Char; // "data" data_size: Dword; // size of data end; const wav_header: tWAV_HEADER = (file_desc: 'RIFF'; file_size: SizeOf(tWAV_HEADER)-8; wav_desc: 'WAVE'; format_desc: 'fmt '; wav_size: 16; wav_type: 1; num_channels: 2; samples_sec: 49716; bytes_sec: 2*49716*16 DIV 8; block_align: 2*16 DIV 8; bits_sample: 16; data_desc: 'data'; data_size: 0); var wav_file: File; temp,bytes_to_write: Longint; idx,from_ch,to_ch: Byte; filename_suffix: String; begin bytes_to_write := wav_buffer_len; // flush when at least 1 sec of recorded data If (bytes_to_write < 2*sdl_sample_rate*16 DIV 8) then EXIT; If NOT ((play_status = isPlaying) and (sdl_opl3_emulator <> 0)) then EXIT; // prepare output directory If NOT DirectoryExists(Copy(sdl_wav_directory,1,Length(sdl_wav_directory)-Length(NameOnly(sdl_wav_directory)))) then If NOT CreateDir(Copy(sdl_wav_directory,1,Length(sdl_wav_directory)-Length(NameOnly(sdl_wav_directory)))) then EXIT; wav_buffer_len := 0; If NOT opl3_channel_recording_mode then begin from_ch := 0; to_ch := 0; end else begin from_ch := 1; If NOT percussion_mode then to_ch := songdata.nm_tracks else to_ch := 18; end; For idx := from_ch to to_ch do begin filename_suffix := ''; If (idx <> 0) then If NOT (opl3_record_channel[idx]) or (is_4op_chan(idx) and NOT (idx in _4op_tracks_hi)) then CONTINUE else If NOT is_4op_chan(idx) then If percussion_mode then Case idx of 16: filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+'_BD)'; 17: filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+'_SD_HH)'; 18: filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+'_TT_TC)'; else filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+')'; end else filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+')' else filename_suffix := ' ('+ExpStrL(Num2str(idx,10),2,'0')+'_' +ExpStrL(Num2str(idx+1,10),2,'0')+'_4OP)'; If opl3_flushmode then Assign(wav_file,Copy(sdl_wav_directory,1,Length(sdl_wav_directory)-Length(NameOnly(sdl_wav_directory)))+ BaseNameOnly(sdl_wav_directory)+filename_suffix+'.wav') else Assign(wav_file,sdl_wav_directory+BaseNameOnly(songdata_title)+filename_suffix+'.wav'); // update WAV header {$i-} If renew_wav_files_flag then begin RewriteF(wav_file); wav_header.file_size := 0; wav_header.data_size := 0; end else ResetF(wav_file); {$i+} If renew_wav_files_flag or (IOresult <> 0) then begin {$i-} RewriteF(wav_file); {$i+} If (IOresult <> 0) then begin Close(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; wav_header.samples_sec := sdl_sample_rate; wav_header.bytes_sec := 2*sdl_sample_rate*16 DIV 8; wav_header.file_size := bytes_to_write; wav_header.data_size := bytes_to_write; {$i-} BlockWriteF(wav_file,wav_header,SizeOf(wav_header),temp); {$i+} If (IOresult <> 0) or (temp <> SizeOf(wav_header)) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; end else begin {$i-} BlockReadF(wav_file,wav_header,SizeOf(wav_header),temp); {$i+} If (IOresult <> 0) or (temp <> SizeOf(wav_header)) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; wav_header.file_size := wav_header.file_size+bytes_to_write; wav_header.data_size := wav_header.data_size+bytes_to_write; {$i-} ResetF_RW(wav_file); {$i+} If (IOresult <> 0) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; {$i-} BlockWriteF(wav_file,wav_header,SizeOf(wav_header),temp); {$i+} If (IOresult <> 0) or (temp <> SizeOf(wav_header)) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; {$i-} SeekF(wav_file,FileSize(wav_file)); {$i+} If (IOresult <> 0) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; EXIT; end; end; // write sample data {$i-} BlockWriteF(wav_file,wav_buffer[idx],bytes_to_write,temp); {$i+} If (IOresult <> 0) or (temp <> bytes_to_write) then begin CloseF(wav_file); {$i-} EraseF(wav_file); {$i+} If (IOresult <> 0) then ; end else CloseF(wav_file); end; renew_wav_files_flag := FALSE; end; procedure opl2out(reg,data: Word); begin // relevant only for DOS version -> option opl_latency=1 opl3out_proc(reg,data); end; procedure opl3out_proc(reg,data: Word); begin OPL3EMU_WriteReg(reg,data); end; procedure opl3exp(data: Word); begin OPL3EMU_WriteReg((data AND $ff) OR $100,data SHR 8); end; procedure opl3_init; begin OPL3EMU_init; end; procedure opl3_done; begin SDL_PauseAudio(1); end; // value in Hz for timer procedure snd_SetTimer(value: Longint); begin If (value < 18) then value := 18; sample_frame_size := ROUND(sdl_sample_rate/value*(1+sdl_timer_slowdown/100)); end; function get_num_files: Byte; var idx,result: Byte; begin result := 18; For idx := 1 to 18 do If NOT opl3_record_channel[idx] then Dec(result); If (result <> 0) then get_num_files := result else get_num_files := 1; end; procedure update_recorded_channels; var idx: Byte; begin For idx := 1 to 20 do If channel_flag[idx] then opl3_record_channel[idx] := TRUE else opl3_record_channel[idx] := FALSE; For idx := SUCC(songdata.nm_tracks) to 20 do opl3_record_channel[idx] := FALSE; If percussion_mode then begin If NOT channel_flag[19] then opl3_record_channel[18] := FALSE; If NOT channel_flag[20] then opl3_record_channel[17] := FALSE; end; end; procedure playcallback(var userdata; stream: pByte; len: Longint); cdecl; const counter_idx: Longint = 0; var counter: Longint; idx: Byte; IRQ_freq_val: Longint; buffer_ptr_table: array[1..18] of pDword; buf_size: Longint; begin If NOT rewind then IRQ_freq_val := IRQ_freq else IRQ_freq_val := IRQ_freq * 20; For counter := 0 to PRED(len DIV 4) do begin Inc(counter_idx); If (counter_idx >= sample_frame_size) then begin counter_idx := 0; 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_val DIV tempo) then ticklooper := 0; Inc(macro_ticklooper); If (macro_ticklooper >= IRQ_freq_val DIV (tempo*macro_speedup)) then macro_ticklooper := 0; end; // update partial channel sample buffer pointers For idx := 1 to 18 do buffer_ptr_table[idx] := opl3_sample_buffer_chan_ptr[idx]+counter*4; // update one step OPL3EMU_PollProc(opl3_sample_buffer_ptr+counter*4,buffer_ptr_table); end; // update SDL Audio sample buffer Move(opl3_sample_buffer_ptr^,stream^,len); If (play_status = isStopped) then begin wav_buffer_len := 0; EXIT; end; // calculate cache buffer size If opl3_channel_recording_mode then buf_size := WAV_BUFFER_SIZE DIV 18 * get_num_files else buf_size := WAV_BUFFER_SIZE DIV 18; // WAV dumper If (sdl_opl3_emulator <> 0) then If (wav_buffer_len+len <= buf_size) then begin // update main sample buffer Move(opl3_sample_buffer_ptr^,wav_buffer[0][wav_buffer_len],len); // update partial channel sample buffers For idx := 1 to 18 do Move(opl3_sample_buffer_chan_ptr[idx]^,wav_buffer[idx][wav_buffer_len],len); Inc(wav_buffer_len,len); end else begin // sample buffers full -> flush to disk! flush_WAV_data; // update main sample buffer Move(opl3_sample_buffer_ptr^,wav_buffer[0][wav_buffer_len],len); // update partial channel sample buffers For idx := 1 to 18 do Move(opl3_sample_buffer_chan_ptr[idx]^,wav_buffer[idx][wav_buffer_len],len); Inc(wav_buffer_len,len); end; end; procedure snd_init; var idx: Byte; begin GetMem(opl3_sample_buffer_ptr,sdl_sample_buffer*4); For idx := 1 to 18 do GetMem(opl3_sample_buffer_chan_ptr[idx],sdl_sample_buffer*4); sample_frame_size := ROUND(sdl_sample_rate/50*(1+sdl_timer_slowdown/100));; opl3_init; sdl_audio_spec.freq := sdl_sample_rate; sdl_audio_spec.format := AUDIO_S16; sdl_audio_spec.channels := 2; sdl_audio_spec.samples := sdl_sample_buffer; @sdl_audio_spec.callback := @playcallback; sdl_audio_spec.userdata := NIL; If (SDL_Openaudio(@sdl_audio_spec,NIL) < 0) then begin WriteLn('SDL: Audio initialization error'); HALT(1); end; WriteLn(' Sample buffer size: ',sdl_audio_spec.samples,' samples (requested ',sdl_sample_buffer,')'); WriteLn(' Sampling rate: ',sdl_audio_spec.freq,' Hz (requested ',sdl_sample_rate,')'); sdl_sample_rate := sdl_audio_spec.freq; sdl_sample_buffer := sdl_audio_spec.samples; SDL_PauseAudio(0); end; procedure snd_done; var idx: Byte; begin SDL_PauseAudio(1); SDL_CloseAudio; FreeMem(opl3_sample_buffer_ptr); For idx := 1 to 18 do FreeMem(opl3_sample_buffer_chan_ptr[idx]); opl3_sample_buffer_ptr := NIL; end; {$ENDIF} {$IFDEF GO32V2} var old_exit_proc: procedure; procedure new_exit_proc; begin Lock_Data(___OPL3OUT_UNIT_DATA_START___,DWORD(Addr(___OPL3OUT_UNIT_DATA_END___))-DWORD(Addr(___OPL3OUT_UNIT_DATA_START___))); Lock_Code(@___OPL3OUT_IRQ_CODE_START___,DWORD(@___OPL3OUT_IRQ_CODE_END___)-DWORD(@___OPL3OUT_IRQ_CODE_START___)); ExitProc := @old_exit_proc; end; begin FillWord(_opl_regs_cache,SizeOf(_opl_regs_cache) DIV SizeOf(WORD),NOT 0); Lock_Data(___OPL3OUT_UNIT_DATA_START___,DWORD(Addr(___OPL3OUT_UNIT_DATA_END___))-DWORD(Addr(___OPL3OUT_UNIT_DATA_START___))); Lock_Code(@___OPL3OUT_IRQ_CODE_START___,DWORD(@___OPL3OUT_IRQ_CODE_END___)-DWORD(@___OPL3OUT_IRQ_CODE_START___)); @old_exit_proc := ExitProc; ExitProc := @new_exit_proc; {$ENDIF} end. adlibtracker2-2.4.24/txtscrio.pas0000644000000000000000000024363713411003760015410 0ustar rootroot// 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 SCREEN_RES_x: Word = 720; SCREEN_RES_y: Word = 480; MAX_COLUMNS: Byte = 90; MAX_ROWS: Byte = 40; MAX_TRACKS: Byte = 5; MAX_ORDER_COLS: Byte = 9; MAX_PATTERN_ROWS: Byte = 18; INSCTRL_xshift: Byte = 0; INSCTRL_yshift: Shortint = 0; INSEDIT_yshift: Byte = 0; PATTORD_xshift: Byte = 0; GOTOXY_xshift: Byte = 0; 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 temp_screen: tSCREEN_MEM; temp_screen2: tSCREEN_MEM; screen_backup: tSCREEN_MEM; scr_backup: tSCREEN_MEM; scr_backup2: tSCREEN_MEM; screen_mirror: tSCREEN_MEM; screen_emulator: tSCREEN_MEM; centered_frame_vdest: tSCREEN_MEM_PTR; text_screen_shadow: tSCREEN_MEM; const screen_ptr: Pointer = Addr(text_screen_shadow); ptr_temp_screen: Pointer = Addr(temp_screen); ptr_temp_screen2: Pointer = Addr(temp_screen2); ptr_screen_backup: Pointer = Addr(screen_backup); ptr_scr_backup: Pointer = Addr(scr_backup); ptr_scr_backup2: Pointer = Addr(scr_backup2); ptr_screen_mirror: Pointer = Addr(screen_mirror); ptr_screen_emulator: Pointer = Addr(screen_emulator); const move_to_screen_data: Pointer = NIL; move_to_screen_area: array[1..4] of Byte = (0,0,0,0); move_to_screen_routine: procedure = NIL; const program_screen_mode: Byte = 0; const MaxLn: Byte = 0; MaxCol: Byte = 0; hard_maxcol: Byte = 0; hard_maxln: Byte = 0; work_maxcol: Byte = 0; work_maxln: Byte = 0; scr_font_width: Byte = 0; scr_font_height: Byte = 0; const area_x1: Byte = 0; area_y1: Byte = 0; area_x2: Byte = 0; area_y2: Byte = 0; scroll_pos0: Byte = BYTE(NOT 0); scroll_pos1: Byte = BYTE(NOT 0); scroll_pos2: Byte = BYTE(NOT 0); scroll_pos3: Byte = BYTE(NOT 0); scroll_pos4: Byte = BYTE(NOT 0); var cursor_backup: Longint; 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; procedure ShowStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; attr: Byte); procedure ShowVStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; attr: Byte); procedure ShowCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); procedure ShowCStr2(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); procedure ShowVCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); procedure ShowVCStr2(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); procedure ShowC3Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3: Byte); procedure ShowVC3Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3: Byte); procedure ShowC4Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); procedure show_str(xpos,ypos: Byte; str: String; color: Byte); procedure show_cstr(xpos,ypos: Byte; str: String; attr1,attr2: Byte); procedure show_cstr_alt(xpos,ypos: Byte; str: String; attr1,attr2: Byte); procedure show_vstr(xpos,ypos: Byte; str: String; color: Byte); procedure show_vcstr(xpos,ypos: Byte; str: String; attr1,attr2: Byte); function CStrLen(str: String): Byte; function CStr2Len(str: String): Byte; function C3StrLen(str: String): Byte; procedure ScreenMemCopy(source,dest: tSCREEN_MEM_PTR); procedure move2screen; procedure move2screen_alt; procedure TxtScrIO_Init; function is_default_screen_mode: Boolean; {$IFDEF GO32V2} function is_VESA_emulated_mode: Boolean; function get_VESA_emulated_mode_idx: Byte; {$ENDIF} function is_scrollable_screen_mode: Boolean; type tFRAME_SETTING = Record shadow_enabled, wide_range_type, zooming_enabled, update_area: Boolean; end; const fr_setting: tFRAME_SETTING = (shadow_enabled: TRUE; wide_range_type: FALSE; zooming_enabled: FALSE; update_area: TRUE); procedure Frame(dest: tSCREEN_MEM_PTR; x1,y1,x2,y2,atr1: Byte; title: String; atr2: Byte; border: String); 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); const v_seg: Word = $0b800; v_ofs: Word = 0; v_mode: Byte = $03; {$IFDEF GO32V2} var DispPg: Byte; type tCUSTOM_VIDEO_MODE = 0..52; function iVGA: Boolean; procedure initialize; procedure ResetMode; procedure SetCustomVideoMode(vmode: tCUSTOM_VIDEO_MODE); procedure GetRGBitem(color: Byte; var red,green,blue: Byte); procedure SetRGBitem(color: Byte; red,green,blue: Byte); procedure WaitRetrace; procedure GetPalette(var pal; first,last: Word); procedure SetPalette(var pal; first,last: Word); 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; procedure VgaFade(var data: tFADE_BUF; fade: tFADE; delay: tDELAY); procedure RefreshEnable; procedure RefreshDisable; procedure Split2Static; procedure SplitScr(line: Word); procedure SetSize(columns,lines: Word); procedure SetTextDisp(x,y: Word); procedure set_vga_txtmode_80x25; procedure set_svga_txtmode_100x38; procedure set_svga_txtmode_128x48; procedure set_custom_svga_txtmode; type VGA_REGISTER = Record port: Word; idx: Byte; val: Byte; end; type VGA_REG_DATA = array[1..29] of VGA_REGISTER; const svga_txtmode_cols: Byte = 100; svga_txtmode_rows: Byte = 37; svga_txtmode_regs: VGA_REG_DATA = ( (port: $3c2; idx: $00; val: $06b), // Miscellaneous output (port: $3d4; idx: $00; val: $070), // Horizontal total (port: $3d4; idx: $01; val: $063), // Horizontal display enable end (port: $3d4; idx: $02; val: $064), // Horizontal blank start (port: $3d4; idx: $03; val: $082), // Horizontal blank end (port: $3d4; idx: $04; val: $065), // Horizontal retrace start (port: $3d4; idx: $05; val: $082), // Horizontal retrace end (port: $3d4; idx: $06; val: $070), // Vertical total (port: $3d4; idx: $07; val: $0f0), // Overflow register (port: $3d4; idx: $08; val: $000), // Preset row scan (port: $3d4; idx: $09; val: $04f), // Maximum scan line/char height (port: $3d4; idx: $10; val: $05b), // Vertical retrace start (port: $3d4; idx: $11; val: $08c), // Vertical retrace end (port: $3d4; idx: $12; val: $04f), // Vertical display enable end (port: $3d4; idx: $13; val: $03c), // Offset/logical width (port: $3d4; idx: $14; val: $000), // Underline location (port: $3d4; idx: $15; val: $058), // Vertical blank start (port: $3d4; idx: $16; val: $070), // Vertical blank end (port: $3d4; idx: $17; val: $0a3), // Mode control (port: $3c4; idx: $01; val: $001), // Clock mode register (port: $3c4; idx: $03; val: $000), // Character generator select (port: $3c4; idx: $04; val: $000), // Memory mode register (port: $3ce; idx: $05; val: $010), // Mode register (port: $3ce; idx: $06; val: $00e), // Miscellaneous register (port: $3c0; idx: $10; val: $002), // Mode control (port: $3c0; idx: $11; val: $000), // Screen border color (port: $3c0; idx: $12; val: $00f), // Color plane enable (port: $3c0; idx: $13; val: $000), // Horizontal panning (port: $3c0; idx: $14; val: $000)); // Color select {$ENDIF} implementation uses {$IFDEF GO32V2} CRT,GO32, {$ENDIF} AdT2unit,AdT2sys,AdT2ext2, DialogIO,ParserIO; procedure show_str(xpos,ypos: Byte; str: String; color: Byte); var x11,x12,x21,x22,y11,y21: Byte; index: Byte; begin asm xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos add bl,index sub bl,2 mov ah,ypos dec ah mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos add al,index dec al mov ah,ypos cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx movsb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 lodsb jmp @@6 @@5: add edi,ebx lodsb mov ah,color stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; procedure show_cstr(xpos,ypos: Byte; str: String; attr1,attr2: Byte); var x11,x12,x21,x22,y11,y21: Byte; index,color1,color2: Byte; begin asm mov al,attr1 mov color1,al mov al,attr2 mov color2,al xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos add bl,index sub bl,2 mov ah,ypos dec ah mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos add al,index dec al mov ah,ypos cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx @@3a: lodsb cmp al,'~' jnz @@3b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@3a cmp al,'~' jz @@7 @@3b: stosb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 @@4a: lodsb cmp al,'~' jnz @@6 push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@4a jmp @@7 @@5: add edi,ebx @@5a: lodsb cmp al,'~' jnz @@5b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@5a jmp @@7 @@5b: mov ah,color1 stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; procedure show_cstr_alt(xpos,ypos: Byte; str: String; attr1,attr2: Byte); var x11,x12,x21,x22,y11,y21: Byte; index,color1,color2: Byte; begin asm mov al,attr1 mov color1,al mov al,attr2 mov color2,al xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos add bl,index sub bl,2 mov ah,ypos dec ah mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos add al,index dec al mov ah,ypos cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx @@3a: lodsb cmp al,10 jnz @@3b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@3a cmp al,10 jz @@7 @@3b: stosb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 @@4a: lodsb cmp al,10 jnz @@6 push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@4a jmp @@7 @@5: add edi,ebx @@5a: lodsb cmp al,10 jnz @@5b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@5a jmp @@7 @@5b: mov ah,color1 stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; procedure show_vstr(xpos,ypos: Byte; str: String; color: Byte); var x11,x12,x21,x22,y11,y21: Byte; index: Byte; begin asm xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos dec bl mov ah,ypos add ah,index sub ah,2 mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos mov ah,ypos add ah,index dec ah cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx movsb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 lodsb jmp @@6 @@5: add edi,ebx lodsb mov ah,color stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; procedure show_vcstr(xpos,ypos: Byte; str: String; attr1,attr2: Byte); var x11,x12,x21,x22,y11,y21: Byte; index,color1,color2: Byte; begin asm mov al,attr1 mov color1,al mov al,attr2 mov color2,al xor ebx,ebx xor ecx,ecx mov edi,dword ptr [screen_ptr] mov edx,edi lea esi,[str] lodsb mov cl,al or ecx,ecx jz @@7 mov al,area_x1 mov x11,al inc x11 mov x12,al add x12,2 mov al,area_x2 mov x21,al inc x21 mov x22,al add x22,2 mov al,area_y1 mov y11,al inc y11 mov al,area_y2 mov y21,al inc y21 mov index,1 @@1: mov edi,edx xor bx,bx mov bl,xpos dec bl mov ah,ypos add ah,index sub ah,2 mov al,MaxCol mul ah add bx,ax shl bx,1 mov al,xpos mov ah,ypos add ah,index dec ah cmp al,x12 jnae @@2 cmp al,x22 jnbe @@2 cmp ah,y21 jne @@2 jmp @@3 @@2: cmp al,x21 jnae @@4 cmp al,x22 jnbe @@4 cmp ah,y11 jnae @@4 cmp ah,y21 jnbe @@4 @@3: add edi,ebx @@3a: lodsb cmp al,'~' jnz @@3b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@3a cmp al,'~' jz @@7 @@3b: stosb jmp @@6 @@4: cmp al,area_x1 jnae @@5 cmp al,area_x2 jnbe @@5 cmp ah,area_y1 jnae @@5 cmp ah,area_y2 jnbe @@5 @@4a: lodsb cmp al,'~' jnz @@6 push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@4a jmp @@7 @@5: add edi,ebx @@5a: lodsb cmp al,'~' jnz @@5b push eax mov al,color1 mov ah,color2 xchg al,ah mov color1,al mov color2,ah pop eax dec cl cmp index,cl jbe @@5a jmp @@7 @@5b: mov ah,color1 stosw @@6: inc index cmp index,cl jbe @@1 @@7: end; end; 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 ShowStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; attr: Byte); begin asm mov edi,dword ptr [dest] lea esi,[str] mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos lodsb mov cl,al jecxz @@2 add edi,edx mov ah,attr @@1: lodsb stosw loop @@1 @@2: end; end; procedure ShowVStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; attr: Byte); begin asm mov al,MaxCol dec al xor ah,ah xor ebx,ebx mov bl,2 mul bl mov bx,ax mov edi,dword ptr [dest] lea esi,[str] mov al,x mov ah,y xor ecx,ecx call DupChar xor edx,edx mov dx,absolute_pos lodsb mov cl,al jecxz @@2 add edi,edx mov ah,attr @@1: lodsb stosw add edi,ebx loop @@1 @@2: end; end; procedure ShowCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: 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 bh,atr2 @@1: lodsb cmp al,'~' jz @@2 stosw loop @@1 jmp @@3 @@2: xchg ah,bh loop @@1 @@3: end; end; procedure ShowCStr2(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: 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 bh,atr2 @@1: lodsb cmp al,'"' jz @@2 stosw loop @@1 jmp @@3 @@2: xchg ah,bh loop @@1 @@3: end; end; procedure ShowVCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); begin asm mov al,MaxCol dec al xor ah,ah mov bl,2 mul bl mov bx,ax 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 dx,bx mov ah,atr1 mov bh,atr2 @@1: lodsb cmp al,'~' jz @@2 stosw add edi,edx loop @@1 jmp @@3 @@2: xchg ah,bh loop @@1 @@3: end; end; procedure ShowVCStr2(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2: Byte); begin asm mov al,MaxCol dec al xor ah,ah mov bl,2 mul bl mov bx,ax 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 dx,bx mov ah,atr1 mov bh,atr2 @@1: lodsb cmp al,'`' jz @@2 stosw add edi,edx loop @@1 jmp @@3 @@2: xchg ah,bh loop @@1 @@3: end; end; procedure ShowC3Str(dest: tSCREEN_MEM_PTR; 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 @@4 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 ShowC4Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); begin asm lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@5 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 mov dl,atr4 @@1: lodsb cmp al,'~' jz @@2 cmp al,'`' jz @@3 cmp al,'^' jz @@4 stosw loop @@1 jmp @@5 @@2: xchg ah,bl loop @@1 jmp @@5 @@3: xchg ah,bh loop @@1 jmp @@5 @@4: xchg ah,dl loop @@1 @@5: end; end; procedure ShowVC3Str(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3: Byte); begin asm mov al,MaxCol dec al xor ah,ah mov bl,2 mul bl mov bx,ax lea esi,[str] mov edi,dword ptr [dest] lodsb xor ecx,ecx mov cl,al jecxz @@4 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 dx,bx mov ah,atr1 mov bl,atr2 mov bh,atr3 @@1: lodsb cmp al,'~' jz @@2 cmp al,'`' jz @@3 stosw add edi,edx loop @@1 jmp @@4 @@2: xchg ah,bl loop @@1 jmp @@4 @@3: xchg ah,bh loop @@1 @@4: end; end; function CStrLen(str: String): Byte; var result: Byte; begin asm lea esi,[str] lodsb xor ebx,ebx xor ecx,ecx mov cl,al jecxz @@3 @@1: lodsb cmp al,'~' jz @@2 inc ebx loop @@1 jmp @@3 @@2: loop @@1 @@3: mov eax,ebx mov result,al end; CStrLen := result; end; function CStr2Len(str: String): Byte; var result: Byte; begin asm lea esi,[str] lodsb xor ebx,ebx xor ecx,ecx mov cl,al jecxz @@3 @@1: lodsb cmp al,'`' jz @@2 inc ebx loop @@1 jmp @@3 @@2: loop @@1 @@3: mov eax,ebx mov result,al end; CStr2Len := result; end; function C3StrLen(str: String): Byte; var result: Byte; begin asm lea esi,[str] lodsb xor ebx,ebx xor ecx,ecx mov cl,al jecxz @@4 @@1: lodsb cmp al,'~' jz @@2 cmp al,'`' jz @@3 inc ebx loop @@1 jmp @@4 @@2: loop @@1 jmp @@4 @@3: loop @@1 @@4: mov eax,ebx mov result,al end; C3StrLen := result; 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; procedure Frame(dest: tSCREEN_MEM_PTR; x1,y1,x2,y2,atr1: Byte; title: String; atr2: Byte; border: String); var xexp1,xexp2,xexp3,yexp1,yexp2: Byte; offs: Longint; begin asm cmp fr_setting.update_area,1 jnz @@0 mov al,x1 mov area_x1,al mov al,y1 mov area_y1,al mov al,x2 mov area_x2,al mov al,y2 mov area_y2,al @@0: mov bl,fr_setting.wide_range_type mov bh,fr_setting.shadow_enabled lea esi,[border] mov edi,[dest] mov offs,edi cmp bl,0 je @@1 mov xexp1,4 mov xexp2,-1 mov xexp3,7 mov yexp1,1 mov yexp2,2 jmp @@2 @@1: mov xexp1,1 mov xexp2,2 mov xexp3,1 mov yexp1,0 mov yexp2,1 jmp @@4 @@2: mov al,x1 sub al,3 mov ah,y1 dec ah mov dl,' ' mov dh,atr1 xor ecx,ecx mov cl,x2 sub cl,x1 add cl,7 call DupChar mov ah,y2 inc ah call DupChar mov bl,y1 @@3: mov al,x1 sub al,3 mov ah,bl mov dl,' ' mov ecx,3 call DupChar mov al,x2 inc al mov dl,' ' mov ecx,3 call DupChar inc bl cmp bl,y2 jng @@3 @@4: mov al,x1 mov ah,y1 mov dl,[esi+1] mov dh,atr1 mov ecx,1 push edi call DupChar inc al mov dl,[esi+2] mov dh,atr1 mov cl,x2 sub cl,x1 dec cl call DupChar mov al,x2 mov dl,[esi+3] mov dh,atr1 mov ecx,1 call DupChar mov bl,y1 @@5: inc bl mov al,x1 mov ah,bl mov dl,[esi+4] mov dh,atr1 mov ecx,1 call DupChar inc al mov dl,' ' mov dh,atr1 mov cl,x2 sub cl,x1 dec cl call DupChar mov al,x2 mov dl,[esi+5] mov dh,atr1 mov ecx,1 call DupChar cmp bl,y2 jnge @@5 mov al,x1 mov ah,y2 mov dl,[esi+6] mov dh,atr1 mov ecx,1 call DupChar inc al mov dl,[esi+7] mov cl,x2 sub cl,x1 dec cl call DupChar mov al,x2 mov dl,[esi+8] mov dh,atr1 mov ecx,1 call DupChar lea esi,[title] mov cl,[esi] jecxz @@7 xor eax,eax mov al,x2 sub al,x1 sub al,cl mov bl,2 div bl add al,x1 add al,ah mov ah,y1 xor ecx,ecx call DupChar push eax xor eax,eax mov ax,absolute_pos mov edi,offs add edi,eax pop eax lodsb mov cl,al mov ah,atr2 @@6: lodsb stosw loop @@6 @@7: cmp bh,0 je @@11 mov bl,y1 sub bl,yexp1 @@8: inc bl mov al,x2 add al,xexp1 mov ah,bl xor ecx,ecx call DupChar push eax xor eax,eax mov ax,absolute_pos mov edi,offs add edi,eax pop eax inc edi mov al,07 stosb inc edi stosb cmp MaxCol,180 jna @@9 inc edi stosb @@9: cmp bl,y2 jng @@8 mov al,x1 add al,xexp2 mov ah,y2 add ah,yexp2 xor ecx,ecx call DupChar push eax xor eax,eax mov ax,absolute_pos mov edi,offs add edi,eax pop eax inc edi mov al,07 mov cl,x2 sub cl,x1 add cl,xexp3 cmp MaxLn,60 jb @@10 dec cl @@10: stosb inc edi loop @@10 @@11: end; end; {$IFDEF GO32V2} 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 lea edi,[virtual_cur_pos] mov ah,y mov al,x stosw mov dh,y mov dl,x add dl,GOTOXY_xshift 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 lea edi,[virtual_cur_pos] mov ax,word ptr [cursor+2] stosw 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 ax,shape mov word ptr [virtual_cur_shape],ax 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; {$ELSE} function WhereX: Byte; begin WhereX := virtual_cur_pos AND $0ff; end; function WhereY: Byte; begin WhereY := virtual_cur_pos SHR 8; end; procedure GotoXY(x,y: Byte); begin virtual_cur_pos := x OR (y SHL 8); end; function GetCursor: Longint; begin GetCursor := 0; end; procedure SetCursor(cursor: Longint); begin virtual_cur_pos := cursor SHR 16; SetCursorShape(cursor AND WORD_NULL); end; procedure ThinCursor; begin SetCursorShape($0d0e); end; procedure WideCursor; begin SetCursorShape($010e); end; procedure HideCursor; begin SetCursorShape($1010); end; function GetCursorShape: Word; begin GetCursorShape := virtual_cur_shape; end; procedure SetCursorShape(shape: Word); begin virtual_cur_shape := shape; end; {$ENDIF} {$IFDEF GO32V2} procedure initialize; begin asm mov ah,0fh int 10h and al,7fh mov v_mode,al mov DispPg,bh end; MaxCol := MEM[SEG0040:$4a]; MaxLn := SUCC(MEM[SEG0040:$84]); work_MaxLn := MaxLn; work_MaxCol := MaxCol; FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); 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 ResetMode; begin asm xor ah,ah mov al,v_mode mov bh,DispPg int 10h end; v_seg := $0b800; v_ofs := 0; MaxCol := MEM[SEG0040:$4a]; MaxLn := SUCC(MEM[SEG0040:$84]); FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); 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 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; 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 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,0,255); If delay = delayed then For i := fade_speed downto 0 do begin For j := 0 to 255 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,0,255); CRT.Delay(1); end else begin FillChar(data.pal1,SizeOf(data.pal1),0); SetPalette(data.pal1,0,255); 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 := 0 to 255 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,0,255); CRT.Delay(1); end else SetPalette(data.pal0,0,255); data.action := fadeIn; end; end; procedure RefreshEnable; begin asm mov ax,1200h mov bl,36h int 10h end; end; procedure RefreshDisable; begin asm mov ax,1201h mov bl,36h int 10h end; end; procedure Split2Static; begin inportb($3da); outportb($3c0,$10 OR $20); outportb($3c0,inportb($3c1) OR $20); end; procedure SplitScr(line: Word); var temp: Byte; begin outportb($3d4,$18); outportb($3d5,LO(line)); outportb($3d4,$07); temp := inportb($3d5); If (line < $100) then temp := temp AND $0ef else temp := temp OR $10; outportb($3d5,temp); outportb($3d4,$09); temp := inportb($3d5); If (line < $200) then temp := temp AND $0bf else temp := temp OR $40; outportb($3d5,temp); end; procedure SetSize(columns,lines: Word); begin outportb($3d4,$13); outportb($3d5,columns SHR 1); MEMW[Seg0040:$4a] := columns; MEMW[Seg0040:$84] := lines-1; MEMW[Seg0040:$4c] := columns*lines; end; procedure SetTextDisp(x,y: Word); var maxcol_val: Byte; begin While (inportb($3da) AND 1 = 1) do ; While (inportb($3da) AND 1 <> 1) do ; If NOT (program_screen_mode in [4,5]) then maxcol_val := MaxCol else maxcol_val := SCREEN_RES_X DIV scr_font_width; outportb($3d4,$0c); outportw($3d5,HI(WORD((y DIV scr_font_height)*maxcol_val+(x DIV scr_font_width)))); outportb($3d4,$0d); outportw($3d5,LO(WORD((y DIV scr_font_height)*maxcol_val+(x DIV scr_font_width)))); outportb($3d4,$08); outportb($3d5,(inportb($3d5) AND $0e0) OR (y AND $0f)); end; procedure SetCustomVideoMode(vmode: tCUSTOM_VIDEO_MODE); const vmode_data: array[0..52,0..63] of Byte = ( { 1..5 - BIOS variables, 6..9 - Sequencer, 10 - Miscellaneous Output, 11..35 - CRTC, 36..55 - Attribute, 56..64 - Graphics } { 0, Text 36x14, 9x14, complete } ( 36, 13, 14, 0, 4, 8, 3, 0, 2, 99, 40, 35, 36,138, 38,192,183, 31, 0,205, 11, 12, 0, 0, 0, 0,148,134,135, 18, 31,142,177,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 1, Text 40x14, 8x14, complete } ( 40, 13, 14, 0, 5, 9, 3, 0, 2, 99, 45, 39, 40,144, 43,160,183, 31, 0,205, 11, 12, 0, 0, 0, 0,148,134,135, 20, 31,142,177,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 2, Text 40x14, 9x14, complete } ( 40, 13, 14, 0, 5, 8, 3, 0, 2, 103, 45, 39, 40,144, 43,160,183, 31, 0,205, 11, 12, 0, 0, 0, 0,148,134,135, 20, 31,142,177,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 3, Text 46x14, 8x14, complete } ( 46, 13, 14, 0, 6, 9, 3, 0, 2, 103, 52, 45, 46,151, 50,150,183, 31, 0,205, 11, 12, 0, 0, 0, 0,148,134,135, 23, 31,142,177,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 4, Text 36x15, 9x16, complete } ( 36, 14, 16, 0, 5, 8, 3, 0, 2, 227, 40, 35, 36,138, 38,192, 11, 62, 0,207, 13, 14, 0, 0, 0, 0,234,172,223, 18, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 5, Text 40x15, 8x16, complete } ( 40, 14, 16, 0, 5, 9, 3, 0, 2, 227, 45, 39, 40,144, 43,160, 11, 62, 0,207, 13, 14, 0, 0, 0, 0,234,172,223, 20, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 6, Text 40x15, 9x16, complete } ( 40, 14, 16, 0, 5, 8, 3, 0, 2, 231, 45, 39, 40,144, 43,160, 11, 62, 0,207, 13, 14, 0, 0, 0, 0,234,172,223, 20, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 7, Text 46x15, 8x16, complete } ( 46, 14, 16, 0, 6, 9, 3, 0, 2, 231, 52, 45, 46,151, 50,150, 11, 62, 0,207, 13, 14, 0, 0, 0, 0,234,172,223, 23, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 8, Text 36x17, 9x14, complete } ( 36, 16, 14, 0, 5, 8, 3, 0, 2, 227, 40, 35, 36,138, 38,192, 7, 62, 0,205, 11, 12, 0, 0, 0, 0,230,168,219, 18, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 9, Text 40x17, 8x14, complete } ( 40, 16, 14, 0, 6, 9, 3, 0, 2, 227, 45, 39, 40,144, 43,160, 7, 62, 0,205, 11, 12, 0, 0, 0, 0,230,168,219, 20, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 10, Text 40x17, 9x14, complete } ( 40, 16, 14, 0, 6, 8, 3, 0, 2, 231, 45, 39, 40,144, 43,160, 7, 62, 0,205, 11, 12, 0, 0, 0, 0,230,168,219, 20, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 11, Text 46x17, 9x14, complete } ( 46, 16, 14, 0, 7, 9, 3, 0, 2, 231, 52, 45, 46,151, 50,150, 7, 62, 0,205, 11, 12, 0, 0, 0, 0,230,168,219, 23, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 12, Text 36x22, 9x16, complete } ( 36, 21, 16, 0, 7, 8, 3, 0, 2, 163, 40, 35, 36,138, 38,192,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 18, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 13, Text 40x22, 8x16, complete } ( 40, 21, 16, 0, 7, 9, 3, 0, 2, 163, 45, 39, 40,144, 43,160,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 20, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 14, Text 40x22, 9x16, complete } ( 40, 21, 16, 0, 7, 8, 3, 0, 2, 167, 45, 39, 40,144, 43,160,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 20, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 15, Text 46x22, 8x16, complete } ( 46, 21, 16, 0, 8, 9, 3, 0, 2, 167, 52, 45, 46,151, 50,150,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 23, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 16, Text 70x22, 9x16, complete } ( 70, 21, 16, 0,13, 0, 3, 0, 2, 163, 83, 69, 70,150, 75, 21,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 35, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 17, Text 80x22, 8x16, complete } ( 80, 21, 16, 0,14, 1, 3, 0, 2, 163, 95, 79, 80,130, 85,129,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 40, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 18, Text 80x22, 9x16, complete } ( 80, 21, 16, 0,14, 0, 3, 0, 2, 167, 95, 79, 80,130, 85,129,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 40, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 19, Text 90x22, 8x16, complete } ( 90, 21, 16, 0,16, 1, 3, 0, 2, 167, 107, 89, 90,142, 95,138,193, 31, 0, 79, 13, 14, 0, 0, 0, 0,133,165, 95, 45, 31,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 20, Text 36x25, 9x16, complete } ( 36, 24, 16, 0, 8, 8, 3, 0, 2, 99, 40, 35, 36,138, 38,192,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 18, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 21, Text 40x25, 8x16, complete } ( 40, 24, 16, 0, 8, 9, 3, 0, 2, 99, 45, 39, 40,144, 43,160,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 20, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 22, Text 40x25, 9x16, complete } ( 40, 24, 16, 0, 8, 8, 3, 0, 2, 103, 45, 39, 40,144, 43,160,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 20, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 23, Text 46x25, 8x16, complete } ( 46, 24, 16, 0,10, 9, 3, 0, 2, 103, 52, 45, 46,151, 50,150,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 23, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 24, Text 70x25, 9x16, complete } ( 70, 24, 16, 0,14, 0, 3, 0, 2, 99, 83, 69, 70,150, 75, 21,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 35, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 25, Text 80x25, 8x16, complete } ( 80, 24, 16, 0,16, 1, 3, 0, 2, 99, 95, 79, 80,130, 85,129,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 26, Text 80x25, 9x16, standard } ( 80, 24, 16, 0,16, 0, 3, 0, 2, 103, 95, 79, 80,130, 85,129,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 27, Text 90x25, 8x16, complete } ( 90, 24, 16, 0, 18 , 1, 3, 0, 2, 103, 107, 89, 90,142, 95,138,191, 31, 0, 79, 13, 14, 0, 0, 0, 0,156,142,143, 45, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 28, Text 46x29, 8x16, complete } ( 46, 28, 14, 0,11, 9, 3, 0, 2, 103, 52, 45, 46,151, 50,150,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 23, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 29, Text 70x29, 9x14, complete } ( 70, 28, 14, 0, 16 , 0, 3, 0, 2, 99, 83, 69, 70,150, 75, 21,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 35, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 30, Text 80x29, 8x14, complete } ( 80, 28, 14, 0, 19 , 1, 3, 0, 2, 99, 95, 79, 80,130, 85,129,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 40, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 31, Text 80x29, 9x14, complete } ( 80, 28, 14, 0, 19 , 0, 3, 0, 2, 103, 95, 79, 80,130, 85,129,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 40, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 32, Text 90x29, 8x14, complete } ( 90, 28, 14, 0, 21 , 1, 3, 0, 2, 103, 107, 89, 90,142, 95,138,193, 31, 0, 77, 11, 12, 0, 0, 0, 0,159,145,149, 45, 31,155,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 33, Text 70x30, 9x16, complete } ( 70, 29, 16, 0, 17 , 0, 3, 0, 2, 227, 83, 69, 70,150, 75, 21, 11, 62, 0, 79, 13, 14, 0, 0, 0, 0,234,172,223, 35, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 34, Text 80x30, 8x16, complete } ( 80, 29, 16, 0, 19 , 1, 3, 0, 2, 227, 95, 79, 80,130, 85,129, 11, 62, 0, 79, 13, 14, 0, 0, 0, 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 35, Text 80x30, 9x16, complete } ( 80, 29, 16, 0, 19 , 0, 3, 0, 2, 231, 95, 79, 80,130, 85,129, 11, 62, 0, 79, 13, 14, 0, 0, 0, 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 36, Text 90x30, 8x16 ,complete } ( 90, 29, 16, 0, 22 , 1, 3, 0, 2, 231, 107, 89, 90,142, 95,138, 11, 62, 0, 79, 13, 14, 0, 0, 0, 0,234,172,223, 45, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 37, Text 70x34, 9x14, complete } ( 70, 33, 14, 0, 19 , 0, 3, 0, 2, 227, 83, 69, 70,150, 75, 21, 7, 62, 0, 77, 11, 12, 0, 0, 0, 0,230,168,219, 35, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 38, Text 80x34, 8x14, complete } ( 80, 33, 14, 0, 22 , 1, 3, 0, 2, 227, 95, 79, 80,130, 85,129, 7, 62, 0, 77, 11, 12, 0, 0, 0, 0,230,168,219, 40, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 39, Text 80x34, 9x14, complete } ( 80, 33, 14, 0, 22 , 0, 3, 0, 2, 231, 95, 79, 80,130, 85,129, 7, 62, 0, 77, 11, 12, 0, 0, 0, 0,230,168,219, 40, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 40, Text 90x34, 8x14, complete } ( 90, 33, 14, 0, 24 , 1, 3, 0, 2, 231, 107, 89, 90,142, 95,138, 7, 62, 0, 77, 11, 12, 0, 0, 0, 0,230,168,219, 45, 31,227, 2,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 41, Text 70x44, 9x8, complete } ( 70, 43, 8, 0,25, 0, 3, 0, 2, 163, 83, 69, 70,150, 75, 21,193, 31, 0, 71, 6, 7, 0, 0, 0, 0,133,135, 95, 35, 15,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 42, Text 80x44, 8x8, complete } ( 80, 43, 8, 0,28, 1, 3, 0, 2, 163, 95, 79, 80,130, 85,129,193, 31, 0, 71, 6, 7, 0, 0, 0, 0,133,135, 95, 40, 15,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 43, Text 80x44, 9x8, complete } ( 80, 43, 8, 0,28, 0, 3, 0, 2, 167, 95, 79, 80,130, 85,129,193, 31, 0, 71, 6, 7, 0, 0, 0, 0,133,135, 95, 40, 15,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 44, Text 90x44, 8x8, complete } ( 90, 43, 8, 0,31, 1, 3, 0, 2, 167, 107, 89, 90,142, 95,138,193, 31, 0, 71, 6, 7, 0, 0, 0, 0,133,135, 95, 45, 15,101,187,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 45, Text 70x50, 9x8, complete } ( 70, 49, 8, 0,28, 0, 3, 0, 2, 99, 83, 69, 70,150, 75, 21,191, 31, 0, 71, 6, 7, 0, 0, 0, 0,156,142,143, 35, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 46, Text 80x50, 8x8, complete } ( 80, 49, 8, 0,32, 1, 3, 0, 2, 99, 95, 79, 80,130, 85,129,191, 31, 0, 71, 6, 7, 0, 0, 0, 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 47, Text 80x50, 9x8, standard } ( 80, 49, 8, 0,32, 0, 3, 0, 2, 103, 95, 79, 80,130, 85,129,191, 31, 0, 71, 6, 7, 0, 0, 0, 0,156,142,143, 40, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 12, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 48, Text 90x50, 8x8, complete } ( 90, 49, 8, 0, 36 , 1, 3, 0, 2, 103, 107, 89, 90,142, 95,138,191, 31, 0, 71, 6, 7, 0, 0, 0, 0,156,142,143, 45, 31,150,185,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 49, Text 70x60, 9x8, complete } ( 70, 59, 8, 0, 33 , 0, 3, 0, 2, 227, 83, 69, 70,150, 75, 21, 11, 62, 0, 71, 6, 7, 0, 0, 0, 0,234,172,223, 35, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 50, Text 80x60, 8x8, complete } ( 80, 59, 8, 0, 38 , 1, 3, 0, 2, 227, 95, 79, 80,130, 85,129, 11, 62, 0, 71, 6, 7, 0, 0, 0, 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 51, Text 80x60, 9x8, complete } ( 80, 59, 8, 0, 38 , 0, 3, 0, 2, 231, 95, 79, 80,130, 85,129, 11, 62, 0, 71, 6, 7, 0, 0, 0, 0,234,172,223, 40, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 8, 0, 0, 0, 0, 0, 16, 14, 0, 255), { 52, Text 90x60, 8x8, complete } ( 90, 59, 8,128, 42 , 1, 3, 0, 2, 231, 107, 89, 90,142, 95,138, 11, 62, 0, 71, 6, 7, 0, 0, 0, 0,234,172,223, 45, 31,231, 6,163,255, 0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63, 8, 0, 15, 0, 0, 0, 0, 0, 0, 16, 14, 0, 255) ); var _seg0040: Dword; temp: Byte; begin _seg0040 := Seg0040; asm movzx eax,vmode shl eax,6 lea esi,[vmode_data] add esi,eax mov dx,3cch in al,dx mov dl,0d4h test al,1 jnz @@1 mov dl,0b4h @@1: add dx,6 in al,dx xor al,al mov dx,3c0h out dx,al mov ax,100h mov dx,3c4h out dx,ax add esi,5 mov ecx,4 mov al,1 mov dx,3c4h @@2: mov ah,[esi] inc esi out dx,ax inc al loop @@2 mov al,[esi] inc esi mov dx,3c2h out dx,al mov dx,3c4h mov ax,300h out dx,ax mov dx,3cch in al,dx mov dl,0d4h test al,1 jnz @@3 mov dl,0b4h @@3: mov edi,_seg0040 shl edi,4 add edi,63h shl edi,4 mov [edi],dx mov al,11h out dx,al inc dx mov ah,al in al,dx dec dx xchg al,ah and ah,7fh out dx,ax mov ecx,25 xor al,al @@4: mov ah,[esi] inc esi out dx,ax inc al loop @@4 add dx,6 in al,dx xor ah,ah mov ecx,20 mov dx,3c0h @@5: mov al,ah out dx,al inc ah mov al,[esi] inc esi out dx,al loop @@5 xor al,al mov ecx,9 mov dx,3ceh @@6: mov ah,[esi] inc esi out dx,ax inc al loop @@6 mov dx,3c0h mov al,32 out dx,al end; MEM[SEG0040:$4a] := vmode_data[vmode,0]; MEM[SEG0040:$84] := vmode_data[vmode,1]; MEM[SEG0040:$85] := vmode_data[vmode,2]; MEM[SEG0040:$4c] := vmode_data[vmode,3]; MEM[SEG0040:$4d] := vmode_data[vmode,4]; For temp := 0 to 16 do MEM[SEG0040:$4e+temp] := 0; MEM[SEG0040:$60] := vmode_data[vmode,20]; MEM[SEG0040:$61] := vmode_data[vmode,21]; MEM[SEG0040:$62] := 0; Case vmode_data[vmode,2] of 8: asm mov ah,11h; mov al,2; xor bx,bx; int 10h end; 14: asm mov ah,11h; mov al,1; xor bx,bx; int 10h end; 16: asm mov ah,11h; mov al,4; xor bx,bx; int 10h end; end; initialize; dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; procedure set_vga_txtmode_80x25; begin asm mov ax,03h xor bh,bh int 10h end; v_seg := $0b800; v_ofs := 0; MaxCol := 80; MaxLn := 25; FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; procedure set_svga_txtmode_100x38; var crt_address: Word; begin // set VESA gfx mode 102h (800x600) asm mov ax,4f02h mov bx,102h int 10h end; // rerogram CRT controller crt_address := MEMW[SEG0040:$63]; asm cli mov dx,crt_address // clear write protection for CRT register 0-7 mov al,11h // vertical retrace end register bit 7 reset out dx,al inc dx in al,dx and al,7fh out dx,al dec dx mov al,9 out dx,al inc dx in al,dx and al,0e0h // clear bits 0-4 or al,0fh // set max scan line to 15 out dx,al dec dx mov ax,0e0ah out dx,ax mov ax,0f0bh out dx,ax mov al,17h // mode control register out dx,al inc dx in al,dx and al,not 40h // set byte mode out dx,al dec dx // restore write protection for CRT register 0-7 mov al,11h out dx,al inc dx in al,dx or al,80h out dx,al dec dx // write sequencer: make planes 2+3 write protected mov dx,3c4h mov al,2 mov ah,3 out dx,ax // set odd/even mode, reset chain 4, more than 64 kB mov dx,3c4h mov al,4 mov ah,2 out dx,ax // write graphics controller mov dx,3ceh mov ax,1005h // set write mode 0, read mode 0, odd/even addressing out dx,ax mov dx,3ceh mov al,6 out dx,al inc dx in al,dx and al,0f0h or al,0eh // set B800h as base, set text mode, set odd/even out dx,al // write attribute controller mov dx,3cch in al,dx mov dx,3dah test al,1 jnz @@1 mov dx,3bah @@1: in al,dx // reset attribute controller mov dx,3c0h mov al,10h // select mode register out dx,al mov al,0 // set text mode [bit 0=0] out dx,al mov al,20h // turn screen on again out dx,al sti end; MaxCol := 100; MaxLn := 38; MEM[SEG0040:$4a] := MaxCol; MEM[SEG0040:$84] := MaxLn-1; initialize; dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; procedure set_svga_txtmode_128x48; var crt_address: Word; begin // set VESA gfx mode 104h (1024x768) asm mov ax,4f02h mov bx,104h int 10h end; // rerogram CRT controller crt_address := MEMW[SEG0040:$63]; asm cli mov dx,crt_address // clear write protection for CRT register 0-7 mov al,11h // vertical retrace end register bit 7 reset out dx,al inc dx in al,dx and al,7fh out dx,al dec dx mov al,9 out dx,al inc dx in al,dx and al,0e0h // clear bits 0-4 or al,0fh // set max scan line to 15 out dx,al dec dx mov ax,0e0ah out dx,ax mov ax,0f0bh out dx,ax mov al,17h // mode control register out dx,al inc dx in al,dx and al,not 40h // set byte mode out dx,al dec dx // restore write protection for CRT register 0-7 mov al,11h out dx,al inc dx in al,dx or al,80h out dx,al dec dx // write sequencer: make planes 2+3 write protected mov dx,3c4h mov al,2 mov ah,3 out dx,ax // set odd/even mode, reset chain 4, more than 64 kB mov dx,3c4h mov al,4 mov ah,2 out dx,ax // write graphics controller mov dx,3ceh mov ax,1005h // set write mode 0, read mode 0, odd/even addressing out dx,ax mov dx,3ceh mov al,6 out dx,al inc dx in al,dx and al,0f0h or al,0eh // set B800h as base, set text mode, set odd/even out dx,al // write attribute controller mov dx,3cch in al,dx mov dx,3dah test al,1 jnz @@1 mov dx,3bah @@1: in al,dx // reset attribute controller mov dx,3c0h mov al,10h // select mode register out dx,al mov al,0 // set text mode [bit 0=0] out dx,al mov al,20h // turn screen on again out dx,al sti end; MaxCol := 128; MaxLn := 48; MEM[SEG0040:$4a] := MaxCol; MEM[SEG0040:$84] := MaxLn-1; initialize; dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; const ATTRCON_ADDR = $3c0; // Attribute Controller MISC_ADDR = $3c2; // Miscellaneous Register VGAENABLE_ADDR = $3c3; // VGA Enable Register SEQ_ADDR = $3c4; // Sequencer GRACON_ADDR = $3ce; // Graphics Controller CRTC_ADDR = $3d4; // CRT Controller STATUS_ADDR = $3da; // Status Register procedure LoadVgaRegisters(reg: VGA_REG_DATA); procedure out_reg(reg: VGA_REGISTER); begin Case (reg.port) of ATTRCON_ADDR: begin inportb(STATUS_ADDR); outportb(ATTRCON_ADDR,reg.idx OR $20); outportb(ATTRCON_ADDR,reg.val); end; MISC_ADDR, VGAENABLE_ADDR: outportb(reg.port,reg.val); else begin outportb(reg.port,reg.idx); outportb(reg.port+1,reg.val); end; end; end; var idx,temp: Byte; begin outportb($3d4,$11); temp := inportb($3d5) AND $7f; outportb($3d4,$11); outportb($3d5,temp); For idx := 1 to 29 do out_reg(reg[idx]); end; procedure set_custom_svga_txtmode; begin LoadVgaRegisters(svga_txtmode_regs); MaxCol := svga_txtmode_cols; MaxLn := svga_txtmode_rows; MEM[SEG0040:$4a] := MaxCol; MEM[SEG0040:$84] := MaxLn-1; initialize; dosmemput(v_seg,v_ofs,screen_ptr^,MAX_SCREEN_MEM_SIZE); end; {$ENDIF} procedure move2screen; var screen_ptr_backup: Pointer; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'TXTSCRIO.PAS:move2screen'; {$ENDIF} HideCursor; screen_ptr_backup := screen_ptr; screen_ptr := move_to_screen_data; area_x1 := 0; area_y1 := 0; area_x2 := 0; area_y2 := 0; scroll_pos0 := BYTE_NULL; scroll_pos1 := BYTE_NULL; scroll_pos2 := BYTE_NULL; scroll_pos3 := BYTE_NULL; scroll_pos4 := BYTE_NULL; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); status_refresh; decay_bars_refresh; ScreenMemCopy(screen_ptr,screen_ptr_backup); screen_ptr := screen_ptr_backup; SetCursor(cursor_backup); end; procedure move2screen_alt; var pos1,pos2: Byte; begin If (move_to_screen_data <> NIL) then asm mov esi,dword ptr [screen_ptr] lea edi,[temp_screen2] mov ecx,SCREEN_MEM_SIZE rep movsb mov esi,[move_to_screen_data] mov edi,dword ptr [ptr_temp_screen2] xor ecx,ecx mov cl,byte ptr [move_to_screen_area+1] @@1: mov pos2,cl xor ecx,ecx mov cl,byte ptr [move_to_screen_area+0] @@2: mov pos1,cl mov al,pos1 mov ah,pos2 xor ecx,ecx call DupChar movzx ecx,absolute_pos mov ax,word ptr [esi+ecx] mov word ptr [edi+ecx],ax movzx ecx,pos1 inc ecx cmp cl,byte ptr [move_to_screen_area+2] jbe @@2 movzx ecx,pos2 inc ecx cmp cl,byte ptr [move_to_screen_area+3] jbe @@1 lea esi,[temp_screen2] mov edi,dword ptr [screen_ptr] mov ecx,SCREEN_MEM_SIZE rep movsb end; end; function is_default_screen_mode: Boolean; begin {$IFDEF GO32V2} is_default_screen_mode := (program_screen_mode = 0) or ((program_screen_mode = 3) and (comp_text_mode < 4)); {$ELSE} is_default_screen_mode := (program_screen_mode = 0); {$ENDIF} end; {$IFDEF GO32V2} function is_VESA_emulated_mode: Boolean; begin is_VESA_emulated_mode := (program_screen_mode = 3) and (comp_text_mode > 1); end; function get_VESA_emulated_mode_idx: Byte; begin get_VESA_emulated_mode_idx := min(comp_text_mode-2,0); end; {$ENDIF} function is_scrollable_screen_mode: Boolean; begin {$IFDEF GO32V2} is_scrollable_screen_mode := (program_screen_mode = 0) or ((program_screen_mode = 3) and (comp_text_mode < 2)) or (is_VESA_emulated_mode and (get_VESA_emulated_mode_idx in [0,1])); {$ELSE} is_scrollable_screen_mode := (program_screen_mode = 0); {$ENDIF} end; procedure TxtScrIO_Init; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'TXTSCRIO.PAS:TxtScrIO_Init'; program_screen_mode := screen_mode; {$ENDIF} mn_environment.v_dest := screen_ptr; centered_frame_vdest := screen_ptr; {$IFDEF GO32V2} If NOT is_VESA_emulated_mode then {$ENDIF} Case program_screen_mode of 0: begin SCREEN_RES_X := 720; SCREEN_RES_Y := 480; MAX_COLUMNS := 90; MAX_ROWS := 40; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 18; INSCTRL_xshift := 0; INSCTRL_yshift := 0; INSEDIT_yshift := 0; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 30; work_MaxCol := MAX_COLUMNS; work_MaxLn := 30; scr_font_width := 8; scr_font_height := 16; end; // full-screen view 1: begin SCREEN_RES_X := 960; SCREEN_RES_Y := 800; MAX_COLUMNS := 120; MAX_ROWS := 50; MAX_ORDER_COLS := 13; MAX_TRACKS := 7; MAX_PATTERN_ROWS := 28; INSCTRL_xshift := 15; INSCTRL_yshift := 6; INSEDIT_yshift := 12; PATTORD_xshift := 1; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 50; work_MaxCol := MAX_COLUMNS; work_MaxLn := 40; scr_font_width := 8; scr_font_height := 16; end; // wide full-screen view 2: begin SCREEN_RES_X := 1440; SCREEN_RES_Y := 960; MAX_COLUMNS := 180; MAX_ROWS := 60; MAX_ORDER_COLS := 22; MAX_TRACKS := 11; MAX_PATTERN_ROWS := 38; INSCTRL_xshift := 45; INSCTRL_yshift := 12; INSEDIT_yshift := 12; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 60; work_MaxCol := MAX_COLUMNS; work_MaxLn := 50; scr_font_width := 8; scr_font_height := 16; end; // 90x47 4: begin SCREEN_RES_X := 800; SCREEN_RES_Y := 600; MAX_COLUMNS := 90; MAX_ROWS := 38; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 16; INSCTRL_xshift := 0; INSCTRL_yshift := 4; INSEDIT_yshift := 12; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 38; work_MaxCol := MAX_COLUMNS; work_MaxLn := 38; scr_font_width := 8; scr_font_height := 16; GOTOXY_xshift := ((SCREEN_RES_X DIV scr_font_width)-MAX_COLUMNS) DIV 2; end; // 120x47 5: begin SCREEN_RES_X := 1024; SCREEN_RES_Y := 768; MAX_COLUMNS := 120; MAX_ROWS := 48; MAX_ORDER_COLS := 13; MAX_TRACKS := 7; MAX_PATTERN_ROWS := 26; INSCTRL_xshift := 15; INSCTRL_yshift := 7; INSEDIT_yshift := 12; PATTORD_xshift := 1; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 48; work_MaxCol := MAX_COLUMNS; work_MaxLn := 48; scr_font_width := 8; scr_font_height := 16; GOTOXY_xshift := ((SCREEN_RES_X DIV scr_font_width)-MAX_COLUMNS) DIV 2; end; {$IFDEF GO32V2} // compatibility text-mode 3: Case comp_text_mode of 0, 1: begin SCREEN_RES_X := 720; SCREEN_RES_Y := 480; MAX_COLUMNS := 90; MAX_ROWS := 40; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 18; INSCTRL_xshift := 0; INSCTRL_yshift := 0; PATTORD_xshift := 0; INSEDIT_yshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 30; work_MaxCol := MAX_COLUMNS; work_MaxLn := 30; scr_font_width := 9; scr_font_height := 16; end; end; end else // VESA-emulated text-mode Case get_VESA_emulated_mode_idx of // 90x30 (default mode) 0: begin SCREEN_RES_X := 800; SCREEN_RES_Y := 600; MAX_COLUMNS := 90; MAX_ROWS := 40; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 18; INSCTRL_xshift := 0; INSCTRL_yshift := 0; INSEDIT_yshift := 0; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 30; work_MaxCol := MAX_COLUMNS; work_MaxLn := 30; scr_font_width := 8; scr_font_height := 16; end; // 90x47 1: begin SCREEN_RES_X := 800; SCREEN_RES_Y := 600; MAX_COLUMNS := 90; MAX_ROWS := 46; MAX_ORDER_COLS := 9; MAX_TRACKS := 5; MAX_PATTERN_ROWS := 24; INSCTRL_xshift := 0; INSCTRL_yshift := 4; INSEDIT_yshift := 0; PATTORD_xshift := 0; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 36; work_MaxCol := MAX_COLUMNS; work_MaxLn := 36; scr_font_width := 8; scr_font_height := 16; end; // 120x47 2: begin SCREEN_RES_X := 1024; SCREEN_RES_Y := 768; MAX_COLUMNS := 120; MAX_ROWS := 46; MAX_ORDER_COLS := 13; MAX_TRACKS := 7; MAX_PATTERN_ROWS := 24; INSCTRL_xshift := 15; INSCTRL_yshift := 7; INSEDIT_yshift := 12; PATTORD_xshift := 1; MaxCol := MAX_COLUMNS; MaxLn := MAX_ROWS; hard_maxcol := MAX_COLUMNS; hard_maxln := 47; work_MaxCol := MAX_COLUMNS; work_MaxLn := 36; scr_font_width := 8; scr_font_height := 16; end; end; {$ELSE} end; {$ENDIF} FillWord(screen_ptr^,MAX_SCREEN_MEM_SIZE DIV 2,$0700); SCREEN_MEM_SIZE := (SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2; move_to_screen_routine := move2screen; If (command_typing = 0) then _pattedit_lastpos := 4*MAX_TRACKS else _pattedit_lastpos := 10*MAX_TRACKS; Case MAX_COLUMNS of 120: temp := 1; 180: temp := 2; else temp := 0; end; patt_win[1] := patt_win_tracks[temp][1]; patt_win[2] := patt_win_tracks[temp][2]; patt_win[3] := patt_win_tracks[temp][3]; patt_win[4] := patt_win_tracks[temp][4]; patt_win[5] := patt_win_tracks[temp][5]; end; end. adlibtracker2-2.4.24/package/0000755000000000000000000000000013414571210014403 5ustar rootrootadlibtracker2-2.4.24/package/ver/0000755000000000000000000000000013411003760015174 5ustar rootrootadlibtracker2-2.4.24/package/ver/dos/0000755000000000000000000000000013414570775016003 5ustar rootrootadlibtracker2-2.4.24/package/ver/dos/ADTRACK2.DOC0000644000000000000000000031540013411003760017446 0ustar rootroot Ú-ÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄ-¿ ù ³ ú ³ subz3ro's ³ ÄÂÄ ÄÄ ³ /´DLiB³R/´CK3R ³³ G3 ³ ³ ³ ÄÄ ³ 2.3.57 ³ ³ ³ ³ ³ SYSTEM REQUiREMENTS ù ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ú MiNiMAL þ CPU 386DX þ VGA card þ VGA monitor þ 230k free conventional memory þ 5MB+ free extended memory þ Yamaha YMF262 / OPL3 (compatible) sound card þ MS-DOS 3.0 (compatible) operating system RECOMMENDED þ Pentium processor þ SVGA PCI card þ SVGA monitor (VESA DDC/2B compliant) þ 400k free conventional memory þ 8MB+ free extended memory þ 100k free disk space þ SoundBlaster 16/AWE32/AWE64 (AWE64 with Reverb 15% and Chorus 25%) þ DOS console under Windows 98 CONTENTS I. PROLOGUE II. SCREEN LAYOUT III. KEY REFERENCE IV. iNSTRUMENTS V. EFFECTS VI. SONG VARiABLES VII. GETTiNG STARTED VIII. USEFUL TiPS IX. KNOWN PROBLEMS X. EPiLOGUE Ú-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú ú ù I. PROLOGUE ù ú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù AdLib tracker is a 9-channel FM tracker for the OPL2-compatible chips found on most sound cards. A few years ago, there was a huge variety of AdLib trackers. The most common were: Zwerg Zwack/Chicken's HSC-Tracker, Jens-Christian Huus' EdLib, Shayde's Reality AdLib Tracker, Erik Pojar's Surprise! AdLib Tracker, and the latest piece of cake - Conqueror's Amusic. This new way of AdLib tracking was just that missing part in scene, splitting the two different worlds: a world of ugly CMF shit, as Chicken used to say, and a world of sample based trackers, such as FastTracker or Impulse Tracker. The above trackers became pretty popular and were used to produce very nice FM music, short on size but high on quality. Such tunes were included in many BBS intros and demos. Unfortunately, the things went wrong, and AdLib tracking has come to fruition. Nowadays, at the end of second Millennium, i decided to revive this part of tracking history. Ladies and gentlemen, subz3ro is proud to present you a brandnew AdLib tool - /´DLiB TR/´CK3R ][. You may probably ask WHY? Let me use the words of Jens-Christian Huus, one of the most common people in C64 and AdLib programming, the author of EdLib: "People begun to actually hate FM sounds. The arrival of GUS and AWE32 made wavetable techniques very popular and indeed it sounds very good, but there are some things in the old FM standard that is unique. You can't fiddle with samples in the same way as you can with FM. I personally never quite liked sampling, i find it downright boring. With a FM chip it is like on a C64; you have a few parameters and everything you do has to be done within these parameters. These boundaries makes it funny to make music, to see how far you can actually push AdLib. To do sounds on FM requires expertice but if you're good at it, almost any instrument can be reproduced properly, except perhaps drums." HiGHLiGHTS ÄÄÄÄÄÄÄÄÄÄ þ supports 4-op instruments, melodic and percussion instruments þ supports up to 255 instruments, 128 patterns, 128 order list entries, 89 effect commands, and 22 extended commands þ features 2 effect columns, instrument macro-definitions, MPU-401 MIDI slave mode (SYNTH!) þ loads following song formats: A2M (AdT2) A2P (AdT2) [pattern] A2T (AdT2) [tiny module] N1/ AMD (Amusic) CFF (BoomTracker 4.0) DFM (Digital-FM) N2/ FMK (FM-Kingtracker) HSC (HSC AdLib Composer / HSC-Tracker) MTK (MPU-401 tr’kkîr) RAD (Reality AdLib Tracker) {ver.1} N3/ S3M (Scream Tracker 3.x) N4/ SAT (Surprise! AdLib Tracker) {ver.1,5,6} N4/ SA2 (Surprise! AdLib Tracker 2.0) {ver.8,9} N1/ XMS (XMS-Tracker) NOTE 1 Because of bug in Amusic's (and its crack XMS-Tracker's) replay routine, the Arpeggio effect used to generate buggy sounds. Since /´DLiB TR/´CK3R ][ ain't got a support for such buggy things, the Arpeggio effect may differ. NOTE 2 After conversion, the Tremolo and Vibrato effects may sound different, because FM-Kingtracker uses slow speed table (not 100% emulated in AT2) and optional waveform definitions that are currently not supported. Also the Retrig Note effect is slightly different (if i should be honest, i really couldn't get any sense of Sami's frame counting; all i could do to make this effect sound way "authentic" was the frame correction during conversion phase--and this ain't perfect, though :) The OPL3 setting is ignored, Stereo setting is accepted, Rhythm mode is not supported, because it was incorrectly implemented in earlier versions of the tracker, and the author himself stopped supporting it. Also the pattern order list will be truncated to 128 if exceeds. NOTE 3 Conversion of these (primarily sample based) modules may not be 100% exact. Therefore Slide Up/Down, Vibrato, and Tone Portamento effects may be inaccurate after importing to /´DLiB TR/´CK3R ][. Anyway, some experimental methods are used to fix up the fine-tuning and frequency slide based Scream Tracker's effects during conversion phase (experimental understand as "non-perfect" :) Note that the optional vibrato/tremolo waveforms are not supported. Also the pattern order list will be truncated to 128 if exceeds. NOTE 4 Since Surprise! AdLib Tracker uses non-standard Volume Slide procedure in replay routine, Volume Slide based effects may differ after importing to /´DLiB TR/´CK3R ][. Anyway, an experimental method to fix up this difference is used during conversion phase (blabla, same as above :) The special arpeggio is also currently not supported (anyway, there are no SA2 modules using that feature, afaik :) þ loads following instrument formats: A2i (AdT2) A2F (AdT2) [w/fm-register macro] CiF (BoomTracker 4.0) FiN (FM-Kingtracker) iNS (HSC-Tracker/RAD-Tracker, SAdT, Amusic/AdLib instrument) SBi (Creative Labs FM instrument) SGi (Sound Generator 3.0) Note that the type of "ins" file can be set up in configuration file if neccessary (see option "force_ins"). þ loads following bank formats: A2B (AdT2) A2W (AdT2) [w/macros] BNK (AdLib instrument bank) {ver.1.0} FiB (FM-Kingtracker) iBK (Creative Labs FM instrument bank) þ The tracker supports block operations, and has an instrument editor. In addition, it features Tracing, Debugging, and a MidiBoard. þ The tracker reads many of its settings from a configuration file. It has strong support geared for row by row tracing, pausing, and playing from any line in a pattern. Ú-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú ú ù II. SCREEN LAYOUT ù ú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù The main window of the tracker is roughly composed of 5 parts: A. The upper left hand window shows the Status of the song (paused, playing, etc.), row number and order/pattern position, current speed/tempo, time playing and file information. B. The upper right hand window is the Pattern Order. There the user can build the order by which the patterns are played. C. The main window is the Pattern Editor with total count of 18/20 tracks, 5 tracks visible at a time, where the user can compose the song, enter the notes, commands, number of instrument, and effects. D. The Status Line at the bottom where the user can keep track of the different modes and the active mode which is highlighted (MBoard, Trace, Debug, Tracking), active octave, active instrument, behavior mode, a.o. The user should experiment to gain familiarity with different modes that can be activated. E. The bottom window under Pattern Editor shows the Volume Analyzer. User have to scroll up the rest of main screen to see it. You can get all the volume information (carrier and modulator output level, overall volume and global song volume, approximate intensity in dB) there. KEYBOARD CONVENTiONS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ [A] means the 'a' key on your keyboard [^A] means the 'a' key + [Ctrl] [Shift] A means the 'a' key + [Shift] [Alt] A means the 'a' key + [Alt] [Shift] ^A means the 'a' key + [Ctrl] + [Shift] [Alt] ^A means the 'a' key + [Ctrl] + [Alt] In case of composite shortkeys, it is recommended to use following order of pressing the keys: 1st: [Ctrl] (if any) 2nd: [Alt] or [Shift] or [Tab] (if any) 3rd: "ordinary" key (if any :) Note that sometimes when running /´DLiB TR/´CK3R ][ in Windows environment, some of the Ctrl+Shift+xx (where "xx" is an ordinary character key) keys may stop responding. It is caused by some Windows programs or Windows itself overriding the DOS keyboard driver. Therefore, it is recommended to use pure MS-DOS mode or terminate such Windows programs. Ú-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú ú ù III. KEY REFERENCE ù ú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù III/1. GENERAL KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ F1 Help F2 (^S) Save file F3 (^L) Load file F4 (^A) Toggle Nuke'm dialog F5 Play F6 Pause F7 Stop F8 Play song from current pattern or order F9 Play current pattern or order only [Ctrl] F8 @F8 from current line ¿ [Ctrl] F9 @F9 from current line à (Pattern Editor) [Alt] F6 Single-play pattern Ù (Shift toggles trace) [Alt] F5 @F5 ¿ [Alt] F8 @F8 à without synchronization [Alt] F9 @F9 Ù [Shift] F2 Quick Save [Shift] F3 Quick Load [Shift] F5 F5 with Trace [Shift] F6 Toggle Debug mode from position at cursor [Shift] F8 F8 with Trace [Shift] F9 F9 with Trace [Shift] Space Toggle MidiBoard mode ON/OFF ^Space Toggle Note Recorder mode ON/OFF [Alt] Space Toggle Synth! mode ON/OFF (if available) [Ctrl] Home,End Skip to previous/next pattern while Tracing +,- Same as above; play pattern from start ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ WHEN iN NOTE RECORDER MODE ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ^Left,^Right Select group of tracks for recording ³ ³ Enter Start recording from current position (*) ³ ³ Space Toggle using custom instrument for all tracks ¿ ³ ³ [Alt] Space Toggle using present instruments in tracks à ref. ³ ³ MBoard keys Write notes to corresponding tracks ³ (*) ³ ³ F8,F9 Toggle pattern repeat OFF/ON Ù ³ ³ Backspace Clear note/instrument sequence in tracks ³ ³ ^Backspace Clear complete note/instrument columns ³ ³ Up,Down Rewind/Fast-Forward while recording ³ ³ [Shift] Up,Down Increase/Decrease row correction for writing notes ³ ³ [Shift] F6 Continue in Debug mode from position at cursor ³ ³ F7 Stop recording and reset starting position; ³ ³ current group of tracks can be modified ³ ³ [Alt] 1..9,0 Toggle track channel ON/OFF (Shift toggles 1X) ³ ³ [Alt] R Reset flags on all tracks ³ ³ * Reverse ON/OFF on all tracks ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ In case you need non-continuos track selection, you can choose ³ ³ from already selected group a subset of tracks where notes will be ³ ³ written by manipulating track ON/OFF flags. ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Note that playing with Trace and playing without synchronization can be set up in configuration file (see options "trace_by_default" and "nosync_by_default") ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ iF SONG iS PLAYED WiTH TRACE, iT CAN BE REMOVED WHiLE... ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ Enter Playback is paused and cursor stays on position ³ ³ Esc Cursor jumps to last position and playback continues ³ ³ [Shift] Esc Cursor stays on position and playback continues ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ^Enter Play next pattern according to order ^Left (Up) Rewind current pattern (with Trace) ^Right (Down) Fast-Forward (with Trace) [Ctrl]{Shift} , Change playback speed up/down {fine stepping} [Ctrl]{Shift} [] Reset playback speed {default speed} [Ctrl][Alt] Temporarily show Debug Info window ^B Toggle Message Board window ^D Toggle Debug Info window ^Q Toggle Instrument Macro Editor window ^G Toggle Arpeggio/Vibrato Macro Editor window ^F Toggle Song Variables window ^H Toggle Replace window ^I Toggle Instrument Control panel ^E Toggle Instrument Editor window ^O Toggle Octave Control panel ^P Toggle Pattern List window ^R Toggle Remap Instrument window ^T Toggle Transpose window ^X Toggle Rearrange Tracks window ^1..^8 Quick-set octave [Alt] +,- (Up,Down) Adjust volume level of sound output [Alt] C Copy object to clipboard (with selection) [Alt] P Paste object from clipboard [Alt] M Toggle marking lines ON/OFF [Alt] L Toggle Line Marking Setup window [Alt] 1..9,0 Toggle track channel ON/OFF (Shift toggles 1X) [Alt] S Set all OFF except current track (solo) [Alt] R Reset flags on all tracks * Reverse ON/OFF on all tracks F10 Quit program F11 Toggle typing mode in Pattern Editor (ATÄFTÄST) F12 Toggle line feed in Pattern Editor [Shift] F12 Toggle jump to marked line in Pattern Editor [Ctrl][Tab] [...] (*) Scroll screen content (if necessary) (*) Up,Down,Left,Right,PgUp,PgDown,Home,End III/2. PATTERN ORDER KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right Cursor navigation PgUp,PgDn Move up/down 32 patterns Home,End Move to the top/end of pattern order Tab,[Shift] Tab Move to next/previous entry Insert Insert new entry Delete Delete entry Backspace Clear entry ^Space Enter skip mark ^C Copy entry to clipboard ^V Paste entry from clipboard +,- Adjust entry ^F2 Save module in tiny format Enter Switch to Pattern Editor Note that 80-FF pattern number range causes a jump in pattern order. syntax: order_number[hex](+80h); e.g. "9A" jumps to order 1A III/3. PATTERN EDiTOR KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right Cursor navigation PgUp,PgDn Move up/down 16 lines Home,End Move to the top/end of current pattern Tab,[Shift] Tab Move to next/previous track [Shift] PgDn,PgUp (+,-) Move to next/previous pattern [Shift] Home,End Move fwd./bckwd. to the first/last pattern ^Home,^End Move to the end/top of previous/next pattern Space Advance to next row ^PgUp,^PgDn Transpose note (block) halftone up/down Backspace Remove note or clear attributes Insert Insert new line (within track only) Delete Delete line (within track only) [Shift] Insert Insert new line [Shift] Delete Delete line [Shift] Enter Toggle fixed and regular note ^K Insert Key-Off ^C Copy object at cursor to clipboard ^V Paste object from clipboard [Alt][Shift] P Paste object from clipboard to more patterns ^Z Undo last operation (if possible) {Ctrl} "[","]" Change current instrument [Alt] F2 Save current pattern to file ^F2 Save module in tiny format [Shift] F3 Quick load recent pattern data Enter Switch to Pattern Order NOTE SYSTEM: C,C#,D,D#,E,F,F#,G,G#,A,A#,B(H) VALiD NOTE ENTRiES: C,C-,C#,C1,C-1,C#1... ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ BLOCK OPERATiONS iN PATTERN EDiTOR ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ Starting to mark a block: [Shift] Up,Down,Left,Right ³ ³ When at least one row in one track is marked, you can continue ³ ³ marking also with PgUp,PgDn,Home,End (Shift is still held down!) ³ ³ Quick mark: [Alt] Q (1x-2x-3x) track Ä pattern Ä discard ³ ³ Toggle last marked block: [Alt] B ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ^B Blank block (Insert blank block to pattern) ³ ³ ^C Copy block (Copy block to clipboard) ³ ³ ^D Delete block (Remove block from pattern) ³ ³ ^N Nuke block (Clear block contents) ³ ³ ^V Paste block (Paste block from clipboard to pattern) (*) ³ ³ ^X Cut block (Combine both Copy and Delete operation) ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ (*) PASTE BLOCK OPERATiON VARiANTS ³ ³ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ³ ³ "Paste block" operation has three other functional variants ³ ³ with different key shortcuts for activation: ³ ³ 1. [Alt] V toggles "Mix block" operation, when block data ³ ³ from clipboard is applied without overwriting existing data; ³ ³ 2. [Shift] ^V toggles "Selective paste block" operation, ³ ³ when only block data from clipboard corresponding to current ³ ³ cursor position is being applied (i.e. note, instrument, ³ ³ 1st effect or 2nd effect); ³ ³ 3) [Alt][Shift] V toggles "Flipped paste block" operation, ³ ³ when block data from clipboard is applied vertically flipped. ³ ³ ³ ³ MANiPULATiON WiTH FX VOLUME iNFORMATiON ³ ³ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ³ ³ When there is block marked, which contains some effect ³ ³ commands carrying volume information, you can increase/decrease ³ ³ their values with +/- keys. ³ ³ Effect commands are processed with following priority: ³ ³ 1) Set instrument volume (Cxx), ³ ³ Force instrument volume (=xx) ³ ³ 2) Set modulator volume (9xx) ³ ³ 3) Set carrier volume (Ixx) ³ ³ 4) Set global volume (%xx) ³ ³ If effect command with higher priority has been processed, ³ ³ all remaining effect commands with lower priority are skipped. ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ III/4. PATTERN LiST WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down Cursor navigation PgUp,PgDn Move up/down 20 patterns Home,End Move to the top/end of pattern list Space Mark/Unmark pattern ^Space Unmark all marked patterns [Shift] ^Space Reverse marks on all patterns [Alt] C (^C) Copy pattern to clipboard [Alt] P (^V) Paste pattern from clipboard [Shift] ^V Paste pattern data from clipboard [Alt] ^V Paste pattern name from clipboard ^N Nuke current pattern [Shift] ^N Nuke all marked patterns ^W Swap marked patterns [Shift] ^W Swap marked patterns w/o names [Shift] Insert Insert new pattern [Shift] Delete Delete pattern Enter Rename pattern / Multiple paste [Shift] F3 Quick load recent pattern data Esc Return to Pattern Editor or Pattern Order III/5. iNSTRUMENT CONTROL PANEL KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down Cursor navigation PgUp,PgDn Move up/down 16 instruments Home,End Move to the top/end of instrument list Space Mark/Unmark instrument MBoard keys Preview instrument Enter Rename instrument ^C Copy instrument to clipboard [Shift] ^C Copy instrument also with macro-definitions ^V Paste instrument(s) from clipboard [Shift] ^V Paste instrument data from clipboard [Alt] V Paste instrument name(s) from clipboard ^W Swap marked instruments [Shift] ^W Swap marked instruments W/o names Tab Toggle Instrument Editor window [Shift] Tab Toggle Macro Editor window [Shift] O Toggle operator mode 4OP / 2OP [Shift] M,B,S,T,C,H Toggle melodic and percussion (BD,SD,TT,TC,HH) [Shift] F2 Save instrument w/ fm-register macro to file [Alt] F2 Save instrument bank to file ^F2 Save instrument bank w/ all macros to file [Shift] F3 Quick load recent instrument data Esc Return to Pattern Editor or Pattern Order III/6. iNSTRUMENT EDiTOR WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right, Home,End Cursor navigation [Alt]
Jump to section Tab Jump to next setting [Shift] Tab Jump to previous setting +,- (PgUp,PgDn) Adjust value Space Select item ^Space (opt.) Toggle ADSR preview ON/OFF [Ctrl] "[","]" Change current instrument [Ctrl][Shift] "[","]" Change macro speed [Alt]{Shift} 1..4,0 Set operators for instrument preview (*) MBoard keys Preview instrument Enter Toggle carrier/modulator/4OP slot settings [Shift] O Toggle operator mode 4OP / 2OP [Shift] M,B,S,T,C,H Toggle melodic and percussion (BD,SD,TT,TC,HH) [Shift] F2 Save instrument w/ fm-register macro to file [Shift] Enter Copy values from carrier/modulator slot Esc Return to Instrument Control panel (*) [Alt] 1..4 Set solo operator [Alt][Shift] 1..4 Toggle operator ON/OFF [Alt] 0 Reset III/7. iNSTRUMENT MACRO EDiTOR WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right Home,End Cursor navigation PgUp,PgDown Move up/down 16 lines Tab (Enter) Jump to next field in order [Shift] Tab Jump to previous field in order [Shift] Up,Down Synchronous navigation within tables [Shift] Home,End Move to the start/end of current line in table ^Left,^Right Switch between macro tables [Shift] ^Left,^Right Navigate to start/end of macro table ^PgUp,^PgDown Change current arpeggio/vibrato table [Ctrl] "[","]" Change current instrument [Ctrl][Shift] "[","]" Change macro speed [Alt]{Shift} 1..4,0 Set operators for instrument preview (*) [Alt] ^C Copy values from carrier column [Alt] ^M Copy values from modulator column ^C Copy line in table (whole table respectively) [Shift] ^C Copy column in table ^V Paste object from clipboard ^Enter Paste data from instrument registers [Shift] Enter Paste data to instrument registers [Shift] ^Enter Paste data from instrument registers w/ selection Backspace Clear current item in table [Shift] Backspace Clear line in table +,- Adjust value at cursor / current item in table ^Home,^End Quick-adjust table length [Shift] ^Home,^End Quick-adjust loop begin position [Shift] ^PgUp,^PgDown Quick-adjust loop length Insert Insert new line in table Delete Delete line in table ^E Toggle envelope restart ON/OFF ¿ ^N Toggle note retrigger ON/OFF ³ ^Z Toggle ZERO frequency ON/OFF ³ [Alt] ^E,^N,^Z Reset all alike flags in table à FM-register ^Backspace Toggle corresponding column ON/OFF ³ table [Alt] S Set all OFF except current column ³ [Alt] R Reset flags on all columns ³ * Reverse ON/OFF on all columns Ù \ Toggle current item (switch types only) Space Toggle macro-preview mode ^Space Toggle Key-Off loop within macro-preview mode ^F2 Save instrument bank w/ all macros to file Esc Leave Instrument Macro Editor window (*) [Alt] 1..4 Set solo operator [Alt][Shift] 1..4 Toggle operator ON/OFF [Alt] 0 Reset III/8. APREGGiO/ViBRATO MACRO EDiTOR WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right Home,End Cursor navigation PgUp,PgDown Move up/down 16 lines Tab (Enter) Jump to next field in order [Shift] Tab Jump to previous field in order [Shift] Up,Down Synchronous navigation within tables ^Left,^Right Switch between macro tables [Shift] ^Left,^Right Navigate to start/end of macro table ^PgUp,^PgDown Change current arpeggio/vibrato table [Ctrl] "[","]" Change current instrument [Ctrl][Shift] "[","]" Change macro speed [Alt]{Shift} 1..4,0 Set operators for instrument preview (*) ^C Copy line in table (whole table respectively) [Shift] ^C Copy column in table ^V Paste object from clipboard Backspace Clear current item in table [Shift] Backspace Clear line in table +,- Adjust value at cursor / current item in table ^Home,^End Quick-adjust table length [Shift] ^Home,^End Quick-adjust loop begin position [Shift] ^PgUp,^PgDown Quick-adjust loop length [Shift] Esc Apply table indexes to current instrument Esc Leave Arpeggio/Vibrato Macro Editor window (*) [Alt] 1..4 Set solo operator [Alt][Shift] 1..4 Toggle operator ON/OFF [Alt] 0 Reset III/9. iNSTRUMENT MACRO BROWSER KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,PgUp,PgDown Home,End Cursor navigation [Shift] Up,Down Move up/down in macro table [Shift] Left,Right Move left/right in macro table [Shift] PgUp,PgDown Move page up/down in macro table [Shift] Home,End Move to the start/end of macro table [Ctrl] Home,End Move to the start/end of line in macro table Enter Load selected macro data ^Enter (opt.) Load all macro data from bank [Ctrl][Shift] "[","]" Change macro speed MBoard keys Preview instrument with selected macro data Tab (opt.) Switch to Arpeggio/Vibrato Macro Browser window Esc Leave Instrument Macro Browser window III/10. ARPEGGiO/ViBRATO MACRO BROWSER KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,PgUp,PgDown Home,End Cursor navigation [Shift] Left,Right Move left/right in arpeggio table ¿ [Shift] PgUp,PgDown Move page left/right in arpeggio table ³ ^Left,^Right Move left/right in vibrato table à refer to ^PgUp,^PgDown Move page left/right in vibrato table ³ (*) [Shift]{Alt} Space Toggle arpeggio table selection (**) ³ [Ctrl] {Alt} Space Toggle vibrato table selection (**) Ù [Shift] Home,End Navigate to start/end of arpeggio table ^Home,^End Navigate to start/end of vibrato table [Ctrl] "[","]" Change current instrument [Ctrl][Shift] "[","]" Change macro speed MBoard keys Preview instrument with selected macro data Enter Load selected macro data ^Enter (opt.) Load all macro data from bank Esc Leave Arpeggio/Vibrato Macro Browser window (*) Key combination with Ctrl+Shift applies action to both tables (**) Alt key invokes no arpeggio resp. vibrato table (index value reset) III/11. DEBUG iNFO WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,PgUp,PgDown Home,End Change current track Tab Toggle details Backspace Toggle pattern repeat Space Enter Debug mode / Proceed step ^Space Exit Debug mode [Ctrl] Home,End Skip to previous/next pattern +,- Same as above; play pattern from start ^Enter Play next pattern according to order ^Left Rewind current pattern ^Right Fast-Forward [Alt] 1..9,0 Toggle track channel ON/OFF (Shift toggles 1X) [Alt] S Set all OFF except current track (solo) [Alt] R Reset flags on all tracks * Reverse ON/OFF on all tracks Esc Return to Pattern Editor or Pattern Order III/12. REMAP iNSTRUMENT WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right Home,End Cursor navigation PgUp,PgDown Move up/down 16 instruments Tab Jump to next selection [Shift] Tab Jump to previous selection MBoard keys Preview instrument Enter Remap Esc Return to Pattern Editor or Pattern Order III/13. REARRANGE TRACKS WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right, Home,End Cursor navigation Tab Jump to next selection [Shift] Tab Jump to previous selection ^PgUp,^PgDown Shift track at cursor up/down in the track list [Shift] ^PgUp,^PgDown Rotate track list from cursor upside/downside Enter Rearrange Esc Return to Pattern Editor or Pattern Order III/14. REPLACE WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right, Home,End Cursor navigation Tab Jump to next selection [Shift] Tab Jump to previous selection ^K Insert Key-Off in note column ^N Mark "new" field to clear found item ^W Swap "to find" and "replace" mask content Delete,Backspace Delete current/previous character ^Backspace Delete "to find" or "replace" mask content [Shift] ^Backspace Delete content of both masks Enter Replace Esc Return to Pattern Editor or Pattern Order III/15. SONG VARiABLES WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right Cursor navigation [Alt]
Jump to section Tab (Enter) Jump to next variable field [Shift] Tab Jump to previous variable field Space Select item ^Enter Setup rows per beat for BPM calculation Esc Return to Pattern Editor or Pattern Order III/16. FiLE BROWSER KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right, PgUp,PgDown,Home,End Cursor navigation \ Navigate to drive root Backspace Navigate to parent directory [Shift] Backspace Navigate to program home directory MBoard keys Preview instrument (instrument files only) Enter Choose file under cursor / read instrument bank Esc Leave without choosing file III/17. MESSAGE BOARD WiNDOW KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Up,Down,Left,Right, ^PgUp,^PgDown, Home,End,^Home,^End Cursor navigation PgUp,PgDown Move backwards/forwards over text ^Left,^Right Move word left/right Backspace,Delete Delete character left/right ^Backspace,^T Delete word left/right ^K Delete characters to end ^Y Delete current line Tab Indent current line ^Space Insert row for text at cursor [Shift] ^Backspace Delete row for text at cursor Insert Toggle input and overwrite mode Enter Wrap line of text Esc Return to Pattern Editor or Pattern Order III/18. iNPUT FiELD KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Left,Right Move left/right Home,End Move to the begin/end ^Left,^Right Move word left/right Backspace,Delete Delete character left/right ^Backspace,^T Delete word left/right ^K Delete characters to end ^Y Delete string Insert Toggle input and overwrite mode +,- Increment/decrement decimal or hexadecimal value III/19. MiDiBOARD KEY REFERENCE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Use to enter notes while in MBoard mode (if not already active, Shift+Space activates this mode if song is Stopped, or if song is Paused with no Trace). C# D# F# G# A# C# D# F# G# A# C# D# ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ ÞÛÛ SÞÛ DÞÛÛÞÛÛ GÞÛ HÞÛ JÞÛÛÞÛÛ 2ÞÛ 3ÞÛÛÞÛÛ 5ÞÛ 6ÞÛ 7ÞÛÛÞÛÛ 9ÞÛ 0ÞÛÛ ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ ÞÝZÞÞÝXÞÞÝCÞÞÝVÞÞÝBÞÞÝNÞÞÝMÞÞÝQÞÞÝWÞÞÝEÞÞÝRÞÞÝTÞÞÝYÞÞÝUÞÞÝIÞÞÝOÞÞÝPÞ ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ C D E F G A B C D E F G A B C D E ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ WHiLE TRACKER iS iN MBOARD MODE ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ MBoard key copies note in note field, plays it, and advances song ³ ³ to next row. If used with Left-Shift key and line marking toggled ON, ³ ³ it advances song to next highlighted row. ³ ³ If used with Right-Shift key, it makes a fixed note. ³ ³ Space plays row and advances song by one row. ³ ³ ` inserts Key-Off, releases playing note and advances to next row. ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Ú-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú ú ù IV. iNSTRUMENTS ù ú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù ATTACK RATE ÄÄÄÄÄÄÄÄÄÄÄ Indicates how fast the sound volume goes to maximum. 1=slow, 15=fast. 0 means no attack phase. DECAY RATE ÄÄÄÄÄÄÄÄÄÄ Indicates how fast the sound goes from maximum level to sustain level. 1=slow, 15=fast. 0 means no decay phase. SUSTAiN LEVEL ÄÄÄÄÄÄÄÄÄÄÄÄÄ Indicates the sustain level. 1=loudest, 15=softest. 0 means no sustain phase. RELEASE RATE ÄÄÄÄÄÄÄÄÄÄÄÄ Indicates how fast the sound goes from sustain level to zero level. 1=slow, 15=fast. 0 means no release phase. OUTPUT LEVEL ÄÄÄÄÄÄÄÄÄÄÄÄ Ranges from 0 to 63, indicates the attenuation according to the envelope generator output. In Additive synthesis, varying the output level of any operator varies the volume of its corresponding channel. In FM synthesis, varying the output level of carrier varies the volume of its corresponding channel, but varying the output of the modulator will change the frequency spectrum produced by the carrier. WAVEFORM SELECT ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Specifies the output waveform type. The first is closest to pure sine wave, the last is most distorted. [0] SiNE  ³ ³ __ __ ³ / \ / \ ³ / \ / \ ÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ ³ \ / \ / ³ \ / \ / ³ ~~ ~~ ³ ã/2 ã 3/2ã 2ã [1] HALF-SiNE  ³ ³ __ __ ³ / \ / \ ³ / \ / \ ÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ ³ ³ ã/2 ã 3/2ã 2ã ³ ³ [2] ABS-SiNE  ³ ³ __ __ __ __ ³ / \ / \ / \ / \ ³ / \ / \ / \ / \ ÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ ³ ³ ã/2 ã 3/2ã 2ã ³ ³ [3] PULSE-SiNE  ³ ³ _ _ _ _ ³ / | / | / | / | ³/ | / | / | / | ÄÅÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄ ³ ³ ã/4 ã/2 3/4ã ã 5/4ã 3/2ã 7/4ã 2ã ³ ³ [4] SiNE, EVEN PERiODS ONLY (EPO)  ³ ³ ³ /~\ /~\ ³/ \ / \ ÄÅÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄ ³ \ / \ / ³ \_/ \_/ ³ ³ ã/4 ã/2 3/4ã ã 5/4ã 3/2ã 7/4ã 2ã [5] ABS-SiNE, EVEN PERiODS ONLY (EPO)  ³ ³ ³ /~\ /~\ /~\ /~\ ³/ \ / \ / \ / \ ÄÅÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄ ³ ³ ã/4 ã/2 3/4ã ã 5/4ã 3/2ã 7/4ã 2ã ³ ³ [6] SQUARE  ³ ³ Ã-----------¿ Ú-----------¿ | | | | ÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ ³ | | | | ³ À-----------Ù À-----------Ù ³ ³ ã/2 ã 3/2ã 2ã [7] DERiVED SQUARE  ³ |\ |\ | ~~__ | ~~__ | ~~--__ | ~~--__ ÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ ³ ~~--__ | ~~--__ | ³ ~~__ | ~~__ | ³ \| \| ³ ã/2 ã 3/2ã 2ã KEY SCALiNG LEVEL (KSL) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ When set, makes the sound softer at higher frequencies. With musical instruments, volume decreases as pitch increases. Level key scaling values are used to simulate this effect. If any (not zero), the diminishing factor can be 1.5 dB/octave, 3.0 dB/octave, or 6.0 dB/octave. PANNiNG ÄÄÄÄÄÄÄ Gives you ability of controlling output, going to left or right channel, standing in the middle respectively. The parameter corresponds either with carrier and modulator, therefore it is listed only once (within the carrier slot). FiNE-TUNE ÄÄÄÄÄÄÄÄÄ This is not a hardware parameter. Ranges from -127 to 127, it indicates the number of frequency units shifted up or down for any note playing with the corresponding instrument. The parameter corresponds either with carrier and modulator, therefore it is listed only once (within the carrier slot). FEEDBACK STRENGTH ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Ranges from 0 to 7, it indicates the modulation depth for the modulator slot FM feedback. ÚÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿ ³ FEEDBACK º [0] ³ [1] ³ [2] ³ [3] ³ [4] ³ [5] ³ [6] ³ [7] ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄ´ ³ MODULATiON º 0 ³ã/16 ³ ã/8 ³ ã/4 ³ ã/2 ³ ã ³ 2ã ³ 4ã ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÙ The parameter corresponds either with carrier and modulator, therefore it is listed only once (within the carrier slot). CONNECTiON TYPE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Frequency modulation means that the modulator slot modulates the carrier. Additive synthesis means that both slots produce sound on their own. [FM] FREQUENCY MODULATiON ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³  ÉÍÍÍÍ» ³ ÉÍÍÍÍ» P1 ÄÄ(+)Äĺ MO ÇÄÄÁÄÄ(+)Äĺ CA ÇÄÄ OUT ÈÍÍÍͼ  ÈÍÍÍͼ ³ P2 [ADDiTiVE SYNTHESiS] AM ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³  ÉÍÍÍÍ» ³ P1 ÄÄ(+)Äĺ MO ÇÄÄÁÄÄÄÄ¿ ÈÍÍÍͼ ³  (+)ÄÄ OUT  ÉÍÍÍÍ» ³ P2 ÄÄÄÄÄÄÄĺ CA ÇÄÄÄÄÄÄÄÙ ÈÍÍÍͼ The parameter corresponds either with carrier and modulator, therefore it is listed only once (within the carrier slot). This parameter is also very important when making 4-op instruments, because the combination of two instrument connections specifies the connection of the 4-op instrument as shown below: ÚÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿ ³ SLOT º M1 ³ C1 ³ M2 ³ C2 ³ ÃÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄ´ ³ OPERATOR º 1 ³ 2 ³ 3 ³ 4 ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÙ [FM/FM] ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³  ÉÍÍÍÍ» ³ ÉÍÍÍÍ» ÉÍÍÍÍ» ÉÍÍÍÍ» P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄ(+)Äĺ C1 ÇÄÄ(+)Äĺ M2 ÇÄÄ(+)Äĺ C2 ÇÄÄ OUT ÈÍÍÍͼ  ÈÍÍÍͼ  ÈÍÍÍͼ  ÈÍÍÍͼ ³ ³ ³ P2 P3 P4 [FM/AM] ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³  ÉÍÍÍÍ» ³ ÉÍÍÍÍ» P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄ(+)Äĺ C1 ÇÄÄÄÄ¿ ÈÍÍÍͼ  ÈÍÍÍͼ ³ ³ ³  P2 (+)ÄÄ OUT  ³ ÉÍÍÍÍ» ÉÍÍÍÍ» ³ P3 ÄÄÄÄÄÄÄĺ M2 ÇÄÄÄÄÄ(+)Äĺ C2 ÇÄÄÄÄÙ ÈÍÍÍͼ  ÈÍÍÍͼ ³ P4 [AM/FM] (*) ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³  ÉÍÍÍÍ» ³ P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÈÍÍÍͼ ³ ³ ³ ³ ÉÍÍÍÍ» ÉÍÍÍÍ» ÉÍÍÍÍ»  P2 ÄÄÄÄÄÄÄĺ C1 ÇÄÄÄÄÄ(+)Äĺ M2 ÇÄÄ(+)Äĺ C2 ÇÄÄ(+)ÄÄ OUT ÈÍÍÍͼ  ÈÍÍÍͼ  ÈÍÍÍͼ ³ ³ P3 P4 [AM/AM] (*) ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ ³  ÉÍÍÍÍ» ³ P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÈÍÍÍͼ ³ ³ ³ ³ ÉÍÍÍÍ» ÉÍÍÍÍ»  P2 ÄÄÄÄÄÄÄÄĺ C1 ÇÄÄÄÄÄ(+)Äĺ M2 ÇÄÄ(+)ÄÄ OUT ÈÍÍÍͼ  ÈÍÍÍͼ  ³ ³ ³ P3 ³ ÉÍÍÍÍ» ³ P4 ÄÄÄÄÄÄÄĺ C2 ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ÈÍÍÍͼ (*) REMARK ABOUT 4OP CONNECTiONS FM/AM AND AM/FM Please note, that since order of 4OP channels (hardware-wise) is 2) and 1), these two instrument connections are swapped.', The preview diagrams in the Instrument Editor window show actual order, but here this information is kept in conformity with the official Yamaha YMF262 data specification to prevent further confusion. TREMOLO (AMPLiTUDE MODULATiON) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ When set, turns tremolo (volume vibrato) ON for the corresponding slot. The repetition rate is 3.7Hz, the depth is optional (1dB/4.8dB). ViBRATO ÄÄÄÄÄÄÄ When set, turns frequency vibrato ON for the corresponding slot. The repetition rate is 6.1Hz, the depth is optional (7%/14%). KEY SCALE RATE (KSR) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ When set, makes the sound shorter at higher frequencies. With normal musical instruments, the attack and decay rate becomes faster as the pitch increases. The key scale rate controls simulation of this effect. An offset (rof) is added to the individual attack, decay, and release rates depending on the following formula: actual_rate = (rate * 4) + rof The "rof" values for corresponding "rate" value and KSR state are shown in the following table: ÚÄÄÄÄÄÄÄÄÒÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ³ %rate% º 0 ³ 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ³ 8 ³ 9 ³ A ³ B ³ C ³ D ³ E ³ F ³ ÆÍÍÍÍÍÍÍÍÎÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍ͵ ³ [OFF] º 0 ³ 0 ³ 0 ³ 0 ³ 1 ³ 1 ³ 1 ³ 1 ³ 2 ³ 2 ³ 2 ³ 2 ³ 3 ³ 3 ³ 3 ³ 3 ³ ÃÄÄÄÄÄÄÄÄ×ÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´ ³ [ON] º 0 ³ 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ³ 8 ³ 9 ³ A ³ B ³ C ³ D ³ E ³ F ³ ÀÄÄÄÄÄÄÄÄÐÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ SUSTAiN (ENVELOPE GENERATOR TYPE) ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ When set, the sustain level of the voice is maintained until released. When clear, the sound begins to decay immediately after hitting the sustain phase. [OFF] /\ DR / \ / ...\...SL AR / \ / \ RR / \ _ _/ \_ _ _ . : ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÙ KEY ON [ON] /\ DR / \ SL / \ _ _ _ _ _ AR / \ / : \ RR / : \ _ _/ : \_ _ _ . : : : ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ KEY OFF ÄÄÄÙ KEY ON ÀÄÄÄÄÄÄÄÄÄÄÄÄ FREQUENCY DATA MULTiPLiER ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Sets the multiplier for the frequency data specified by block and F-number. This multiplier is applied to the FM carrier or modulation frequencies. The multiplication factor and corresonding harmonic types are shown in the following table: ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ³ MULT. ³ x ³ HARMONiC ³ ÆÍÍÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵ ³ [0] ³ 0.5 ³ 1 octave below ³ ³ [1] ³ 1 ³ at the voice's specified frequency ³ ³ [2] ³ 2 ³ 1 octave above ³ ³ [3] ³ 3 ³ 1 octave and a 5th above ³ ³ [4] ³ 4 ³ 2 octaves above ³ ³ [5] ³ 5 ³ 2 octaves and a Major 3rd above ³ ³ [6] ³ 6 ³ 2 octaves and a 5th above ³ ³ [7] ³ 7 ³ 2 octaves and a Minor 7th above ³ ³ [8] ³ 8 ³ 3 octaves above ³ ³ [9] ³ 9 ³ 3 octaves and a Major 2nd above ³ ³ [A] ³ 10 ³ 3 octaves and a Major 3rd above ³ ³ [B] ³ 10 ³ ... ³ ³ [C] ³ 12 ³ 3 octaves and a 5th above ³ ³ [D] ³ 12 ³ ... ³ ³ [E] ³ 15 ³ 3 octaves and a Major 7th above ³ ³ [F] ³ 15 ³ ... ³ ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ Ú-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú ú ù V. EFFECTS ù ú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù [0xy] ARPEGGiO ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command causes the note to quickly cycle through three notes: the note playing, a note 'x' halftones above, and a note 'y' halftones above. This causes an effect similar to old C64 chords. Note that the song speed has to be greater or equal to three in order to perform arpeggio effect completely. [1xx] FREQUENCY SLiDE UP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command slides the frequency up (pitch bend). Parameter 'xx' gives speed of slide. [2xx] FREQUENCY SLiDE DOWN ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command slides the frequency down (pitch bend). Parameter 'xx' gives speed of slide. [3xx] TONE PORTAMENTO ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command is used together with a note and will slide to its frequency. Parameter 'xx' gives speed of slide. If you specify 'xx' as '00' then the previous value will be used. [4xy] ViBRATO ÄÄÄÄÄÄÄÄÄÄÄÄÄ This command causes the frequency to oscillate with depth 'y' at speed 'x'. If you specify 'xy' as '00' then the previous value will be used. [5xy] TONE PORTAMENTO WiTH VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Tone portamento and Volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [6xy] ViBRATO WiTH VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Vibrato and Volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [7xx] FiNE FREQUENCY SLiDE UP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command slides the frequency up (pitch bend) once per row. Parameter 'xx' gives speed of slide. [8xx] FiNE FREQUENCY SLiDE DOWN ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command slides the frequency down (pitch bend) once per row. Parameter 'xx' gives speed of slide. [9xx] SET MODULATOR VOLUME ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command sets the volume of modulator slot. Value of 'xx' ranges from 0 to 3F (softest -> loudest). [Axy] VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command fades the volume up or down at the given speed. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'x' then 'y' is not used, and vice versa. [Bxx] PATTERN JUMP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command causes the song to jump to order 'xx'. This is often used to create looping songs. If two 'Bxx' commands are given, then the command in the higher track will take effect. [Cxx] SET iNSTRUMENT VOLUME ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command sets the absolute volume of the instrument. It is equal to Ixx command when instrument uses FM connection, otherwise both carrier and modulator volume is updated. Value of 'xx' ranges from 0 to 3F (softest -> loudest). [Dxx] PATTERN BREAK ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command signifies the end of the current pattern, and also that the next pattern should be played from row 'xx'. If two 'Dxx' commands are given, then the command in the higher track will take effect. [Exx] SET TEMPO ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command changes the song tempo (also known as BPM). Parameter 'xx' gives hexadecimal value of refresh rate in Hz. If two 'Exx' commands are given, then the command in the higher track will take effect. [Fxx] SET SPEED ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command changes the song speed. Parameter 'xx' gives how many frames to wait before advancing row. If two 'Fxx' commands are given, then the command in the higher track will take effect. [Gxy] TONE PORTAMENTO WiTH FiNE VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Tone portamento and Fine volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Hxy] ViBRATO WiTH FiNE VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Vibrato and Fine volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Ixx] SET CARRiER VOLUME ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command sets the volume of carrier slot. Value of 'xx' ranges from 0 to 3F (softest -> loudest). [Jxy] SET WAVEFORM ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command changes the waveform of carrier or modulator slot. Parameter 'x' gives carrier and 'y' modulator waveform type as following: '0'-'7' means type of waveform, 'F' means "no change". For more information see chapter IV, part "Waveform select". [Kxy] FiNE VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command fades the volume up or down at the given speed, once per row. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'x' then 'y' is not used, and vice versa. [Lxx] RETRiG NOTE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command retriggs the note after 'xx' frames. If no note is specified, last given is used. The lower is the interval, the faster is the retrigger. [Mxy] TREMOLO ÄÄÄÄÄÄÄÄÄÄÄÄÄ This command causes the volume to oscillate with depth 'y' at speed 'x'. If you specify 'xy' as '00' then the previous value will be used. Tremolo acts like vibrato, but changing the volume instead of the pitch. [Nxy] TREMOR ÄÄÄÄÄÄÄÄÄÄÄÄ This command causes the volume to remain normal for 'x' frames, then fades the volume to zero for 'y' frames. [Oxy] ARPEGGiO WiTH VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Arpeggio and Volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Pxy] ARPEGGiO WiTH FiNE VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Arpeggio and Fine volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Qxy] MULTi RETRiG NOTE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command retriggs the note after 'x' frames with specified volume change. Parameter 'y' gives type of volume change: '0' is None, '8' is Unused, '1' is -1, '9' is +1, '2' is -2, 'a' is +2, '3' is -4, 'b' is +4, '4' is -8, 'c' is +8, '5' is -16, 'd' is +16, '6' is *2/3, 'e' is *3/2, '7' is *1/2, 'f' is *2. If no note is specified, last given is used. The lower is the interval, the faster is the retrigger. [Rxy] FREQUENCY SLiDE UP WiTH VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Frequency slide up and Volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Sxy] FREQUENCY SLiDE DOWN WiTH VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Frequency slide down and Volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Txy] FiNE FREQUENCY SLiDE UP WiTH VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Fine frequency slide up and Volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Uxy] FiNE FREQUENCY SLiDE DOWN WiTH VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Fine frequency slide down and Volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Vxy] FREQUENCY SLiDE UP WiTH FiNE VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Frequency slide up and Fine volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Wxy] FREQUENCY SLiDE DOWN WiTH FiNE VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Frequency slide down and Fine volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Xxy] FiNE FREQUENCY SLiDE UP WITH FiNE VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Fine frequency slide up and Fine volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Yxy] FiNE FREQUENCY SLiDE DOWN WiTH FiNE VOLUME SLiDE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command executes both Fine frequency slide down and Fine volume slide. Parameter 'xy' gives speed of volume slide: 'x' is speed of slide up, 'y' is speed of slide down. If you specify 'xy' as '00' then the previous value will be used. [Z0x] SET TREMOLO DEPTH ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command changes the Tremolo depth of all 36 operators. Parameter 'x' gives depth: '0' is 1dB, '1' is 4.8dB. [Z1x] SET ViBRATO DEPTH ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command changes the Vibrato depth of all 36 operators. Parameter 'x' gives depth: '0' is 7%, '1' is 14%. [Z2x] SET MODULATOR'S ATTACK RATE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ADSR command. Parameter 'x' gives the value. For more information see chapter IV, part "Attack rate". [Z3x] SET MODULATOR'S DECAY RATE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ADSR command. Parameter 'x' gives the value. For more information see chapter IV, part "Decay rate". [Z4x] SET MODULATOR'S SUSTAiN LEVEL ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ADSR command. Parameter 'x' gives the value. For more information see chapter IV, part "Sustain level". [Z5x] SET MODULATOR'S RELEASE RATE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ADSR command. Parameter 'x' gives the value. For more information see chapter IV, part "Release rate". [Z6x] SET CARRiER'S ATTACK RATE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ADSR command. Parameter 'x' gives the value. For more information see chapter IV, part "Attack rate". [Z7x] SET CARRiER'S DECAY RATE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ADSR command. Parameter 'x' gives the value. For more information see chapter IV, part "Decay rate". [Z8x] SET CARRiER'S SUSTAiN LEVEL ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ADSR command. Parameter 'x' gives the value. For more information see chapter IV, part "Sustain level". [Z9x] SET CARRiER'S RELEASE RATE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ADSR command. Parameter 'x' gives the value. For more information see chapter IV, part "Release rate". [ZAx] SET FEEDBACK STRENGTH ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command changes the Feedback strength of current instrument. Parameter 'x' gives the value. For more information see chapter IV, part "Feedback strength". [ZBx] SET PANNiNG POSiTiON ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command changes the panning of current instrument. Parameter 'x' gives position: '0' is center, '1' is left, '2' is right. [ZCx] PATTERN LOOP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: ZC0 - Set loopback point ZCx - Loop x times. This pattern space-saving feature will cause the pattern to be looped 'x' times back to the last ZC0 command. Note that you can only loop within the pattern, and each track has its own loopback information, so you are supposed to have corresponding ZC0 and ZCx commands in the same track in order to operate. If ZCx commands are put in both effect columns, only the one in first column will operate. [ZDx] RECURSiVE PATTERN LOOP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Syntax: ZD0 - Set loopback point ZDx - Loop x times. This command is recursive variant of ZCx effect command. It means that when such kind of loop is located inside other "parent" loop, it is proceeded any time it is passed by this loop. Note that using ZC0 instead of ZD0 command has the same effect. Please keep in mind that ZDx command should not be used in combination with ZCx command in other effect column, otherwise it will cause an endless loop. [ZE0/ZE1] TOGGLE MACRO KEY-OFF LOOP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command temporarily turns on-or-off looping of Key-Off phase in macro-table for current instrument. Parameter 'x' gives the state to toggle: '0' is OFF, '1' is ON. Note that "temporarily" means that the change is valid until there will be set different instrument than is the current one, for which this command is to be used. [ZE2/ZE3] TOGGLE RESTART ENVOLOPE WiTH TONE PORTAMENTO ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command turns on-or-off restarting of ADSR envelope for current track. It means, that the note key will be retriggered for every row with non-empty input in the note column (rows where note culumn is empty are not affected). Parameter 'x' gives the state to toggle: '2' is OFF, '3' is ON. [ZE4] PERFORM RESTART ENVELOPE ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command restarts ADSR envelope for current instrument. [ZE5/ZE6] TOGGLE 4OP TRACK VOLUME LOCK ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command turns on-or-off 4OP Track Volume Lock. If 4OP Track Volume Lock is set, some of the volume effect commands will work in 4OP mode instead of default (2OP) mode. This means, that volume attenuation is calculated according 4OP connection of the 2 used instruments in track 2) and 1), and you don't have to manage carrier/modulator output level to get desired volume level during playback. Parameter 'x' gives the state to toggle: '5' is OFF, '6' is ON. Here is a complete list of commands that are affected by this lock: 5xy/6xy, Axy, Cxx, Gxy/Hxy, Kxy, Mxy, Rxy/Sxy, Txy/Uxy, Vxy/Wxy, Xxy/Yxy, ^xy, %xx Please note that when the 4OP Track Volume Lock is set for particular 4OP tracks, setting of 'Volume Scaling' is ignored (it is mandatory ON). [ZE7] PERFORM BPM SLiDE USiNG >xx AND xx and xx, xx, loudest). [%xx] SET GLOBAL VOLUME ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command sets the global volume of song. Value of 'xx' ranges from 0 to 3F (softest -> loudest). [>xx] GLOBAL FREQ. SLiDE UP ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ This command slides the frequency up (pitch bend) in all tracks from current to last, if it's not overridden by using another 'xx' in second effect column or one of succeeding tracks. Parameter 'xx' gives speed of slide. Note that you can also use Fine or Extra Fine variant of this command by putting command switch 'ZFD' or 'ZFE' into second effect column. [xx" and enhanced functionality of old "ZFD","ZFE" commands) . fixed processing of new effects in Debug Info window . fixed some typing check bugs in Replace window . fixed bug when after swapping instruments one name was incomplete . fixed cursor key navigation within Remap and Replace window . removed mouse support for screen srolling . added back VESA text-mode emulation and enhanced used screen contents accordingly (refer to option 'screen_mode' and 'comp_text_mode' for compatibility mode in config file) . added Rearrange Tracks function (hotkey: ^X) . added automatic activation of debug mode and switchover from offline to normal debug mode with Space when in Debug Info window . fixed/improved precision of fast-forward/rewind pattern function . added navigation to program home directory in File Browser window with Shift+Backspace key (refer also to option "home_dir_path") . added quick selection for muting track numbers above 9 with Shift key . fixed treating of all +/- combos for keyboards without NUMPAD . fixed player calibration issue with pattern break command . AT2 player updated to version 0.42 * fixed interface bugs in Instrument Editor window * fixed fast-forward/rewind outside Pattern Editor window; added functionality to Instrument Control panel * fixed interface bug with ~xy effect command in 2nd effect column * fixed bug when entering notes for 4OP tracks in midiboard mode caused putting wrong instrument in left track of the pair * fixed rearrange function (faulty reordering of tracks) * version 2.3.52 released: 10/27/2014 . fixed switchover from offline to normal debug mode with ^Enter . fixed not working instrument selection with no 4OP track extension . fixed position bugs in File Selector . fixed lately introduced bug in Tone Portamento (arrgh) . fixed treating Tone Portamento with offline Debug and Note Recorder . fixed usage of non-NUMPAD asterisk (*) key for track ON/OFF flags . fixed/improved Replace function and added new shortkey functions . fixed pattern/order editor refresh bug occurring with small song speeds . added synchronized instrument/command processing for selected tracks when Note Recorder mode is armed . added quick reset of track group selection (hotkey: [Alt] Q) . added 'fps_down_factor' option to config file . improved layout in Instrument Control panel * version 2.3.51 released: 09/05/2014 . changes in Note Recorder feature: - fixed bug when deleting notes was operating in wrong track if current track view on screen was moved by user; fixed precision with high song speeds (all notes are deleted now :) - added possibility to switch between using custom instrument and using present instruments in tracks (hotkey: Space / [Alt] Space) - improved keyboard reference on Help screen * version 2.3.50 released: 07/28/2014 (* 07/30/2014) . fixed ADSR preview update with enhanced screen modes . added Note Recorder feature (hotkey: ^Space); changed hotkey for Synth! mode to [Alt] Space * fixed some missing usage of non-NUMPAD +/- keys * version 2.3.49 released: 07/14/2014 (* 07/15/2014) . improved current track movement in Debug Info window . added macro details section to Debug Info window . added flipped paste block feature (hotkey: Alt+Shift+V) . fixed/improved File Browser and Replace window . enhanced cursor movement in File Browser and Replace window . enhanced Help screen navigation for effect columns . added FX volume information processing in marked block . small changes in user interface * fixed deviation between real and OPL3-emulated playback which was caused by misuse of FM-register macro; updated AT2 player to version 0.41 * version 2.3.48 released: 06/13/2014 . added 'Set Custom Speed Table' effect command (`xx) . fixed conversion of FMK files . fixed forced OPL3 port range to 1-FFFFh . fixed processing of Force instrument volume effect for 'AM' connections . fixed bug in post-processing of Arpeggio effect . small fixes in Arpeggio import from S3M files . fixed/improved/enhanced ADSR preview feature . optimized/enhanced color scheme options in config file . added possibility to control config file options with command line (refer to tip #25 in program documentation); removed obsolete "/aXXXX" option for OPL3 autodetection . fixed handling of ON/OFF flags for 4-OP track pair . added positional memory for Song variables and Replace window . majorly improved Debug Info window functionality (hotkey: ^D) . AT2 player updated to version 0.40 * version 2.3.47 released: 04/02/2014 (* 04/09/2014) . fixed current instrument control in Macro Browser window . fixed macro speed manipulation and Song Variables value update . fixed keypress repeat between instrument/macro speed control . fixed macro table preview bug with positive/negative columns . added macro speed control to Instrument Editor window . added FM-register macro table preview to Instrument Macro Browser . improved layout in Arpeggio/Vibrato Macro Editor window . improved positional memory logic . added enhanced screen layouts from SDL version (refer to option "screen_mode" in config file); removed obsolete VESA support and options from config file . major fixes/cleanups/optimizations of source code . updated incomplete key reference information in Help and .doc file . fixed some keyboard routines for potentially less hardware issues . fixed not initialized song timer in AT2 Player * fixed text cursor position issue with mouse driver under DOS * reverted back to "FT" as default typing mode * version 2.3.46 released: 03/14/2014 . fixed general faulty behavior of save-required notification . fixed wrong instrument naming when loading complete A2W bank . fixed position behavior of instrument selection for load/paste register data operation in Macro Editor window . completely recoded refresh routines of realtime graphics for more efficient CPU usage; removed option "cpu_saving" from config file . fixed arpeggio/vibrato macro table pointer in Macro Editor window * version 2.3.45 released: 03/11/2014 . improved debugging information on program crash screen . added new modules from Diode Milliampere . slightly fixed Synth! mode behavior in Pattern Editor window . added fully-featured macro browser . added bank browser for A2B and A2W files (finally :) . added file-dependent positional memory to all bank browsers . added positional memory to Macro Editor window . fixed command typing bug in arpeggio macro table . improved paste operation in more places of the tracker . improved navigation system in Macro Editor window . improved layout of Macro Editor window . overall major improvements in macro data exchange and user handling * version 2.3.44 released: 02/11/2014 . fixed bug in playback calibration (macros were not processed) . added command typing behavior mode handling in Macro Editor window . added some new modules (Madbrain’s awesome A2M collection is hopefully complete now :) and a bit put to order some old ones . added instrument type indicators in Macro Editor window . added instrument type indicators and possibility to change current instrument in Instrument Editor window . changed handling of F2/F3 related actions over instrument data * version 2.3.43 released: 02/06/2014 . fixed interface bugs in Transpose and Pattern List window . changed F2/F3 related key combos: - some quick-load functionality was disabled for safety reasons; only single instruments and patterns can be quick loaded now - all quick-save functionality disabled except for saving A2M file in Pattern Editor / Pattern Order window - hot key for saving instrument bank w/ macros ([Shift] ^F2) in Instrument Control panel was simplified to [Shift] F2 . changed loading process of A2W files: - only FM-register / FM-register Macro Table instrument data is loaded within Instrument Control panel - only Arpeggio/Vibrato Macro Table data is loaded within Arpeggio/Vibrato Macro Table Editor window . added some modules from OxygenStar, a.o. to Modules directory . added new "AT" command typing behavior mode (like FT but without cycling pattern moves) (hotkey: Shift+F11); if not overridden by config file, this mode is set by default . updated "techinfo.doc" file * version 2.3.42 released: 01/26/2014 . fixed bug in replay routine (playback never advanced to order #7f) . added quick access key for Macro Editor window (^Q) . added macro-preview mode for Arpeggio/Vibrato Macro Editor window . added possibility to change current instrument directly within Macro Editor window (new key combo: Ctrl+[]) . added possibility to change current instrument and octave while macro-preview mode is activated * version 2.3.41 released: 01/22/2014 . fixed bug in replay routine (frequency data output for 4OP channels) . fixed bug with channel calculation in 4OP binding mode . added ADSR preview indication to Instrument Control panel . updated AdT2 player to version 0.38 (full source code included) . updated "techinfo.doc" file * version 2.3.40 released: 01/17/2014 . fixed program freeze with marking block at 4OP channel . fixed bug with track binding not displayed without panning lock on in Song Variables window . fixed binding of two 4OP instruments in Instrument Control panel . fixed toggle of ADSR preview (new key combo: [Ctrl] LShift/RShift) . improved MPU-401 status reporting . removed "timer_precision" option from config file * version 2.3.39 released: 01/17/2012 as 2.4.00 at Google Code by ijsf . MPU-401 compatible MIDI slave mode, can be used to send notes to Adlib Tracker II, also known as "synth mode" * version 2.3.38 released: 06/10/2007 . fixed bugs with command typing selection (ST/FT) . added play state preview when in instrument control panel . optimizations for running in DOSBox environment * version 2.3.37 released: 01/06/2006 . changed behavior of ZFF command (refer to "adtrack2.doc" file) . slightly fixed off-tune bug with preview of macro-instruments . fixed !xx and @xx command . added playback control in instrument control panel (refer to tip #22) . added activity indicators to instrument control panel . fixed high CPU usage while playing w/o trace and some window is open . fixed scrollbar bug . fixed decimal values to hexadecimal in debug info and instrument editor . fixed volume on testing instrument in song with volume_scaling set . fixed arpeggio/vibrato table played on testing macro-instrument . added compatibility text-mode (refer to "troubleshooting" options) . improved CFF loader stability (implemented internal YsComp decompression) * version 2.3.36 released: 02/21/2004 (* 10/13/2004) never officially released . added possibility to toggle off ADSR preview (hotkey: [ScrollLock]) . added possibility to quick-adjust loop begin and loop length (hotkey: [Shift] ^Home,End and [Shift] ^PgUp,PgDown) . added separated arpeggio/vibrato editing (hotkey: ^E) . improved cursor navigation with Home,End and [Shift] Home,End keys . improved song change indicator . improved scrollbar accuracy . improved speed of internal calculation routines . improved replace feature . improved macro editor convenience . improved running program under Windows NT/2000/XP (no system warnings - but no drive info either :) . fixed jerky playback on setting octave in instrument control panel . fixed marked pattern indicator in pattern list . fixed timing bug in player . fixed song tracing when pattern is delayed . fixed pattern delay effect command * improved tracing in pattern editor and pattern order window * changed layout for on/off fm-registers (TVKS) * version 2.3.35 released: 01/28/2003 . added instrument w/ fm-register macro file format (A2F) . added optional playback w/ sync (refer to tip #18) . added CPU saving feature (refer to "troubleshooting" options) . added note retrigger to FM-register macro-table (refer to tip #21) . added ^Home and ^End as quick-adjust table length in macro editor . added macro indicator to instrument control panel . added [Alt] B as toggle last marked block . added highlighting of currently played line number . added some block marking intelligence (it's no Einstein, though :) . added disabling columns in fm-register macro table (refer to tip #20) . added checking key-off phase while testing instrument (refer to tip #17) . added single-playing pattern (hotkey: [Alt] F6) . added playback without synchronization (hotkey: [Alt] F5,F8,F9) . added ADSR preview to instrument editor . added full-view text-mode emulation (refer to "troubleshooting" options) . added [Ctrl] F8 or [Ctrl] F9 as play from current line . added [Shift] ^V or [Shift][Alt] P as partial block pasting . added [Ctrl][Tab] V as multiple object pasting . added pattern list (hotkey: ^P) (cool, isn't it? :) . added behavior mode hotkeys (F11,F12) and behavior indicator . fixed some keyboard routines (due to national keyboard drivers) . fixed processing global volume in tracker . fixed loading text font to graphic card's memory (hardware method used) . fixed some bugs in player (it should not crash now ;) . fixed slow movement in pattern order window . fixed some interface bugs . improved midiboard (note can be tracked while playing with no trace) . improved decay bars and volume analyzer in both tracker and player . improved several interface functions * version 2.3.34 released: 12/02/2002 . changed line counter (at status line) to decimal mode . added optional OPLx latency (refer to "troubleshooting" options) . fixed minor bugs in both tracker and player * version 2.3.33 released: 10/06/2002 . replay routine sourcecode changes: sorcecode is both TMTPC and FPC compatible added optional fading out fixed minor bugs . added text-mode emulation (refer to "troubleshooting" options) . added screen saver . added FMK file support . added initial lock states to song variables . added more FM-register control effect commands (#0x-#Cx) . added extra fine vibrato and tremolo effect commands (~xy,^xy) . added extra fine arpeggio effect command ($xy) . added extra fine frequency slide effect commands (&Ex,&Fx) . added extra fine volume slide effect commands (&Cx,&Dx) . added extra fine global volume slide effect commands (&Ax,&Bx) . added 4-op track extension (ogie dogie :) . added force instrument volume effect command (=xx) . added replace feature (hotkey: ^H) . fixed mixing block bug in pattern editor . fixed tremor effect command . fixed retrig note and multi retrig note effect commands . fixed loading FIN instruments . fixed instrument preview . improved autodetection of OPL3 interface . improved program documentation . improved debugging mode and playback navigation . improved song timer . improved importing AMD/S3M/SAT/SA2/XMS modules . improved overall volume control (made a bit more logarithmic :) . improved debug info window . improved macro editor and instrument editor . improved program interface * version 2.3.32 released: 04/05/2002 . major cosmetic improvements (finally had time to do that :) . advanced macro frequency range (1000Hz should be enough, imho :) . fixed behavior of global volume indicator . fixed errors in macro editor * version 2.3.31 released: 01/08/2002 (* 03/21/2002) . added lots of other things I can't remember now =) . added lots of AdLib modules . added instrument preview in file open dialog and bank browser . added FIB and FIN file support . added IBK file support . added BNK file support . added S3M file support . added indicator of unsaved data . added fine vibrato/tremolo switch commands (ZFD,ZFE) . added pattern length and number of tracks settings . added volume scaling switch . added 2nd effect column (useful, isn't it? :) . added global volume effects (%xx,&6x,&7x,&8x,&9x) . added vibrato off and tremolo off effect commands (ZFB,ZFC) . added tremolo effect command (Mxy); manual slide up/down has been remapped to &4x,&5x (fine-tune up/down) . added fixed-note system . added percussion track extension (yep, yep :) . improved file format (smaller files :) . improved transpose feature . improved instrument preview (chords can be done :) . improved command typing (see tip #5 in doc file) . improved importing AMD/XMS modules . improved importing RAD modules . improved importing SAT/SA2 modules . improved importing CFF/DFM/HSC/MTK modules . fixed pattern loop in combination with Bxx/Dxx effect commands . fixed calculating frequency shift up/down . fixed pattern delay effect command . fixed saving tiny modules . removed mouse requirement (mouse emulation keys: [Ctrl][Tab] Arrows) . increased number of patterns and instruments available . recoded task switching (looks like multi-tasking, eh? :) . completely recoded timer and keyboard routines * added swap arpeggio table effect command (!xx) * added swap vibrato table effect command (@xx) * added arpeggio/vibrato table swapping switch command (ZFF) * added macro key-off loop command (ZEx) * added instrument macro-definitions (yep! they kick EdLib's ass, imho :) * added instrument bank with macros file format (A2W) * fixed song change indicator * fixed instrument testing/preview * fixed loading older A2P/A2B/A2I file formats * removed pattern/order editing restriction while song is played * version 2.3.30 released: 02/10/2001 (* 02/24/2001) . added TMT Pascal port of replay routine . added icon (adtrack2.ico) for the tracker (thanks to Corona688 :) . added brandnew modules from Nula and Malfunction/Altair . added drive identification in directory lister . added active octave and instrument indicators . added quick octave setting (hotkey: [Shift] 1..8) . added remapping of instruments (hotkey: ^R) . added instrument swapping in instrument control panel . added note delay and note cut effect commands (&2x,&3x) . added pattern delay effect commands (&0x,&1x) . added pattern loop and recursive pattern loop effect commands (ZCx,ZDx) . fixed replay of tone portamento with volume slide effect commands . fixed sorting in directory lister . fixed ZAx effect command . fixed typing in effect command definitions * added backup feature for song state (Hotkeys: /, [Shift] /) * fixed loading pattern files * fixed all (?) cosmetic bugs :)) * added FPC port of replay routine * fixed TMT Pascal port of replay routine * fixed instrument loading bug * version 2.3.29 released: 12/31/2000 . added brandnew modules from Nula and Malfunction/Altair . added track panning and track volume control . added pattern/song/track/block transpose (hotkey: ^T) . added sequencing [5xy,6xy],[Gxy,Hxy],[Oxy,Pxy],[Rxy-Yxy] effect commands . added frequency slide with volume slide effect commands (Rxy-Yxy) . added changing of instrument parameters while playing . fixed typing in "Jxy" effect command * version 2.3.28 released: 12/21/2000 . totally changed color scheme (hope you like it, guys :) . improved module and tiny module file format . implemented like 9 new effects (tremor, multi retrig, a.o.) . implemented advanced song variables . added support for DFM modules . bugfixes ;-D adlibtracker2-2.4.24/package/ver/dos/ADTRACK2.INI0000644000000000000000000004046413411003760017465 0ustar rootrootÚ-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú ú ù ù ù /´DLiB TR/´CK3R ][ configuration file ù ù version 2.3.57+ ù ù ù ú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù [PATHS] ; Program Home Directory (used within File Browser window) ; Please specify full path here. If empty, directory where adtrack2.exe ; is located will be used. home_dir_path= ; The following are static paths used while saving data files. ; To toggle dynamic path system, leave space after equal sign empty. a2m_default_path=modules\ a2t_default_path=modules\ a2i_default_path=instr\ a2p_default_path=modules\ a2b_default_path=instr\ a2w_default_path=instr\ a2f_default_path=instr\ [STARTUP] init_tempo=50 ; default tempo (1-255) init_speed=6 ; default speed (hex) (1-FF) init_macro_speedup=1 ; default macro speed-up (range is optional!) octave=4 ; default octave (1-8) patt_len=64 ; default pattern length (1-256) nm_tracks=18 ; default number of tracks (1-20) midiboard=on ; default state for MidiBoard mark_lines=off ; default state for line marking [CONTROL] trace_by_default=on ; play with trace as the default action nosync_by_default=off ; play without sync as the default action keep_position=on ; keep position after quick load alt_ins_name=on ; alternative instrument name ("instrXXX") adjust_tracks=on ; adjust number of tracks for corresponding module linefeed=on ; process line feeding in pattern editor lf_in_mboard_mode=off ; treat line feeding option in MidiBoard mode update_ins=off ; update active instrument by typing in numbers cycle_pattern=on ; cycle vertical and horizontal moves inside pattern keep_track_pos=off ; keep track position (column) when jumping over tracks remember_ins_pos=on ; remember slot and position for each instrument backspace_dir=1 ; backspace direction: ; [1] forwards ; [2] backwards command_typing=1 ; command typing: ; [0] mOrOn ; [1] FastTracker ; [2] Scream Tracker [CONVERSiON] fix_c_note_bug=on ; fix C-note bug (transpose CFF/HSC halftone up); ; correction is needed to properly replay: ; - CFF modules (any version of BoomTracker) ; - HSC modules (HSC-Tracker version 1.3 or above) accurate_conv=off ; convert CFF/DFM/HSC/MTK modules with highest accuracy ; NOTE: playback will be 100% accurate, but handling ; and further editing will be complicated fmk_flip_stereo=on ; flip stereo option in FM-Kingtracker force_ins=0 ; force type of "ins" file: ; [0] autodetect ; [1] HSC-Tracker/RAD-Tracker ; [2] SAdT ; [3] Amusic/AdLib instrument [TiMiNG] fforward_factor=1 ; mult. factor for fast-forward during playback (1-5) rewind_factor=1 ; mult. factor for rewind during playback (1-5) ssaver_time=5 ; time (minutes) before calling screen saver (0 -> off) 18hz_fix=on ; treat 18 Hz tempo as 18.2 Hz [COSMETiCS] mod_description=off ; list description (if any) included in module use_h_for_b=off ; use "h" instead of "b" in note system highlight_controls=on ; highlight common effects (i.e. jump,loop,speed/tempo) decay_bar_rise=3 ; decay bar's rise speed (1-10) decay_bar_fall=3 ; decay bar's fall speed (1-10) scroll_bars=on ; process scrollbars in pattern & order list pattern_layout=0 ; pattern layout: ; [0] AdT2 ; [1] FastTracker ; [2] Scream Tracker [COLORS] // main screen main_background=1 ; background main_title=11 ; title main_border=11 ; border main_stat_line=3 ; status line text main_hi_stat_line=11 ; status line highlighted text main_dis_stat_line=5 ; status line disabled text main_behavior=13 ; behavior mode indicator main_behavior_dis=5 ; behavior mode disabled indicator // scrollbars scrollbar_bckg=3 ; background scrollbar=0 ; text scrollbar_mark=11 ; position mark scrollbar_2nd_mark=15 ; 2nd position mark // status window status_background=1 ; background status_border=14 ; border status_static_txt=11 ; static text status_dynamic_txt=15 ; dynamic text status_play_state=7 ; play state status_text_dis=5 ; disabled text // pattern order window order_background=1 ; background order_hi_bckg=5 ; highlighted background order_border=10 ; border order_entry=3 ; entry order_hi_entry=11 ; highlighted entry order_patt#=7 ; pattern number order_patt#_jump=2 ; pattern number (jump) order_hi_patt#=15 ; highlighted pattern number order_played_b=12 ; currently played order background order_played=0 ; currently played order order_input_bckg=11 ; string input background order_input=0 ; string input text order_input_warn=12 ; string input warning // pattern editor window pattern_bckg=1 ; background pattern_border=15 ; border pattern_pos_indic=11 ; position indicator pattern_pan_indic=3 ; panning indicator pattern_gpan_indic=15 ; track panning indicator pattern_lock_indic=7 ; lock indicator pattern_4op_indic=14 ; 4-OP track indicator pattern_perc_indic=15 ; percussion track indicator pattern_chan_indic=14 ; track OFF indicator pattern_row_bckg=5 ; current row background pattern_row_bckg_p=12 ; currently played row background pattern_block_bckg=2 ; block background pattern_line#=3 ; line number pattern_line#_p=0 ; currently played line number pattern_hi_line#=11 ; highlighted line number pattern_row_bckg_m=11 ; current row background ¿ pattern_line#_m=11 ; line number à if line marking is active pattern_hi_line#_m=3 ; highlighted line number Ù pattern_note=7 ; note pattern_hi_note=15 ; highlighted note pattern_note0=3 ; note (nul) pattern_hi_note0=12 ; highlighted note (nul) pattern_note_hid=9 ; hidden note pattern_hi_note_h=7 ; highlighted hidden note pattern_ins#=2 ; instrument number pattern_hi_ins#=10 ; highlighted instrument number pattern_ins#0=2 ; instrument number (nul) pattern_hi_ins#0=10 ; highlighted instrument number (nul) pattern_cmnd=7 ; effect command pattern_hi_cmnd=15 ; highlighted effect command pattern_cmnd0=3 ; effect command (nul) pattern_hi_cmnd0=11 ; highlighted effect command (nul) pattern_fix_note=11 ; fixed note pattern_hi_fx_note=14 ; higlighted fixed note pattern_cmnd_ctrl=13 ; controls if "highlight controls" is ON pattern_note_m=9 ; note ¿ pattern_note0_m=9 ; note (nul) ³ pattern_note_hid_m=13 ; hidden note ³ pattern_ins#_m=2 ; instrument number à if line marking is active pattern_ins#0_m=2 ; instrument number ³ pattern_cmnd_m=9 ; effect command ³ pattern_cmnd0_m=9 ; effect command (nul) ³ pattern_fix_note_m=14 ; fixed note Ù pattern_note_b=15 ; note ¿ pattern_note0_b=11 ; note (nul) ³ pattern_note_hid_b=5 ; hidden note à if block is being marked pattern_ins#_b=10 ; instrument number ³ pattern_ins#0_b=10 ; instrument number ³ pattern_cmnd_b=15 ; effect command ³ pattern_cmnd0_b=11 ; effect command (nul) ³ pattern_fix_note_b=14 ; fixed note Ù pattern_input_bckg=11 ; string input background pattern_input=0 ; string input text pattern_input_warn=8 ; string input warning // macro editor window macro_background=4 ; background macro_title=11 ; title macro_border=15 ; border macro_topic=12 ; topic macro_topic2=13 ; topic #2 macro_hi_topic=14 ; highlighted topic macro_text=13 ; text macro_hi_text=14 ; highlighted text macro_text_dis=6 ; disabled text macro_text_loop=12 ; text [loop] macro_text_keyoff=3 ; text [key-off] macro_current_bckg=5 ; current line background macro_current=13 ; current line text macro_current_dis=0 ; current line disabled text macro_current_loop=12 ; current line text [loop] macro_current_koff=11 ; current line text [key-off] macro_input_bckg=7 ; string input background macro_input=0 ; string input text macro_def_bckg=12 ; string input default text background macro_def=0 ; string input default text macro_scrbar_bckg=7 ; scrollbar background macro_scrbar_text=0 ; scrollbar text macro_scrbar_mark=15 ; scrollbar position mark macro_hint=7 ; hint macro_item=15 ; item text macro_short=14 ; item shortcut macro_item_dis=7 ; item disabled macro_sel_itm_bckg=7 ; selected item background macro_sel_itm=0 ; selected item text macro_sel_short=4 ; selected item shortcut macro_context=14 ; context macro_context_dis=7 ; disabled context // volume analyzer window analyzer_bckg=1 ; background analyzer=3 ; text analyzer_overallvol=3 ; overall volume analyzer_volumelvl=7 ; volume level analyzer_modulator=2 ; modulator intensity analyzer_carrier=3 ; carrier intensity // debug info window debug_info_bckg=4 ; background debug_info_bckg2=9 ; background of current track debug_info_border=5 ; border debug_info_border2=15 ; border #2 debug_info_title=11 ; title debug_info_topic=14 ; topic debug_info_txt=7 ; text debug_info_hi_txt=15 ; highlighted text debug_info_txt_hid=6 ; hidden text debug_info_mod=2 ; modulator data debug_info_hi_mod=10 ; highlighted modulator data debug_info_car=3 ; carrier data debug_info_hi_car=11 ; highlighted carrier data debug_info_4op=8 ; 4-OP track indicator debug_info_perc=8 ; percussion track indicator debug_info_bpm=8 ; BPM indicator // help window help_background=4 ; background help_title=11 ; title help_border=15 ; border help_topic=12 ; topic help_text=7 ; text help_hi_text=12 ; higlighted text help_keys=15 ; keys, keywords help_indicators=14 ; position indicators // instrument editor windows instrument_bckg=4 ; background instrument_title=11 ; title instrument_border=15 ; border instrument_text=7 ; text instrument_hi_text=15 ; highlighted text instrument_glob=13 ; global data instrument_hi_glob=15 ; highlighted global data instrument_hid=6 ; hidden text instrument_mod=2 ; modulator data instrument_car=3 ; carrier data instrument_hi_mod=10 ; highlighted modulator data instrument_hi_car=11 ; highlighted carrier data instrument_context=14 ; context instrument_con_dis=5 ; disabled context instrument_adsr=6 ; ADSR preview (background) // instrument activity indicators instrument_ai_off=6 ; never played instrument_ai_on=13 ; already played instrument_ai_trig=14 ; currently triggered // dialog boxes dialog_background=4 ; background dialog_title=11 ; title dialog_border=15 ; border dialog_text=13 ; text dialog_hi_text=14 ; highlighted text dialog_hid=6 ; hidden text dialog_item=15 ; item text dialog_short=14 ; item shortcut dialog_item_dis=5 ; disabled item dialog_sel_itm_bckg=7 ; selected item background dialog_sel_itm=0 ; selected item text dialog_sel_short=4 ; selected item shortcut dialog_context=14 ; context dialog_context_dis=7 ; disabled context dialog_context_dis2=9 ; disabled context #2 dialog_input_bckg=7 ; string input background dialog_input=0 ; string input text dialog_def_bckg=12 ; string input default text background dialog_def=0 ; string input default text dialog_prog_bar1=9 ; progress bar color #1 dialog_prog_bar2=11 ; progress bar color #2 dialog_topic=13 ; topic dialog_hi_topic=14 ; highlighted topic dialog_mod_text=10 ; modulator specific text dialog_car_text=11 ; carrier specific text dialog_misc_indic=8 ; miscellaneuos indicators // RGB color palette color00=00,00,00 ; color #0 color01=05,10,30 ; color #1 color02=00,30,30 ; color #2 color03=00,30,40 ; color #3 color04=00,00,20 ; color #4 color05=15,25,35 ; color #5 color06=00,10,25 ; color #6 color07=20,30,40 ; color #7 color08=45,35,50 ; color #8 color09=10,20,30 ; color #9 color10=20,40,40 ; color #10 color11=20,40,50 ; color #11 color12=25,35,50 ; color #12 color13=30,35,45 ; color #13 color14=35,60,60 ; color #14 color15=40,50,55 ; color #15 [SYSTEM SETTiNGS] // adlib hardware adlib_port=0 ; OPL3 interface's base address: ; [0] autodetection ; [1-FFFFh] user definable range opl_latency=0 ; OPLx register writes latency: ; [0] opl3-optimized (recommended) ; [1] 3.3 + 23 æs (use in case of troubles only) // program screen screen_mode=0 ; program screen mode: ; [0] classic view (90x40 @ 720x480) (recommended) ; [1] extended view (120x50 @ 800x600) [SVGA][*] ; [2] wide extended view (180x60 @ 1024x768) [SVGA][*] ; [3] compatibility text-mode (...) ; [4] fullscreen (90x38 @ 800x600) [SVGA] ; [5] extended fullscreen (120x47 @ 1024x768) [SVGA] comp_text_mode=0 ; compatibility text-mode: ; [0] 80x30 ; [1] 80x25 ; [2] 90x30 (default) Ä¿ ; [3] 90x47 à VESA text-mode emulation ; [4] 120x47 ÄÙ fps_down_factor=0 ; CPU saving factor for realtime gfx presentation ; and VESA text-mode emulation: ; [0] none ; [1-10] slowdown factor (1=least, 10=most) // peripherals typematic_rate=0 ; typematic rate [0] 30 chars/sec ... [31] 2 chars/sec typematic_delay=0 ; typematic delay [0] 250 ms ... [3] 1s mouse_hspeed=50 ; horizontal speed in mickeys/pixel mouse_vspeed=50 ; vertical speed in mickeys/pixel mouse_threshold=0 ; speed-doubling threshold in mickeys/second mouse_disabled=off ; disable screen scrolling by mouse // ******************************************* // ** Custom SVGA text-mode configuration ** // ******************************************* custom_svga_mode=off ; custom SVGA text-mode (only use this mode ; if you know what you are doing) svga_txt_columns=100 ; columns (80..180) svga_txt_rows=37 ; rows (25..60) // CRTC register values (hex) (00-FF) crtc_misc_out=6b ; Miscellaneous output crtc_h_total=70 ; Horizontal total crtc_h_disp_en_end=63 ; Horizontal display enable end crtc_h_blank_start=64 ; Horizontal blank start crtc_h_blank_end=82 ; Horizontal blank end crtc_h_ret_start=65 ; Horizontal retrace start crtc_h_ret_end=82 ; Horizontal retrace end crtc_v_total=70 ; Vertical total crtc_overflow_reg=f0 ; Overflow register crtc_preset_r_scan=00 ; Preset row scan crtc_max_scan_h=4f ; Maximum scan line/char height crtc_v_ret_start=5b ; Vertical retrace start crtc_v_ret_end=8c ; Vertical retrace end crtc_v_disp_en_end=4f ; Vertical display enable end crtc_offs_width=3c ; Offset/logical width crtc_underline_loc=00 ; Underline location crtc_v_blank_start=58 ; Vertical blank start crtc_v_blank_end=70 ; Vertical blank end crtc_mode_ctrl=a3 ; Mode control crtc_clock_m_reg=01 ; Clock mode register crtc_char_gen_sel=00 ; Character generator select crtc_memory_m_reg=00 ; Memory mode register crtc_mode_reg=10 ; Mode register crtc_misc_reg=0e ; Miscellaneous register crtc_mode_control=02 ; Mode control crtc_screen_b_clr=00 ; Screen border color crtc_colr_plane_en=0f ; Color plane enable crtc_h_panning=00 ; Horizontal panning crtc_color_select=00 ; Color select adlibtracker2-2.4.24/package/ver/dos/FILE_ID.DIZ0000644000000000000000000000171613411003760017431 0ustar rootroot úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ?? ? subz3ro's ? ? /?LiB TR/?K3R ][ G3 ? ?ÄÄÄÄÄÄ-ÄÄÄÄÄÄÄÄÄÄÄÄ--ùú 2.3.57 ?ÄÄÄÄÄÄÄÄÄÄÄÄ?-ùú ? ? HiGHLiGHTS ? ? úù-ÄÄÄÄÄÄÄÄÄÄ?? þ supports 4-op instruments, melodic and percussion instruments þ 255 instruments, 128 patterns, 128 order list entries þ 89 effect commands, and 22 extended commands ? þ supports: ? AMD,CFF,DFM,FMK,HSC,MTK,RAD, ? S3M,SAT,SA2,XMS, ? BNK,CiF,FiB,FiN,iBK,iNS, ? SBi,SGi ? ? þ 2 effect columns, ? instrument macro-definitions, MPU-401 MIDI slave mode, lots of adlib modules and instruments ? ?þ command-line player included ? ?unZip with "-d" option set ? ?ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ?-ùúadlibtracker2-2.4.24/package/ver/sdl/0000755000000000000000000000000013411003760015756 5ustar rootrootadlibtracker2-2.4.24/package/ver/sdl/linux/0000755000000000000000000000000013411003760017115 5ustar rootrootadlibtracker2-2.4.24/package/ver/sdl/linux/adtrack2_hq1.sh0000644000000000000000000000010613411003760021712 0ustar rootroot#!/bin/sh ./adtrack2 /cfg:sdl_screen_mode=1 /cfg:sdl_frame_rate=150 adlibtracker2-2.4.24/package/ver/sdl/linux/adtrack2.png0000644000000000000000000000614413411003760021323 0ustar rootroot‰PNG  IHDR üí£ +IDATxÚ ßóýÖÖL°¤Äƒ†Õ÷þþþþ%" ÿÿúýÿýýýýõõüþþþëþÿúøö÷öø  RQÿÿ¾ÄNöøy€jøòðÛþÿûýýÁÅH>:(ͲŠFOËþ ýûùù÷úýÿÌÓO3,3È®|FSÎø(ÿÿþõóôüÿÿÐØN/'.ÜÆ‘KSÎúû:ýüýýÿÿÿÿÿBз„GJÆù=ÿüüþñÿÿÿÿÿÿ6ú´—…_jåîFÿ   éúÿÿ-õ}R”¯êNÿ/-=>úúúÿ  úÿ ýþûú'óX‘–¯îU?0Ý‹Š3ÿÿÿþöòòù÷ù  þþþþêåí~S—–®÷` þþþ«¤ð¸©   ùúýèë÷¤ªUîèñ   þ þþýá×ì}Ržœ¯ $q ÿýPööéýéý& Ó$óõýÿÌ»æïƒ[ž ¯ :þÿþÿÿýýèñëíö÷þþýþ ÿÿþý61û’}ÛûŒf¢¡¦ Rªÿÿÿÿéöôö÷õ +þýý ÿþ5.÷‰lÚ—r–¢›ù ^Áþÿÿÿÿþý ÿýÿþûý\MÌ ~Ž™íeÒþþ üý›w{“Šçtáýÿþþÿÿþþÿþÿþÿûûùý ý°¶ÖÇ÷xäþþÿýÿøö÷÷ùø  ÝT_T$ýÿþþÿþýþýûþ ýþ þýþÿýÿÿ ÿýþþýÿýÿýþþþÿþÿÿúüùóîðüÿÿ ýÿÿýþü ýþþÿÿþÿþÿþþÿþþÿÿÿÿåïÿÎÿwÊÿýýýýýýÿûøðöý  ð€²üLIEND®B`‚adlibtracker2-2.4.24/package/ver/sdl/linux/adtrack2_hq2.sh0000644000000000000000000000010613411003760021713 0ustar rootroot#!/bin/sh ./adtrack2 /cfg:sdl_screen_mode=2 /cfg:sdl_frame_rate=150 adlibtracker2-2.4.24/package/ver/sdl/adtrack2.ini0000644000000000000000000003513213411003760020156 0ustar rootroot// // ADLiB TRACK3R II SDL configuration file // version 2.4.24+ // // [PATHS] ; Program Home Directory (used within File Browser window) ; Please specify full path here. If empty, directory where adtrack2.exe ; is located will be used. home_dir_path= ; Directory for storing recorded WAV files ; If you want to record all output to one file, specify it together with path ; including ".wav" extension (e.g. "wav_files\dump.wav" for Windows operating system ; resp. "wav_files/dump.wav" for Linux) otherwise every module being played ; will get its own WAV file with origin name. sdl_wav_directory=wav_files ; The following are static paths used while saving data files. ; To toggle dynamic path system, leave space after equal sign empty. ; In case you will be using nested directories, use correct separator character ; here ('\' for Windows operating system, resp. '/' for Linux). a2m_default_path=modules a2t_default_path=modules a2i_default_path=instr a2p_default_path=modules a2b_default_path=instr a2w_default_path=instr a2f_default_path=instr [STARTUP] init_tempo=50 ; default tempo (1-255) init_speed=6 ; default speed (hex) (1-FF) init_macro_speedup=1 ; default macro speed-up (range is optional!) octave=4 ; default octave (1-8) patt_len=64 ; default pattern length (1-256) nm_tracks=18 ; default number of tracks (1-20) midiboard=on ; default state for MidiBoard mark_lines=off ; default state for line marking [CONTROL] trace_by_default=on ; play with trace as the default action nosync_by_default=off ; play without sync as the default action keep_position=on ; keep position after quick load alt_ins_name=on ; alternative instrument name ("instrXXX") adjust_tracks=on ; adjust number of tracks for corresponding module linefeed=on ; process line feeding in pattern editor lf_in_mboard_mode=off ; treat line feeding option in MidiBoard mode update_ins=off ; update active instrument by typing in numbers cycle_pattern=on ; cycle vertical and horizontal moves inside pattern keep_track_pos=off ; keep track position (column) when jumping over tracks remember_ins_pos=on ; remember slot and position for each instrument backspace_dir=1 ; backspace direction: ; [1] forwards ; [2] backwards command_typing=1 ; command typing: ; [0] mOrOn ; [1] FastTracker ; [2] Scream Tracker [CONVERSiON] fix_c_note_bug=on ; fix C-note bug (transpose CFF/HSC halftone up); ; correction is needed to properly replay: ; - CFF modules (any version of BoomTracker) ; - HSC modules (HSC-Tracker version 1.3 or above) accurate_conv=off ; convert CFF/DFM/HSC/MTK modules with highest accuracy ; NOTE: playback will be 100% accurate, but handling ; and further editing will be complicated fmk_flip_stereo=on ; flip stereo option in FM-Kingtracker force_ins=0 ; force type of "ins" file: ; [0] autodetect ; [1] HSC-Tracker/RAD-Tracker ; [2] SAdT ; [3] Amusic/AdLib instrument [TiMiNG] fforward_factor=1 ; mult. factor for fast-forward during playback (1-5) rewind_factor=1 ; mult. factor for rewind during playback (1-5) 18hz_fix=on ; treat 18 Hz tempo as 18.2 Hz [COSMETiCS] mod_description=off ; list description (if any) included in module use_h_for_b=off ; use "h" instead of "b" in note system highlight_controls=on ; highlight common effects (i.e. jump,loop,speed/tempo) decay_bar_rise=3 ; decay bar's rise speed (1-10) decay_bar_fall=3 ; decay bar's fall speed (1-10) scroll_bars=on ; process scrollbars in pattern & order list pattern_layout=0 ; pattern layout: ; [0] AdT2 ; [1] FastTracker ; [2] Scream Tracker [COLORS] // main screen main_background=1 ; background main_title=11 ; title main_border=11 ; border main_stat_line=3 ; status line text main_hi_stat_line=11 ; status line highlighted text main_dis_stat_line=5 ; status line disabled text main_behavior=13 ; behavior mode indicator main_behavior_dis=5 ; behavior mode disabled indicator // scrollbars scrollbar_bckg=3 ; background scrollbar=0 ; text scrollbar_mark=11 ; position mark scrollbar_2nd_mark=15 ; 2nd position mark // status window status_background=1 ; background status_border=14 ; border status_static_txt=11 ; static text status_dynamic_txt=15 ; dynamic text status_play_state=7 ; play state status_text_dis=5 ; disabled text // pattern order window order_background=1 ; background order_hi_bckg=5 ; highlighted background order_border=10 ; border order_entry=3 ; entry order_hi_entry=11 ; highlighted entry order_patt#=7 ; pattern number order_patt#_jump=2 ; pattern number (jump) order_hi_patt#=15 ; highlighted pattern number order_played_b=12 ; currently played order background order_played=0 ; currently played order order_input_bckg=11 ; string input background order_input=0 ; string input text order_input_warn=12 ; string input warning // pattern editor window pattern_bckg=1 ; background pattern_border=15 ; border pattern_pos_indic=11 ; position indicator pattern_pan_indic=3 ; panning indicator pattern_gpan_indic=15 ; track panning indicator pattern_lock_indic=7 ; lock indicator pattern_4op_indic=14 ; 4-OP track indicator pattern_perc_indic=15 ; percussion track indicator pattern_chan_indic=14 ; track OFF indicator pattern_row_bckg=5 ; current row background pattern_row_bckg_p=12 ; currently played row background pattern_block_bckg=2 ; block background pattern_line#=3 ; line number pattern_line#_p=0 ; currently played line number pattern_hi_line#=11 ; highlighted line number pattern_row_bckg_m=11 ; current row background \ pattern_line#_m=11 ; line number > if line marking is active pattern_hi_line#_m=3 ; highlighted line number / pattern_note=7 ; note pattern_hi_note=15 ; highlighted note pattern_note0=3 ; note (nul) pattern_hi_note0=12 ; highlighted note (nul) pattern_note_hid=9 ; hidden note pattern_hi_note_h=7 ; highlighted hidden note pattern_ins#=2 ; instrument number pattern_hi_ins#=10 ; highlighted instrument number pattern_ins#0=2 ; instrument number (nul) pattern_hi_ins#0=10 ; highlighted instrument number (nul) pattern_cmnd=7 ; effect command pattern_hi_cmnd=15 ; highlighted effect command pattern_cmnd0=3 ; effect command (nul) pattern_hi_cmnd0=11 ; highlighted effect command (nul) pattern_fix_note=11 ; fixed note pattern_hi_fx_note=14 ; higlighted fixed note pattern_cmnd_ctrl=13 ; controls if "highlight controls" is ON pattern_note_m=9 ; note \ pattern_note0_m=9 ; note (nul) \ pattern_note_hid_m=13 ; hidden note \ pattern_ins#_m=2 ; instrument number > if line marking is active pattern_ins#0_m=2 ; instrument number / pattern_cmnd_m=9 ; effect command / pattern_cmnd0_m=9 ; effect command (nul) / pattern_fix_note_m=14 ; fixed note \ pattern_note_b=15 ; note \ pattern_note0_b=11 ; note (nul) \ pattern_note_hid_b=5 ; hidden note \ pattern_ins#_b=10 ; instrument number > if block is being marked pattern_ins#0_b=10 ; instrument number / pattern_cmnd_b=15 ; effect command / pattern_cmnd0_b=11 ; effect command (nul) / pattern_fix_note_b=14 ; fixed note / pattern_input_bckg=11 ; string input background pattern_input=0 ; string input text pattern_input_warn=8 ; string input warning // macro editor window macro_background=4 ; background macro_title=11 ; title macro_border=15 ; border macro_topic=12 ; topic macro_topic2=13 ; topic #2 macro_hi_topic=14 ; highlighted topic macro_text=13 ; text macro_hi_text=14 ; highlighted text macro_text_dis=6 ; disabled text macro_text_loop=12 ; text [loop] macro_text_keyoff=3 ; text [key-off] macro_current_bckg=5 ; current line background macro_current=13 ; current line text macro_current_dis=0 ; current line disabled text macro_current_loop=12 ; current line text [loop] macro_current_koff=11 ; current line text [key-off] macro_input_bckg=7 ; string input background macro_input=0 ; string input text macro_def_bckg=12 ; string input default text background macro_def=0 ; string input default text macro_scrbar_bckg=7 ; scrollbar background macro_scrbar_text=0 ; scrollbar text macro_scrbar_mark=15 ; scrollbar position mark macro_hint=7 ; hint macro_item=15 ; item text macro_short=14 ; item shortcut macro_item_dis=7 ; item disabled macro_sel_itm_bckg=7 ; selected item background macro_sel_itm=0 ; selected item text macro_sel_short=4 ; selected item shortcut macro_context=14 ; context macro_context_dis=7 ; disabled context // volume analyzer window analyzer_bckg=1 ; background analyzer=3 ; text analyzer_overallvol=3 ; overall volume analyzer_volumelvl=7 ; volume level analyzer_modulator=2 ; modulator intensity analyzer_carrier=3 ; carrier intensity // debug info window debug_info_bckg=4 ; background debug_info_bckg2=9 ; background of current track debug_info_border=5 ; border debug_info_border2=15 ; border #2 debug_info_title=11 ; title debug_info_topic=14 ; topic debug_info_txt=7 ; text debug_info_hi_txt=15 ; highlighted text debug_info_txt_hid=6 ; hidden text debug_info_mod=2 ; modulator data debug_info_hi_mod=10 ; highlighted modulator data debug_info_car=3 ; carrier data debug_info_hi_car=11 ; highlighted carrier data debug_info_4op=8 ; 4-OP track indicator debug_info_perc=8 ; percussion track indicator debug_info_bpm=8 ; BPM indicator // help window help_background=4 ; background help_title=11 ; title help_border=15 ; border help_topic=12 ; topic help_text=7 ; text help_hi_text=12 ; higlighted text help_keys=15 ; keys, keywords help_indicators=14 ; position indicators // instrument editor windows instrument_bckg=4 ; background instrument_title=11 ; title instrument_border=15 ; border instrument_text=7 ; text instrument_hi_text=15 ; highlighted text instrument_glob=13 ; global data instrument_hi_glob=15 ; highlighted global data instrument_hid=6 ; hidden text instrument_mod=2 ; modulator data instrument_car=3 ; carrier data instrument_hi_mod=10 ; highlighted modulator data instrument_hi_car=11 ; highlighted carrier data instrument_context=14 ; context instrument_con_dis=5 ; disabled context instrument_adsr=6 ; ADSR preview (background) // instrument activity indicators instrument_ai_off=6 ; never played instrument_ai_on=13 ; already played instrument_ai_trig=14 ; currently triggered // dialog boxes dialog_background=4 ; background dialog_title=11 ; title dialog_border=15 ; border dialog_text=13 ; text dialog_hi_text=14 ; highlighted text dialog_hid=6 ; hidden text dialog_item=15 ; item text dialog_short=14 ; item shortcut dialog_item_dis=5 ; disabled item dialog_sel_itm_bckg=7 ; selected item background dialog_sel_itm=0 ; selected item text dialog_sel_short=4 ; selected item shortcut dialog_context=14 ; context dialog_context_dis=7 ; disabled context dialog_context_dis2=9 ; disabled context #2 dialog_input_bckg=7 ; string input background dialog_input=0 ; string input text dialog_def_bckg=12 ; string input default text background dialog_def=0 ; string input default text dialog_prog_bar1=9 ; progress bar color #1 dialog_prog_bar2=11 ; progress bar color #2 dialog_topic=13 ; topic dialog_hi_topic=14 ; highlighted topic dialog_mod_text=10 ; modulator specific text dialog_car_text=11 ; carrier specific text dialog_misc_indic=8 ; miscellaneuos indicators // RGB color palette color00=00,00,00 ; color #0 color01=05,10,30 ; color #1 color02=00,30,30 ; color #2 color03=00,30,40 ; color #3 color04=00,00,20 ; color #4 color05=15,25,35 ; color #5 color06=00,10,25 ; color #6 color07=20,30,40 ; color #7 color08=45,35,50 ; color #8 color09=10,20,30 ; color #9 color10=20,40,40 ; color #10 color11=20,40,50 ; color #11 color12=25,35,50 ; color #12 color13=30,35,45 ; color #13 color14=35,60,60 ; color #14 color15=40,50,55 ; color #15 [SYSTEM SETTiNGS] // program screen sdl_screen_mode=0 ; program screen mode: ; [0] classic screen (90x40 @ 720x480p) ; [1] enhanced screen (120x50 @ 960x800p) ; [2] wide enhanced screen (180x60 @ 1440x960p) sdl_frame_rate=100 ; SDL screen frame rate in fps (50-200) ; DEFAULT: 100 fps ; NOTE: use smaller values for less CPU occupation, ; increase for smoother screen moves sdl_timer_slowdown=2 ; SDL timer slow-down factor in % (0-50) ; DEFAULT: 2% (measured with genuine Yamaha YMF262 chip) ; NOTE: only change the default value if you know ; what you are trying to do and why :-) // keyboard sdl_typematic_delay=150 ; typematic delay in ms (1-2000) sdl_typematic_rate=30 ; typematic rate in ms (1-100) adlibtracker2-2.4.24/package/ver/sdl/adtrack2.mht0000644000000000000000000777326213411003760020213 0ustar rootrootMIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_NextPart_01D49B5D.3D5D5E60" Tento dokument je jednosúborová webová stránka, nazývaná tiež súbor webového archívu. Ak sa vám zobrazuje toto hlásenie, váš prehliadaè alebo editor nepodporuje súbory webových archívov. Stiahnite si prehliadaè, ktorý podporuje webový archív. ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.htm Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="windows-1250"

 

 ┌^= 72;──────────&#= 9472;∙·          &n= bsp;            = ;            &n= bsp;             ·∙─────────^= 88;

 ∙      &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;     │

 ·       &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;    │

        &n= bsp;            = ;        subz3ro's   &nb= sp;            =             &nb= sp;         │

                        &nb= sp;        ─┬─  &nbs= p;    ──         &nb= sp;            =          │

        &n= bsp;            = ;       /┤DLiB│R/┤CK3R &= #9474;│ SDL           &n= bsp;            = ;   │

        &n= bsp;            = ;        │    &nb= sp;  │     ──    &= nbsp;           &nbs= p;              │

        &n= bsp;            = ;            &n= bsp;            = ;            &n= bsp;            = ;     │

        &n= bsp;                                                                   <= /o:p>

        &n= bsp;            = ;            &n= bsp;            = ;            &n= bsp;            = ;     │

 = CONTENTS          = ;                 &nb= sp;            =             &nb= sp;            =   ∙

        &n= bsp;            = ;               &nb= sp;                       &nb= sp;            =    ·

I= V. iNSTRUMENTS

&= nbsp;   V. EFFECTS

&= nbsp;  VI. SONG VARiABLES

&= nbsp; VII. GETTiNG STARTED

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I. PROLOGUE           &= nbsp;   

∙       &= nbsp; ·∙─────────^= 72;───────┘

 

 

 AdLib tracker is a 9-channel FM tracker for = the OPL2-compatible

 chips found on most sound cards.<= /span>

 A few years ago, there was a huge variety of AdLib trackers.

 The most common were:

 

 Zwerg Zwack/Chicken's HSC-Tracker,

 Jens-Christian Huus' EdLib,

 Shayde's Reality AdLib Tracker,

 Erik Pojar's Surprise! AdLib Tracker,

 and the latest piece of cake - Conqueror's Amusic.

 

 This new way of AdLib tracking was just that missing part in scene,

 splitting the two different worlds: a world = of ugly CMF shit,

 as Chicken used to say, and a world of sample based trackers, such as

 FastTracker or Impulse Tracker.

 

 The above trackers became pretty popular and were used to produce

 very nice FM music, short on size but high on quality. Such tunes were

 included in many BBS intros and demos. Unfortunately, the things

 went wrong, and AdLib tracking has come to fruition.

 

 Nowadays, at the end of second Millennium, i decided to revive this part

 of tracking history. Ladies and gentlemen, subz3ro is proud to present

 you a brandnew AdLib tool - /┤DLiB TR/= ┤CK3R ][.

 

 You may probably ask WHY? Let me use the wor= ds of Jens-Christian Huus,

 one of the most common people in C64 and AdL= ib programming, the author

 of EdLib:

 

 "People begun to actually hate FM sound= s. The arrival of GUS and AWE32

  made wavetable techniques very popular and indeed it sounds very good,

  but there are some things in the old FM standard that is unique.

  You can't fiddle with samples in the same w= ay as you can with FM.

  I personally never quite liked sampling, i = find it downright boring.

  With a FM chip it is like on a C64; you hav= e a few parameters and

  everything you do has to be done within the= se parameters.

  These boundaries makes it funny to make mus= ic, to see how far you can

  actually push AdLib. To do sounds on FM requires expertice but

  if you're good at it, almost any instrument= can be reproduced properly,

  except perhaps drums."

 

 

 ──────&#= 9472;───

 

 ■ features best available software OPL3 playback to this date

 

 ■ supports 4-op instruments, melodic a= nd percussion instruments

 

 ■ supports up to 255 instruments, 128 patterns, 128 order list entries,

   89 effect commands, and 22 extended commands

 

 ■ features 2 effect columns and instru= ment macro-definitions

 

 ■ loads following song formats:

     A2M (AdT2)

     A2P (AdT2) [pattern]=

     A2T (AdT2) [tiny module]<= o:p>

 N1/ AMD (Amusic)

     CFF (BoomTracker 4.0)

     D= FM (Digital-FM)

 N2/ FMK (FM-Kingtracker)

          MTK (MPU-401 trÆkkεr)

     RAD (Reality AdLib Tracker)       {ver.1}

 N3/ S3M (Scream Tracker 3.x)

 N4/ SAT (Surprise! AdLib Tracker)     {ver.1,5,6}

 N4/ SA2 (Surprise! AdLib Tracker 2.0) {ver.8= ,9}

 N1/ XMS (XMS-Tracker)

 

 Because of bug in Amusic's (and its crack XMS-Tracker's) replay routine,

 the Arpeggio effect used to generate buggy sounds. Since /┤DLiB TR/┤CK3R ][

 ain't got a support for such buggy things, t= he Arpeggio effect may differ.

 

 After conversion, the Tremolo and Vibrato effects may sound different,

 because FM-Kingtracker uses slow speed table (not 100% emulated in AT2)

 and optional waveform definitions that are currently not supported.

 Also the Retrig Note effect is slightly different (if i should be honest,

 i really couldn't get any sense of Sami's fr= ame counting; all i could

 do to make this effect sound way "authentic" was the frame correction during

 conversion phase--and this ain't perfect, th= ough :)

 The OPL3 setting is ignored, Stereo setting = is accepted, Rhythm mode is

 not supported, because it was incorrectly implemented in earlier

 versions of the tracker, and the author hims= elf stopped supporting it.

 Also the pattern order list will be truncate= d to 128 if exceeds.

 

 Conversion of these (primarily sample based) modules may not be 100% exact.

 Therefore Slide Up/Down, Vibrato, and Tone Portamento effects may be

 inaccurate after importing to /┤DLiB T= R/┤CK3R ][.

 Anyway, some experimental methods are used to fix up the fine-tuning

 and frequency slide based Scream Tracker's effects during

 conversion phase (experimental understand as "non-perfect" :)

 Note that the optional vibrato/tremolo wavef= orms are not supported.

 Also the pattern order list will be truncate= d to 128 if exceeds.

 

 Since Surprise! AdLib Tracker uses non-stand= ard Volume Slide procedure

 in replay routine, Volume Slide based effects may differ after importing

 to /┤DLiB TR/┤CK3R ][. Anyway, an experimental method to fix up

 this difference is used during conversion ph= ase (blabla, same as above :)

 The special arpeggio is also currently not supported (anyway, there are

 no SA2 modules using that feature, afaik :)<= o:p>

 

 ■ loads following instrument formats:<= o:p>

     A2i (AdT2)

     A2F (AdT2) [w/fm-register macro]

     CiF (BoomTracker 4.0)

     FiN (FM-Kingtracker)=

     iNS (HSC-Tracker/RAD-Trac= ker, SAdT, Amusic/AdLib instrument)

     SBi (Creative Labs FM instrument)

     SGi (Sound Generator 3.0)=

 

 Note that the type of "ins" file c= an be set up in configuration file

 if neccessary (see option "force_ins").

 

 ■ loads following bank formats:

     A2B (AdT2)

     A2W (AdT2) [w/macros]

     BNK (AdLib instrument ban= k) {ver.1.0}

     FiB (FM-Kingtracker)=

     iBK (Creative Labs FM instrument bank)

 

 ■ The tracker supports block operation= s, and has an instrument editor.

   In addition, it features Tracing, Debugging, and a MidiBoard.

 

 ■ The tracker reads many of its settin= gs from a configuration file.

   It has strong support geared for row = by row tracing, pausing,

   and playing from any line in a patter= n.

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I= I. SCREEN LAYOUT          = 729;

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 The main window of the tracker is roughly composed of 5 parts:

 

   A. The upper left hand window shows t= he Status of the song

      (paused, playing, etc.), row number and order/pattern position,

      current speed/tempo, time playing and file information.

 

   B. The upper right hand window is the Pattern Order.

      There the user can build the order by which the patterns are played.

 

   C. The main window is the Pattern Edi= tor with total count of 18/20 tracks,

      5 tracks visible at= a time, where the user can compose the song,

      enter the notes, commands, number of instrument, and effects.

 

   D. The Status Line at the bottom where the user can keep track

      of the different mo= des and the active mode which is

      highlighted (MBoard, Trace, Debug, Track, Synth!), active octave,

      active instrument, behavior mode, a.o. The user should experiment

      to gain familiarity with different modes that can be activated.

 

   E. The bottom window under Pattern Ed= itor shows the Volume Analyzer.

      User have to scroll= up the rest of main screen to see it.

      You can get all the volume information (carrier and modulator

      output level, overa= ll volume and global song volume,

      approximate intensi= ty in dB) there.

 

 

 ──────&#= 9472;──────────= ───

 

 [A]=           means the 'a' key on your keyboard

 [^A= ]         means the 'a' key + [Ctrl]

 [Sh= ift] A    means the 'a' key + [Shift]

 [Al= t] A      means the 'a' key + [Alt]

 [Sh= ift] ^A   means the 'a' key + [Ctrl] + [Shift]

 [Al= t] ^A     means the 'a' key + [Ctrl] + [Alt]

 

 In case of composite shortkeys, it is recommended to use following

 order of pressing the keys:

 

 1st: [Ctrl] (if any)

 2nd: [Alt] or [Shift] or [Tab] (if any)

 3rd: "ordinary" key (if any :)

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I= II. KEY REFERENCE         ∙

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;

 

 F1<= /b>            =            Help

 F2 = (^S)           &= nbsp;      Save file

 F3 = (^L)           &= nbsp;      Load file

 F4 = (^A)           &= nbsp;      Toggle Nuke'm dialog

 F5<= /b>            =            Play

 F6<= /b>            =            Pause

 F7<= /b>            =            Stop

 F8<= /b>            =            Play song from current pattern or order

 F9<= /b>            =            Play current pattern or order only

 [Ct= rl] F8           = ;     @F8 from current line

 [Ct= rl] F9           = ;     @F9 from current line (Pattern Editor)

 [Al= t] F6           =       Single-play pattern   (Shift toggles trace)

 [Al= t] F5           =       @F5

 [Al= t] F8                 @F8 ├ = without synchronization

 [Al= t] F9           =       @F9

 [Shift] F2               Quick Save

 [Shift] F3               Quick Load

 [Sh= ift] F5           &nb= sp;   F5 with Trace

 [Sh= ift] F6           &nb= sp;   Toggle Debug mode from position at cursor

 [Sh= ift] F8          &nbs= p;    F8 with Trace

 [Sh= ift] F9           &nb= sp;   F9 with Trace

 [Sh= ift] Space            Toggle MidiBoard mode ON/OFF

 ^Space                   Toggle Note Recorder m= ode ON/OFF (if possible)

 [Ct= rl] Home,End          Skip to previous/next pattern while Tracing

 +,-=             = ;          Same as above; play pattern from start

 

 ┌───= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;───┐

 γ= 4; WHEN iN NOTE RECORDER MODE                                            γ= 4;

 ζ= 0;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┤<= /span>

 γ= 4; ^Left,^Right     Select group of tracks for recording=                 

 γ= 4; Enter            Start recording from current position (*)           

 γ= 4; Space            Toggle using custom instrumen= t for all tracks       γ= 4;

 γ= 4; [Alt] Space      Toggle using present instruments in tracks    ref. γ= 4;

 γ= 4; MBoard keys      Write notes to corresponding tracks=            (*) 

 γ= 4; F8,F9            Toggle pattern repeat OFF/ON<= span style=3D'mso-spacerun:yes'>                        γ= 4;

 γ= 4; Backspace        Clear note/instrument sequence in tracks             γ= 4;

 Backspace       Clear complete note/instrument columns               γ= 4;

 γ= 4; Up,Down          Rewind/Fast-Forward while recording                  γ= 4;

 γ= 4; [Shift] Up,Down  Increase/Decrease row correction for wr= iting notes  

 γ= 4; [Shift] F6       Continue in Debug mode from positi= on at cursor      

 γ= 4; F7               Stop recording and reset starting position;          γ= 4;

 γ= 4;                  current group of tracks= can be modified              γ= 4;

 γ= 4; [Alt] 1..9,0     Toggle track channel ON/OFF (Shift toggles 1X)       γ= 4;

 γ= 4; [Alt] R          Reset flags on all tracks                            γ= 4;

 γ= 4; *=                 Reverse ON/OFF = on all tracks                         γ= 4;

 ζ= 0;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┤<= /span>

 γ= 4; In case you need non-continuos track selection, you can choose       

 γ= 4; from already selected group a subset of tracks where notes will be   

 γ= 4; written by manipulating track ON/OFF flags.                           γ= 4;

 ε= 2;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┘<= /span>

 

 ┌───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────┐

  iF SONG iS PLAYED WiTH TRACE, iT CAN BE REMOVED WHiLE...        &nb= sp; γ= 4;

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────┤

  Enter        Playback is paused and cursor stays on position     

  Esc          Cursor jumps to last position and playba= ck continues

 γ= 4; [Shift] Esc  Cursor stays on position and playback continues     

 └───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────┘

 

 Note that playing with Trace and playing wit= hout synchronization can be

 set up in configuration file (see options "trace_by_default"

 and "nosync_by_default")

 

 

 ^En= ter           &n= bsp;       Play next pattern according to order

 ^Le= ft  (Up)           &= nbsp;  Rewind current pattern (with Trace)

 ^Ri= ght (Down)            Fast-Forward (with Trace)

 [Ctrl]{Shift} Up,Down    Change playback speed up/down {fine stepping}

 [Ctrl]{Shift} Up+Down    Reset playback speed {default speed}

 [Ctrl][Alt] <hold down>  Temporarily show Debug Info window=

 ^B                       Toggle Message Boa= rd window

 ^D                       Toggle Debug Info = window

 ^Q                       Toggle Instrument = Macro Editor window

 ^G<= /b>            =            Toggle Arpeggio/Vibrato Macro Editor window

 ^M                       Toggle Macro Brows= er window

 ^F<= /b>            =            Toggle Song Variables window

 ^H<= /b>            =            Toggle Replace window

 ^I<= /b>            =            Toggle Instrument Control panel

 ^E<= /b>            =            Toggle Instrument Editor window

 ^O<= /b>            =            Toggle Octave Control panel

 ^P<= /b>            =            Toggle Pattern List window

 ^R<= /b>            =            Toggle Remap Instrument window

 ^T<= /b>            =            Toggle Transpose window

 ^X<= /b>            =            Toggle Rearrange Tracks window

 ^1.= .^8           &n= bsp;       Quick-set octave

 [Al= t] +,- (Up,Down)      Adjust volume level of sound output

 [Al= t] C             &nb= sp;    Copy object to clipboard (with selection)

 [Al= t] P           &= nbsp;      Paste object from clipboard

 [Al= t] M           &= nbsp;      Toggle marking lines ON/OFF

 [Al= t] L           &= nbsp;      Toggle Line Marking Setup window

 [Al= t] 1..9,0           = ;  Toggle track channel ON/OFF (Shift= toggles 1X)<= /p>

 [Al= t] S           &= nbsp;      Set all OFF except current track (solo)

 [Al= t] R           &= nbsp;      Reset flags on all tracks

 *            &= nbsp;           Reverse ON/OFF on all tracks=

 F10                      Quit program

 F11                      Toggle typing mode = in Pattern Editor (AT-►FT-►ST)<= /span>

 F12                      Toggle line feed in Pattern Editor<= /o:p>

 [Shift] F12              Toggle jump to marked line in Pattern Editor

 [Ctrl][Tab] [...] (*)    Scroll Volume Analyzer section (if necessary)

 

 (*) Up,Down,PgUp,PgDown

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 [Alt|Ctrl]{Shift} F11    Toggle WAV recording ON

 [Alt|Ctrl]{Shift} F12    Toggle WAV recording OFF

 

 ┌───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────┐

  FUNCTiONALiTY OF ALTERNATiVE KEYS                   

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────┤

  Alt    Toggle normal recording mode                 

  Ctrl   Toggle 'per track' recording mode            

  Shift  Toggle Fade in / Fade out sound processing   

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────┤

  POSSiBLE COMBiNATiONS: Alt,Ctrl,Alt+Shift,Ctrl+Shift

 └───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────┘

 

 If 'per t= rack' recording mode is activated and song playback is stopped<= /p>

 you can exclude/include corresponing tracks from/to being recorded

 with ordi= nary track selection procedure:

 

 [Alt] 1..9,0             Toggle track channel ON/OFF = (Shift toggles 1X)

 [Alt] S                  Set all OFF except curr= ent track (solo)

 [Alt] R                  Reset flags on all trac= ks

 

 

 III= /3. PATTERN ORDER KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 Up,= Down,Left,Right       Cursor navigation

 PgU= p,PgDn           = ;     Move up/down 32 patterns

 Hom= e,End           =       Move to the top/end of pattern order

 Tab= ,[Shift] Tab          Move to next/previous entry

 Ins= ert           &n= bsp;       Insert new entry

 Del= ete           &n= bsp;       Delete entry

 Bac= kspace           = ;     Clear entry

 ^Sp= ace           &n= bsp;       Enter skip mark

 ^C<= /b>            =            Copy entry to clipboard

 ^V<= /b>            =            Paste entry from clipboard

 +,-=             = ;          Adjust entry

 ^F2=             = ;          Save module in tiny format

 Ent= er           &nb= sp;        Switch to Pattern Editor

 

 Note that 80-FF pattern number range causes a jump in pattern order.

 syntax: order_number[hex](+80h); e.g. "9A" jumps to order 1A

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 Up,= Down,Left,Right       Cursor navigation

 PgU= p,PgDn           = ;     Move up/down 16 lines

 Hom= e,End           =       Move to the top/end of current pattern

 Tab= ,[Shift] Tab          Move to next/previous track

 [Sh= ift] PgDn,PgUp (+,-)  Move to next/previous pattern

 [Sh= ift] Home,End         Move fwd./bckw= d. to the first/last pattern

 ^Ho= me,^End          &nbs= p;    Move to the end/top of previous/next pattern

 Spa= ce           &nb= sp;        Advance to next row

 ^Pg= Up,^PgDn          &nb= sp;   Transpose note (block) halftone up/down

 Bac= kspace           = ;     Remove note or clear attributes

 Ins= ert           &n= bsp;       Insert new line (within track only)

 Del= ete           &n= bsp;       Delete line (within track only)

 [Sh= ift] Insert           Inse= rt new line

 [Sh= ift] Delete           Dele= te line

 [Sh= ift] Enter            Toggle fixed and regular note

 ^K<= /b>            =            Insert Key-Off

 ^C<= /b>            =            Copy object at cursor to clipboard

 ^V<= /b>            =            Paste object from clipboard

 [Alt][Shift] P           Paste object from clipboard to= more patterns

 ^Z                       Undo last operation (if poss= ible)

 {Ct= rl} "[","]"       &n= bsp;   Change current instrument

 [Al= t] F2           =       Save current pattern to file

 ^F2=             = ;          Save module in tiny format

 [Shift] F3               Quick load recent pattern = data

 Ent= er           &nb= sp;        Switch to Pattern Order

 

 NOTE SYSTEM: C,C#,D,D#,E,F,F#,G,G#,A,A#,B(H)

 VAL= iD NOTE ENTRiES: C,C-,C#,C1,C-1,C#1...

 

 ┌───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┐

  BLOCK OPERATiONS iN PATTERN EDiTOR       =             = ;           

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┤

  Starting to mark a block: [Shift] Up,Down,Left,Right    &nbs= p;       

  When at least one row in one track is marked, you can continue  

  marking also with PgUp,PgDn,Home,End (Shift is stil= l held down!)

  Quick mark: [Alt] Q (1x-2x-3x) track ─> pattern ─> discard      

  Toggle last marked block: [Alt] B    &n= bsp;            = ;            &n= bsp; 

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┤

  ^B  Blank block  (Insert blank block to pattern)           &= nbsp;    

  ^C  Copy block   (Copy block to clipboard)           = ;           

  ^D  Delete block (Remove block from pattern)           &= nbsp;        

  ^N  Nuke block   (Clear block contents)           =             &nb= sp; 

  ^V  Paste block  (Paste block from cli= pboard to pattern) (*)  &nb= sp; 

  ^X  Cut block    (Combine bo= th Copy and Delete operation)       

 ├───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┤

  (*) PASTE BLOCK OPERATiON VARiANTS                               γ= 4;

  ¯¯¯¯¯¯¯¯&m= acr;¯¯¯¯¯¯¯¯¯¯¯¯= ;¯¯¯¯¯¯¯¯¯¯¯¯&m= acr;                               γ= 4;

  "Paste block" operation has th= ree other functional variants      γ= 4;

  with different key shortcuts for activation:                     γ= 4;

  1) [Alt] V toggles "Mix block" operation, when block data       

     from clipboard is applied without overwriting existing data; 

  2) [Shift] ^V toggles "Selective paste block" operation,        

     when only block data from clipboard corresponding to current 

     cursor position is being applied (i.e. note, instrument,     

     1st effect or 2nd effect).                                    γ= 4;

 γ= 4; 3) [Alt][Shift] V toggles "Flipped paste block" operation,=       

 γ= 4;    when block data from clipboard is app= lied vertically flipped.

 γ= 4;                                                =                  

 γ= 4; MANiPULATiON WiTH FX VOLUME iNFORM= ATiON                          γ= 4;

  ¯¯¯¯¯¯¯¯&m= acr;¯¯¯¯¯¯¯¯¯¯¯¯= ;¯¯¯¯¯¯¯¯¯¯¯¯&m= acr;¯¯¯¯¯                          γ= 4;

  When there is bl= ock marked, which contains some effect        =   

 γ= 4; commands carrying volume information, you can increase/decrease 

 γ= 4; their values with +/- keys.                                      

 γ= 4; Effect commands are processed with following priority:          

 γ= 4;   1) Set instrument volume (Cxx),                                γ= 4;

 γ= 4;      Force instrument volume (=3Dxx)                               γ= 4;

 γ= 4;   2) Set modulator volume (9xx)                                  γ= 4;

 γ= 4;   3) Set carrier volume (Ixx)                                    γ= 4;

 γ= 4;   4) Set global volume (%xx)                                     γ= 4;

 γ= 4; If effect command with higher priority has been processed,      

 γ= 4; all remaining effect commands with lower priority are skipped.  

 └───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────┘

 

 

 III= /5. PATTERN LiST WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─

 

 Up,= Down           &= nbsp;      Cursor navigation

 PgU= p,PgDn           = ;     Move up/down 20 patterns

 Hom= e,End           =       Move to the top/end of pattern list

 Spa= ce           &nb= sp;        Mark/Unmark pattern

 ^Sp= ace           &n= bsp;       Unmark all marked patterns

 [Sh= ift] ^Space           Reve= rse marks on all patterns

 [Al= t] C (^C)           &= nbsp; Copy pattern to clipboard

 [Al= t] P (^V)           &= nbsp; Paste pattern from clipboard

 [Sh= ift] ^V               Paste pattern data f= rom clipboard

 [Al= t] V                  Paste pattern n= ame from clipboard

 ^N                       Nuke current patte= rn

 [Shift] ^N               Nuke all marked patterns

 ^W<= /b>            =            Swap marked patterns

 [Sh= ift] ^W           &nb= sp;   Swap marked patterns w/o names

 [Sh= ift] Insert           Inse= rt new pattern

 [Sh= ift] Delete           Dele= te pattern

 Ent= er           &nb= sp;        Rename pattern / Multiple paste

 [Shift] F3               Quick load recent pattern = data

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 III= /6. iNSTRUMENT CONTROL PANEL KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────

 

 Up,= Down                  Cursor navigation

 PgU= p,PgDn           = ;     Move up/down 16 instruments

 Hom= e,End           =       Move to the top/end of instrument list

 Spa= ce           &nb= sp;        Mark/Unmark instrument

 MBo= ard keys <hold down>  Preview instrument

 Ent= er           &nb= sp;        Rename instrument

 ^C<= /b>            =            Copy instrument to clipboard

 [Sh= ift] ^C           &nb= sp;   Copy instrument also with macro-definitions

 ^V<= /b>            =            Paste instrument(s) from clipboard

 [Sh= ift] ^V               Paste instrument data from clipb= oard

 [Al= t] V                &n= bsp; Paste instrument name(s) from clipboard

 ^W<= /b>            =            Swap marked instruments

 [Sh= ift] ^W           &nb= sp;   Swap marked instruments w/o names

 Tab=             = ;          Toggle Instrument Editor window

 [Sh= ift] Tab           &n= bsp;  Toggle Instrument Macro Editor window

 [Shift] O                Toggle operator mode 4OP = / 2OP

 [Sh= ift] M,B,S,T,C,H      Toggle melodic and percussion (BD,SD,TT,TC,HH)

 [Sh= ift] F2             &nb= sp; Save instrument w/ fm-register macro to file

 [Al= t] F2           =       Save instrument bank to file

 ^F2=                    &nb= sp;  Save instrument bank w/ all macros to file

 [Shift] F3               Quick load recent instrume= nt data

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 III= /7. iNSTRUMENT EDiTOR WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────

 

 Up,= Down,Left,Right,

 Hom= e,End           =       Cursor navigation

 [Alt] <section hotkey>   Jump to section

 Tab=             = ;          Jump to next setting

 [Sh= ift] Tab           &n= bsp;  Jump to previous setting

 +,- (PgUp,PgDn)          Adjust value

 Spa= ce           &nb= sp;        Select item

 ^Sp= ace (opt.)            Toggle ADSR preview ON/OFF

 [Ctrl] "[","]"           Change current instrument=

 [Ctrl][Shift] "[","]"= ;    Change macro speed<= /o:p>

 [Alt]{Shift} 1..4,0      Set operators for instrument previe= w (*)

 MBo= ard keys <hold down>  Preview instrument

 Ent= er           &nb= sp;        Toggle carrier/modulator/4OP slot settings

 [Shift] O                Toggle operator mode 4OP = / 2OP

 [Shift] M,B,S,T,C,H      Toggle melodic and percussion (BD,SD,TT,TC,HH)

 [Shift] F2               Save instrument w/ fm-regi= ster macro to file

 [Shift] Enter            Copy values from carrier/modu= lator slot

 Esc=             = ;          Return to Instrument Control panel

 

 (*) [Alt] 1..4           Set solo operator

     [Alt][Shift] 1..4    Toggle operator ON/OFF

     [Alt] 0              Reset 

 

 

 III= /8. iNSTRUMENT MACRO EDiTOR WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;─

 

 Up,= Down,Left,Right

 Hom= e,End           =       Cursor navigation

 PgU= p,PgDown          &nb= sp;   Move up/down 16 lines

 Tab (Enter)          &nbs= p;   Jump to next field in order

 [Sh= ift] Tab             &nb= sp;Jump to previous field in order

 [Sh= ift] Up,Down          Synchrono= us navigation within tables

 [Sh= ift] Home,End         Move to the start/end of current line in table

 ^Left,^Right             Switch between macro tables<= o:p>

 [Shift] ^Left,^Right     Navigate to start/end of macro table=

 ^PgUp,^PgDown   &n= bsp;        Change current arpeggio/vibrato table

 [Ctrl] "[","]"           Change current instrument=

 [Ct= rl][Shift] "[","]"    = Change macro speed

 [Alt]{Shift} 1..4,0      Set operators for inst= rument preview (*)<= /p>

 [Alt] ^C                  [Alt] ^M                 <= /o:p>

 ^C [Sh= ift] ^C           &nb= sp;   Copy column in table

 ^V<= /b>            =            Paste object from clipboard

 ^En= ter           &n= bsp;       Paste data from instrument registers

 [Sh= ift] Enter            Paste data to instrument registers

 [Sh= ift] ^Enter           Paste data from instrument registers w/ selection

 Bac= kspace           = ;     Clear current item in table

 [Sh= ift] Backspace        Clear line in table=

 +,-=              = ;         Adjust value at cursor / current item in table

 ^Ho= me,^End          &nbs= p;    Quick-adjust table length

 [Sh= ift] ^Home,^End       Quick-adjust loop begin position

 [Sh= ift] ^PgUp,^PgDown    Quick-adjust loop length

 Ins= ert           &n= bsp;       Insert new line in table

 Del= ete           &n= bsp;       Delete line in table

 ^E                       Toggle envelope re= start ON/OFF    

 ^N                       Toggle note retrig= ger ON/OFF      

 ^Z                       Toggle ZERO freque= ncy ON/OFF      

 [Alt] ^E,^N,^Z           Reset all alike flags in table=      FM-register

 ^Ba= ckspace          &nbs= p;    Toggle corresponding column ON/OFF table

 [Al= t] S           &= nbsp;      Set all OFF except current column 

 [Al= t] R           &= nbsp;      Reset flags on all columns         = │<= /span>

 *            =             Reverse ON/OFF on all columns      ┘<= /span>

 \            &= nbsp;           Toggle current item (switch types only)

 Spa= ce           &nb= sp;        Toggle macro-preview mode

 ^Sp= ace           &n= bsp;       Toggle Key-Off loop within macro-preview mode

 ^F2                      Save instrument bank w/ all ma= cros to file

 Esc=             = ;          Leave Instrument Macro Editor window

 

 (*) [Alt] 1..4           Set solo operator

     [Alt][Shift] 1..4    Toggle operator ON/OFF

     [Alt] 0              Reset 

 

 

 III= /9. APREGGiO/ViBRATO MACRO EDiTOR WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;───────

 

 Up,= Down,Left,Right

 Hom= e,End           =       Cursor navigation

 PgU= p,PgDown          &nb= sp;   Move up/down 16 lines

 Tab (Enter)          &nbs= p;   Jump to next field in order

 [Sh= ift] Tab           &n= bsp;  Jump to previous field in order

 [Sh= ift] Up,Down          Synchrono= us navigation within tables

 ^Left,^Right             Switch between macro tables<= o:p>

 [Shift] ^Left,^Right     Navigate to start/end of macro table=

 ^Pg= Up,^PgDown          &= nbsp; Change current arpeggio/vibrato table

 [Ctrl] "[","]"           Change current instrument=

 [Ctrl][Shift] "[","]"= ;    Change macro speed<= /o:p>

 [Alt]{Shift} 1..4,0      Set operators for inst= rument preview (*)<= /p>

 ^C<= /b>            =            Copy line in table (whole table respectively)<= /span>

 [Sh= ift] ^C           &nb= sp;   Copy column in table

 ^V<= /b>            =            Paste object from clipboard

 Bac= kspace           = ;     Clear current item in table

 [Sh= ift] Backspace        Clear line in table=

 +,-=                     &n= bsp; Adjust value at cursor / current item in table

 ^Ho= me,^End          &nbs= p;    Quick-adjust table length

 [Sh= ift] ^Home,^End       Quick-adjust loop begin position

 [Sh= ift] ^PgUp,^PgDown    Quick-adjust loop length

 Spa= ce           &nb= sp;        Toggle macro-preview mode

 ^Sp= ace           &n= bsp;       Toggle Key-Off loop within macro-preview mode

 Esc=             = ;          Leave Arpeggio/Vibrato Macro Editor window

 

 (*) [Alt] 1..4           Set solo operator

     [Alt][Shift] 1..4    Toggle operator ON/OFF

     [Alt] 0              Reset 

 

 

 III= /10. iNSTRUMENT MACRO BROWSER KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;───────

 

 Up,Down,PgUp,PgDown

 Home,End                 Cursor navigation

 [Shift] Up,Down          Move up/down in macro table=

 [Shift] Left,Right       Move left/right in macro table

 [Shift] PgUp,PgDown      Move page up/down in macro table

 [Shift] Home,End         Move to the start/end of macro t= able

 [Ctrl] Home,End          Move to the start/end of line in macro table

 Enter                    Load selected macro d= ata

 ^Enter (opt.)            Load all macro data from bank=

 [Ctrl][Shift] "[","]"= ;    Change macro speed<= /o:p>

 MBoard keys <hold down>  Preview instrument with selected macro = data

 Tab (opt.)               Switch to Arpeggio/Vibrato= Macro Browser window

 Esc                      Leave Instrument Ma= cro Browser window

 

 

 III= /11. ARPEGGiO/ViBRATO MACRO BROWSER KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──

 

 Up,Down,PgUp,PgDown

 Home,End                 Cursor navigation

 [Shift] Left,Right       Move left/right in arpeggio table<= span style=3D'mso-spacerun:yes'>     

 [Shift] PgUp,PgDown      Move page left/right in arpeggio ta= ble │<= /span>

 ^Left,^Right             Move left/right in vibrato table       refer to=

 ^PgUp,^PgDown            Move page left/right in vibra= to table  (*)

 [Shift]{Alt} Space       Toggle arpeggio table selection (**)  

 [Ctrl] {Alt} Space       Toggle vibrato table selection  (**)  

 [Shift] Home,End         Navigate to start/end of arpeggio table

 ^Home,^End               Navigate to start/end of v= ibrato table

 [Ctrl] "[","]"           Change current instrument<= /span>

 [Ctrl][Shift] "[","]"= ;    Change macro speed<= /o:p>

 MBoard keys <hold down>  Preview instrument with selected macro = data

 Enter                    Load selected macro d= ata

 ^Enter (opt.)            Load all macro data from bank=

 [Shift] Esc              Apply table indexes to curr= ent instrument

 Esc                      Leave Arpeggio/Vibr= ato Macro Browser window

 

 (*)  Key combination with Ctrl+S= hift applies action to both tables

 (**) Alt key invokes no arpeggio resp. vibrato table (index value re= set)

 

 

 III/12. DEBUG iNFO WiNDOW KEY REFERENCE<= o:p>

 ── = 472;──────────&= #9472;──────────= ;──────────^= 72;────

 Up,= Down,Left,Right

 Hom= e,End           =       Change current track

 Tab                      Toggle details=

 Backspace                Toggle pattern repeat

 Space                    Enter Debug mode / Pr= oceed step (if possible)

 ^Space                   Exit Debug mode

 [Ctrl] Home,End          Skip to previous/next pattern

 +,-                      Same as above; play pattern from start

 ^Enter                   Play next pattern acco= rding to order

 ^Left                    Rewind current patter= n

 ^Right                   Fast-Forward

 [Alt] 1..9,0             Toggle track channel ON/OFF = (Shift toggles 1X)

 [Alt] S                  Set all OFF except curr= ent track (solo)

 [Alt] R                  Reset flags on all tracks<= /span>

 *   =                      Reverse ON/OFF on all tracks

 Esc                      Return to Pattern E= ditor or Pattern Order

 

 

 III= /13. REMAP iNSTRUMENT WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────

 

 Up,= Down,Left,Right

 Hom= e,End           =       Cursor navigation

 PgU= p,PgDown          &nb= sp;   Move up/down 16 instruments

 Tab=             = ;          Jump to next selection

 [Sh= ift] Tab           &n= bsp;  Jump to previous selection

 MBo= ard keys <hold down>  Preview instrument

 Ent= er           &nb= sp;        Remap

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 III= /14. REARRANGE TRACKS WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────

 

 Up,Down,Left,Right,

 Home,End                  Cursor navigation<= /o:p>

 Tab                       Jump to next selec= tion

 [Shift] Tab               Jump to previous selection=

 ^PgUp,^PgDown             Shift track at cursor up/dow= n in the track list

 [Shift] ^PgUp,^PgDown     Rotate track list from cursor upside= /downside

 Enter                     Rearrange=

 Esc                       Return to Pattern = Editor or Pattern Order

 

 

 III= /15. REPLACE WiNDOW KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;────────

 

 Up,= Down,Left,Right,

 Hom= e,End           =       Cursor navigation

 Tab=             = ;          Jump to next selection

 [Sh= ift] Tab           &n= bsp;  Jump to previous selection

 ^K<= /b>            =            Insert Key-Off in note column

 ^N<= /b>            =            Mark "new" field to clear found item

 ^W                       Swap "to find" and "replace" mask content

 Delete,Backspace         Delete current/previous characte= r

 ^Backspace               Delete "to find"= or "replace" mask content

 [Shift] ^Backspace       Delete content of both masks<= /o:p>

 Ent= er           &nb= sp;        Replace

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;────

 

 Up,= Down,Left,Right       Cursor navigation

 [Alt] <section hotkey><= span lang=3DEN-US style=3D'font-size:10.0pt;font-family:"Courier New";mso-ansi-l= anguage: EN-US'>   Jump to section

 Tab (Enter)          &nbs= p;   Jump to next variable field

 [Sh= ift] Tab           &n= bsp;  Jump to previous variable field

 Spa= ce           &nb= sp;        Select item

 ^Enter                   Setup rows per beat fo= r BPM calculation

 Esc=             = ;          Return to Pattern Editor or Pattern Order

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 Up,= Down,Left,Right,

 PgUp,PgDown,Home,End     Cursor navigation<= /p>

 \ (/ for Linux)          <= /span>Navigate to root directory

 Backspace                Navigate to parent direct= ory

 [Shift] Backspace        Navigate to program home director= y

 MBoard keys <hold down>  Preview instrument (instrument files on= ly)

 Enter                    Choose file under cur= sor / read instrument bank

 Esc                      Leave without choos= ing file

 III/18. MESSAGE BOARD WiNDOW KEY REFEREN= CE

 ─────γ= 2;────────── = 472;──────────&= #9472;──────────= ;────

 

 Up,Down,Left,Right,

 ^PgUp,^PgDown,<= /p>

 Home,End,^Home,^End      Cursor navigation=

 PgUp,PgDown              Move backwards/forwards ove= r text

 ^Left,^Right             Move word left/right

 Backspace,Delete         Delete character left/right=

 ^Backspace,^T            Delete word left/right

 ^K                       Delete characters = to end

 ^Y                       Delete current lin= e

 Tab                      Indent current line=

 ^Space                   Insert row for text at cursor

 [Shift] ^Backspace       Delete row for text at cursor=

 Insert                   Toggle input and overw= rite mode

 Enter                    Wrap line of text

 Esc                      Return to Pattern E= ditor or Pattern Order 

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 Lef= t,Right          &nbs= p;    Move left/right

 Hom= e,End           =       Move to the begin/end

 ^Le= ft,^Right          &n= bsp;  Move word left/right

 Bac= kspace,Delete         Delete character left/right

 ^Ba= ckspace,^T            Delete word left/right

 ^K                       Delete characters = to end

 ^Y<= /b>            =            Delete string

 Ins= ert           &n= bsp;       Toggle input and overwrite mode

 +,-                      Increment/decrement decimal or hexadecimal value

 

 

 III= /20. MiDiBOARD KEY REFERENCE

 ──────&#= 9472;──────────= ──────────γ= 2;───

 

 Use to enter notes while in MBoard mode (if = not already active,
 Shift+Space activates this mode if song is Stopped, or if song is Paused
 with no Trace).
<= /p>

 

 =

 

 δ= 4;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┐<= /span>

 γ= 4; WHiLE TRACKER iS iN MBOARD MODE            &n= bsp;            = ;            &n= bsp;

 ζ= 0;────────── = 472;──────────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────= ───────┤<= /span>

 γ= 4; MBoard key copies note in note field, plays it, and advances song    

 ^= 74; to next row. If used with = Left-Shift key and line marking toggled ON,

  it advances song to next highlighted row.            = ;            &n= bsp;   

  If used with Right-Shift key, it makes a fixed note.           &nbs= p;     

  Space plays row and advances song by one row.            = ;            

  ` inserts Key-Off, releases playing note and advances to next row.   

 └───────= ;──────────^= 72;──────────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9496;

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I= V. iNSTRUMENTS          &nbs= p;

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 ──────&#= 9472;────

 

 Indicates how fast the sound volume goes to maximum.

 1=3Dslow, 15=3Dfast. 0 means no attack phase= .

 

 

 ──────&#= 9472;───

 

 Indicates how fast the sound goes from maxim= um level to sustain level.

 1=3Dslow, 15=3Dfast. 0 means no decay phase.=

 

 

 ──────&#= 9472;──────

 

 Indicates the sustain level.

 1=3Dloudest, 15=3Dsoftest. 0 means no sustai= n phase.

 

 

 ──────&#= 9472;─────

 

 Indicates how fast the sound goes from susta= in level to zero level.

 1=3Dslow, 15=3Dfast. 0 means no release phas= e.

 

 

 ──────&#= 9472;─────

 

 Ranges from 0 to 63, indicates the attenuati= on according to the

 envelope generator output. In Additive synthesis, varying

 the output level of any operator varies the volume of its corresponding

 channel. In FM synthesis, varying the output level of carrier varies

 the volume of its corresponding channel, but varying the output of

 the modulator will change the frequency spec= trum produced by the carrier.

 

 

 ──────&#= 9472;────────

 

 Specifies the output waveform type.

 The first is closest to pure sine wave, the = last is most distorted.

 

 

[0] SiNE

 

3Dimage001

 

[4] SiNE / EPO

 

 

 3Dimage003

 

[1] HALF-SiNE

3Dimage006

 

[5] ABS-SiNE / EPO=

 

3Dimage005

 

[2] ABS-SiNE

 

3Dimage004

 

[6] SQUARE

 

3Dimage007

 

 [3] PULSE-SiNE

 

  3Dimage008

 

[7] DERiVED SQUARE=

 

3Dimage009

 

 

 

 ──────&#= 9472;──────────= ──────

 

 When set, makes the sound softer at higher frequencies.

 With musical instruments, volume decreases as pitch increases.

 Level key scaling values are used to simulate this effect.

 If any (not zero), the diminishing factor ca= n be 1.5 dB/octave,

 3.0 dB/octave, or 6.0 dB/octave.<= /span>

 

 

 ──────&#= 9472;

 

 Gives you ability of controlling output, goi= ng to left or right channel,

 standing in the middle respectively.

 The parameter corresponds either with carrier and modulator, therefore

 it is listed only once (within the carrier slot).

 

 

 ──────&#= 9472;──

 

 This is not a hardware parameter.=

 Ranges from -127 to 127, it indicates the nu= mber of frequency units

 shifted up or down for any note playing with= the corresponding instrument.

 The parameter corresponds either with carrier and modulator, therefore

 it is listed only once (within the carrier slot).

 

 

 ──────&#= 9472;──────────=

 

 Ranges from 0 to 7, it indicates the modulat= ion depth

 for the modulator slot FM feedback.

 

 ┌────────= ;────╥─────_= 16;─────┬────&#= 9472;┬─────┬───= ──┬─────┬─γ= 2;───┬─────┐

  FEEDBACK   &#= 9553; [0]  [1]  [2]  [3] <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> [4]  [5]  [6] <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> [7]

 ├────────= ;────╫─────_= 32;─────┼────&#= 9472;┼─────┼───= ──┼─────┼─γ= 2;───┼─────┤

  MODULATiON &#= 9553;  0  π/16 &#= 9474; π/8 π/4 π/2   π  │<= /span> 2π  4π 

 └────────= ;────╨─────_= 24;─────┴────&#= 9472;┴─────┴───= ──┴─────┴─γ= 2;───┴─────┘

 

 The parameter corresponds either with carrier and modulator, therefore

 it is listed only once (within the carrier slot).

 

 

 CON= NECTiON TYPE

 ──────&#= 9472;────────

 

 Frequency modulation means that the modulator slot modulates the carrier.

 Additive synthesis means that both slots pro= duce sound on their own.

 

 

 [FM] FREQUENCY MODULATiON

 

         ┌───────── = 472;──┐

         │           = │

         │    ╔════╗ = ; │         ╔════╗

  P1 ───(+)───║ MO ╟─= ─┴───(+)───║ CA ╟──> OUT

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝=

           &nb= sp;            =    │

           &nb= sp;            =    │

           &nb= sp;            =    P2

 

 

 

 [ADDiTiVE SYNTHESiS] AM

 

         ┌───────── = 472;──┐

         │           = │

         │    ╔════╗ = ; │

  P1 ───(+)───║ MO ╟─= ─┴────┐

           &nb= sp;  ╚════╝     &= nbsp; │

           &nb= sp;            =    │

           &nb= sp;            =   (+)──> OUT

           &nb= sp;            =    │

              &= #9556;════╗     &nbs= p; │

  P2 ─────────║= CA ╟───────┘

           &nb= sp;  ╚════╝

 

 

 

 

 The parameter corresponds either with carrier and modulator, therefore

 it is listed only once (within the carrier slot).

 This parameter is also very important when making 4-op instruments,

 because the combination of two instrument connections specifies

 the connection of the 4-op instrument as sho= wn below:

 

 ┌────────= ;──╥────┬──^= 72;─┬────┬───&#= 9472;┐

  SLOT      M1 C1 │<= /span> M2 C2

 ├────────= ;──╫────┼──^= 72;─┼────┼───&#= 9472;┤

  OPERATOR ║<= /span> 1   2  │<= /span> 3   4 

 └────────= ;──╨────┴──^= 72;─┴────┴───&#= 9472;┘

 

 

 

[FM/FM]

 

         ┌───────── = 472;──┐

         │           = │

         │    ╔════╗ = ; │         ╔════╗     &= nbsp;   ╔════╗     &= nbsp;   ╔════╗

  P1 ───(+)───║ M1 ╟─= ─┴───(+)───║ C1 ╟───(+)───║ M2 ╟= ───(+)───║ C2 ╟──> OUT

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝ = ;   │    ╚════╝ = ;   │    ╚════╝=

           &nb= sp;            =    │           =    │           =    │

           &nb= sp;            =    │          =     │          =     │

           &nb= sp;            =    P2             P3            = ; P4

 

 

 

[FM/AM] (*)

 

         ┌───────── = 472;──┐

         │           = │

         │    ╔════╗ = ; │         ╔════╗

  P1 ───(+)───║ M1 ╟─= ─┴───(+)───║ C1 ╟────┐

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝ = ;   │

           &nb= sp;            =    │           =    │

           &nb= sp;            =    │          =     │

           &nb= sp;            =    P2            (+)&= #9472;─> OUT

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;  ╔════╗     &= nbsp;      ╔════╗    │=

  P3 ─────────║= M2 ╟──────(+)──γ= 2;║ C2 ╟────┘

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝=

           &nb= sp;            =    │

           &nb= sp;            =    │

           &nb= sp;            =    P4

 

 

 

[AM/FM] (*)

 

         ┌───────── = 472;──┐

         │           = │

         │    ╔════╗ = ; │

  P1 ───(+)───║ M1 ╟─= ─┴────────γ= 2;────────── = 472;──────────&= #9472;───┐

           &nb= sp;  ╚════╝     &= nbsp;           &nbs= p;            &= nbsp;      │

           &nb= sp;            =             &nb= sp;            =         │

           &nb= sp;            =             &nb= sp;            =         │

           &nb= sp;            =             &nb= sp;            =         │

           &nb= sp;  ╔════╗     &= nbsp;      ╔════╗     &= nbsp;   ╔════╗    │­

  P2 ─────────║= C1 ╟──────(+)──γ= 2;║ M2 ╟───(+)───║ C2 ╟= ───(+)──> OUT

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝ = ;   │    ╚════╝=

                        &= nbsp;  │        &nb= sp;     │

           &nb= sp;            =    │           =    │

           &nb= sp;            =    P3            = ; P4

 

 

 

[AM/AM]

 

         ┌───────── = 472;──┐

         │           = │

         │    ╔════╗ = ; │

  P1 ───(+)───║ M1 ╟─= ─┴────────γ= 2;────────── = 488;

           &nb= sp;  ╚════╝     &= nbsp;           &nbs= p;    │

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;            =             &nb= sp;     │

           &nb= sp;  ╔════╗     &= nbsp;      ╔════╗    │­

  P2 ─────────║= C1 ╟──────(+)──γ= 2;║ M2 ╟───(+)──> OUT

           &nb= sp;  ╚════╝     &= nbsp; │    ╚════╝ = ;   │

           &nb= sp;            =    │           =    │

           &nb= sp;            =    │           =    │

           &nb= sp;            =    P3            = ; │

           &nb= sp;  ╔════╗     &= nbsp;           &nbs= p;    │

  P4 ─────────║= C2 ╟─────────&= #9472;──────────= ;──┘

           &nb= sp;  ╚════╝

 

 

 

 (*) REMA= RK ABOUT 4OP CONNECTiONS FM/AM AND AM/FM

 Please note, that since order of 4OP channels (hardware-wise) is 2) and 1),

 these two instrument connections are swapped.',

 The preview diagrams in the Instrument Editor window show actual order,

 but here this information is kept in conformity with the official

 Yamaha YMF262 data specification to pr= event further confusion.

 

 

  

 TRE= MOLO (AMPLiTUDE MODULATiON)

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 When set, turns tremolo (volume vibrato) ON = for the corresponding slot.

 The repetition rate is 3.7Hz, the depth is optional (1dB/4.8dB).

 

 

 ViB= RATO

 ──────&#= 9472;

 

 When set, turns frequency vibrato ON for the corresponding slot.

 The repetition rate is 6.1Hz, the depth is optional (7%/14%).

 

 

 KEY= SCALE RATE (KSR)

 ──────&#= 9472;──────────= ───

 

 When set, makes the sound shorter at higher frequencies.

 With normal musical instruments, the attack = and decay rate becomes faster

 as the pitch increases. The key scale rate controls simulation of

 this effect. An offset (rof) is added to the individual attack, decay,

 and release rates depending on the following formula:

 

 actual_rate =3D (rate * 4) + rof<= /span>

 

 The "rof" values for corresponding "rate" value and KSR state are shown

 in the following table:

 

 ┌───────= ;─╥───┬───┬^= 72;──┬───┬───&#= 9516;───┬───┬──= ─┬───┬───┬γ= 2;──┬───┬─── = 516;───┬───┬──&= #9472;┐

  %rate% &#= 9553; 0 = │ 1 = │ 2 = │ 3 = │ 4 = │ 5 = │ 6 = │ 7 = │ 8 = │ 9 = │ A = │ B = │ C = │ D = │ E = │ F = │

 ╞════════= ;╬═══╪═══╪═_= 52;═╪═══╪═══╪&#= 9552;══╪═══╪═══= ╪═══╪═══╪═λ= 2;═╪═══╪═══╪ = 552;══╪═══╪═══&= #9569;

  [OFF]  &#= 9553; 0 = │ 0 = │ 0 = │ 0 = │ 1 = │ 1 = │ 1 = │ 1 = │ 2 = │ 2 = │ 2 = │ 2 = │ 3 = │ 3 = │ 3 = │ 3 = │

 ├────────= ;╫───┼───┼─^= 72;─┼───┼───┼&#= 9472;──┼───┼───= ┼───┼───┼─γ= 2;─┼───┼───┼ = 472;──┼───┼───&= #9508;

  [ON]   &#= 9553; 0 = │ 1 = │ 2 = │ 3 = │ 4 = │ 5 = │ 6 = │ 7 = │ 8 = │ 9 = │ A = │ B = │ C = │ D = │ E = │ F = │

 └────────= ;╨───┴───┴─^= 72;─┴───┴───┴&#= 9472;──┴───┴───= ┴───┴───┴─γ= 2;─┴───┴───┴ = 472;──┴───┴───&= #9496;

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 When set, the sustain level of the voice is maintained until released.

 When clear, the sound begins to decay immediately after hitting

 the sustain phase.

 

 

[OFF]

3Dimage010

 

[ON]

3Dimage011

 

 

 

 ──────&#= 9472;──────────= ────────<= /p>

 

 Sets the multiplier for the frequency data specified by block and

 F-number. This multiplier is applied to the = FM carrier or modulation

 frequencies. The multiplication factor and corresonding harmonic types are

 shown in the following table:

 

 ┌───────= ;┬─────┬───^= 72;──────────&#= 9472;──────────= ──────────γ= 2;┐

  MULT. &#= 9474;  HARMONiC    &= nbsp;           &nbs= p;          &#= 9474;

 ╞═══════╪= ;═════╪════_= 52;══════════&#= 9552;══════════= ══════════μ= 9;

   [0]  0.5 1 octave below           &nbs= p;         &#= 9474;

   [1]    1  at the voice's specified frequency

   [2]    2  1 octave above           &nbs= p;         &#= 9474;

   [3]    3  1 octave and a 5th above           │<= /span>

   [4]    4  2 octaves above           &nbs= p;        &#= 9474;

   [5]    5  2 octaves and= a Major 3rd above   

   [6]    6  2 octaves and= a 5th above          │<= /span>

   [7]    7  2 octaves and= a Minor 7th above   

   [8]    8  3 octaves above           &nbs= p;        &#= 9474;

   [9]    9  3 octaves and= a Major 2nd above   

   [A]  10  3 octaves and a Major 3rd above   

   [B]  10               ...                    │<= /span>

   [C]  12  3 octaves and a 5th above&nb= sp;         &#= 9474;

   [D]  12               ...                    │<= /span>

   [E]  15  3 octaves and a Major 7th above   

   [F]  15               ...                    │<= /span>

 └───────= ;┴─────┴───^= 72;──────────&#= 9472;──────────= ──────────γ= 2;┘

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

V. EFFECTS           &n= bsp;    

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

ARPEGGiO

 ──────&#= 9472;───────

 

 This command causes the note to quickly cycle through three notes:

 the note playing, a note 'x' halftones above= ,

 and a note 'y' halftones above.

 This causes an effect similar to old C64 cho= rds.

 Note that the song speed has to be greater or equal to three

 in order to perform arpeggio effect complete= ly.

 

 

FREQUENCY SLiDE UP

 ──────&#= 9472;──────────= ───────

 

 This command slides the frequency up (pitch bend).

 Parameter 'xx' gives speed of slide.

 

 

FREQUENCY SLiDE DOWN

 ──────&#= 9472;──────────= ─────────<= /span>

 

 This command slides the frequency down (pitch bend).

 Parameter 'xx' gives speed of slide.

 

 

TONE PORTAMENTO

 ──────&#= 9472;──────────= ────

 

 This command is used together with a note and will slide to its frequency.

 Parameter 'xx' gives speed of slide.

 If you specify 'xx' as '00' then the previous value will be used.

 

 

ViBRATO

 ──────&#= 9472;──────

 

 This command causes the frequency to oscilla= te with depth 'y' at speed 'x'.

 If you specify 'xy' as '00' then the previous value will be used.

 

 

TONE PORTAMENTO WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;

 

 This command executes both Tone portamento a= nd Volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

ViBRATO WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;───

 

 This command executes both Vibrato and Volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FiNE FREQUENCY SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command slides the frequency up (pitch bend) once per row.

 Parameter 'xx' gives speed of slide.

 

 

FiNE FREQUENCY SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;───

 

 This command slides the frequency down (pitch bend) once per row.

 Parameter 'xx' gives speed of slide.

 

 

SET MODULATOR VOLUME

 ──────&#= 9472;──────────= ─────────<= /span>

 

 This command sets the volume of modulator sl= ot.

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

VOLUME SLiDE

 ──────&#= 9472;──────────= ─

 

 This command fades the volume up or down at = the given speed.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'x' then 'y' is not used, and vice versa.

 

 

PATTERN JUMP

 ──────&#= 9472;──────────= ─

 

 This command causes the song to jump to order 'xx'.

 This is often used to create looping songs.<= o:p>

 If two 'Bxx' commands are given, then the co= mmand in the

 higher track will take effect.

 

 

SET iNSTRUMENT VOLUME

 ──────&#= 9472;──────────= ──────────=

 

 This command sets the absolute volume of the instrument.

 It is equal to Ixx command when instrument u= ses FM connection,

 otherwise both carrier and modulator volume = is updated.

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

PATTERN BREAK

 ──────&#= 9472;──────────= ──

 

 This command signifies the end of the current pattern, and also that

 the next pattern should be played from row '= xx'.

 If two 'Dxx' commands are given, then the command in the

 higher track will take effect.

 

 

SET TEMPO

 ──────&#= 9472;────────

 

 This command changes the song tempo (also kn= own as BPM).

 Parameter 'xx' gives hexadecimal value of refresh rate in Hz.

 If two 'Exx' commands are given, then the command in the

 higher track will take effect.

 

 

SET SPEED

 ──────&#= 9472;────────

 

 This command changes the song speed.

 Parameter 'xx' gives how many frames to wait before advancing row.

 If two 'Fxx' commands are given, then the command in the

 higher track will take effect.

 

 

TONE PORTAMENTO WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────

 

 This command executes both Tone portamento a= nd Fine volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

ViBRATO WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────

 

 This command executes both Vibrato and Fine volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

SET CARRiER VOLUME

 ──────&#= 9472;──────────= ───────

 

 This command sets the volume of carrier slot= .

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

SET WAVEFORM

 ──────&#= 9472;──────────= ─

 

 This command changes the waveform of carrier= or modulator slot.

 Parameter 'x' gives carrier and 'y' modulator waveform type as following:

 

   '0'-'7' means type of waveform,<= /o:p>

   'F' means "no change".=

 

 For more information see chapter IV, part "Waveform select".

 

 

FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────

 

 This command fades the volume up or down at = the given speed,

 once per row.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'x' then 'y' is not used, and vice versa.

 

 

RETRiG NOTE

 ──────&#= 9472;──────────=

 

 This command retriggs the note after 'xx' frames.

 If no note is specified, last given is used.=

 The lower is the interval, the faster is the retrigger.

 

 

TREMOLO

 ──────&#= 9472;──────

 

 This command causes the volume to oscillate = with depth 'y' at speed 'x'.

 If you specify 'xy' as '00' then the previous value will be used.

 Tremolo acts like vibrato, but changing the = volume instead of the pitch.

 

 

TREMOR

 ──────&#= 9472;─────

 

 This command causes the volume to remain nor= mal for 'x' frames,

 then fades the volume to zero for 'y' frames= .

 

 

ARPEGGiO WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 This command executes both Arpeggio and Volu= me slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

ARPEGGiO WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;─────────

 

 This command executes both Arpeggio and Fine volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

MULTi RETRiG NOTE

 ──────&#= 9472;──────────= ──────

 

 This command retriggs the note after 'x' fra= mes with specified

 volume change. Parameter 'y' gives type of volume change:

 

   '0' is None,    '8' is Unused,

   '1' is -1,    &nb= sp; '9' is +1,

   '2' is -2,    &nb= sp; 'a' is +2,

   '3' is -4,    &nb= sp; 'b' is +4,

   '4' is -8,    &nb= sp; 'c' is +8,

   '5' is -16,     '= d' is +16,

   '6' is *2/3,    'e' is *3/2,

   '7' is *1/2,    'f' is= *2.

 

 If no note is specified, last given is used.=

 The lower is the interval, the faster is the retrigger.

 

 

FREQUENCY SLiDE UP WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;───

 

 This command executes both Frequency slide up and Volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FREQUENCY SLiDE DOWN WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;─────

 

 This command executes both Frequency slide d= own and Volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FiNE FREQUENCY SLiDE UP WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;────────

 

 This command executes both Fine frequency sl= ide up and Volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FiNE FREQUENCY SLiDE DOWN WiTH VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────<= o:p>

 

 This command executes both Fine frequency sl= ide down and Volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FREQUENCY SLiDE UP WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;────────

 

 This command executes both Frequency slide up and Fine volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FREQUENCY SLiDE DOWN WiTH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────<= o:p>

 

 This command executes both Frequency slide d= own and Fine volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FiNE FREQUENCY SLiDE UP WITH FiNE VOLUME SLiDE

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──

 

 This command executes both Fine frequency sl= ide up and Fine volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

FiNE FREQUENCY SLiDE DOWN WiTH FiNE VOLUME SLiDE<= /p>

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;────

 

 This command executes both Fine frequency sl= ide down and Fine volume slide.

 Parameter 'xy' gives speed of volume slide:<= o:p>

 

   'x' is speed of slide up,<= /span>

   'y' is speed of slide down.

 

 If you specify 'xy' as '00' then the previous value will be used.

 

 

SET TREMOLO DEPTH

 ──────&#= 9472;──────────= ──────

 

 This command changes the Tremolo depth of al= l 36 operators.

 Parameter 'x' gives depth:=

 

   '0' is 1dB,

   '1' is 4.8dB.

 

 

SET ViBRATO DEPTH

 ──────&#= 9472;──────────= ──────

 

 This command changes the Vibrato depth of al= l 36 operators.

 Parameter 'x' gives depth:=

 

   '0' is 7%,

   '1' is 14%.

 

 

SET MODULATOR'S ATTACK RATE

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Attack rate".

 

 

SET MODULATOR'S DECAY RATE

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Decay rate".

 

 

SET MODULATOR'S SUSTAiN LEVEL

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Sustain level".

 

 

SET MODULATOR'S RELEASE RATE

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Release rate".

 

 

SET CARRiER'S ATTACK RATE

 ──────&#= 9472;──────────= ──────────γ= 2;───

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Attack rate".

 

 

SET CARRiER'S DECAY RATE

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Decay rate".

 

 

SET CARRiER'S SUSTAiN LEVEL

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Sustain level".

 

 

SET CARRiER'S RELEASE RATE

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 ADSR command. Parameter 'x' gives the value.=

 For more information see chapter IV, part "Release rate".

 

 

SET FEEDBACK STRENGTH

 ──────&#= 9472;──────────= ──────────=

 

 This command changes the Feedback strength of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Feedback strength".

 

 

SET PANNiNG POSiTiON

 ──────&#= 9472;──────────= ─────────<= /span>

 

 This command changes the panning of current instrument.

 Parameter 'x' gives position:

 

   '0' is center,

   '1' is left,

   '2' is right.

 

 

PATTERN LOOP

 ──────&#= 9472;──────────= ─

 

 Syntax: ZC0 - Set loopback point<= /span>

         Z= Cx - Loop x times.

 

 This pattern space-saving feature will cause= the pattern

 to be looped 'x' times back to the last ZC0 command.

 Note that you can only loop within the patte= rn, and each track

 has its own loopback information, so you are supposed to have

 corresponding ZC0 and ZCx commands in the sa= me track in order to operate.

 If ZCx commands are put in both effect colum= ns, only the one in first

 column will operate.

 

 

RECURSiVE PATTERN LOOP

 ──────&#= 9472;──────────= ──────────γ= 2;

 

 Syntax: ZD0 - Set loopback point<= /span>

         Z= Dx - Loop x times.

 

 This command is recursive variant of ZCx eff= ect command.

 It means that when such kind of loop is loca= ted inside other "parent" loop,

 it is proceeded any time it is passed by this loop.

 Note that using ZC0 instead of ZD0 command h= as the same effect.

 Please keep in mind that ZDx command should = not be used in combination

 with ZCx command in other effect column, otherwise it will cause an

 endless loop.

 

 

 [ZE0/ZE1] TOGGLE MACRO KEY-OFF LO= OP

 ─&#= 9472;──────────= ──────────γ= 2;────────── = 472;─

 

 This comm= and temporarily turns on-or-off looping

 of Key-Off phase in macro-table for current instrument.

 Parameter= 'x' gives the state to toggle:

 

   '0' is = OFF,

   '1' is = ON.

 

 Note that "temporarily" means that the change is valid until there will be<= o:p>

 set diffe= rent instrument than is the current one, for which this command

 is to be = used.

 

 

 [ZE2/ZE3] TOGGLE RESTARTiNG ENVOL= OPE WiTH TONE PORTAMENTO

 ─&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──────────= ;──

 This comm= and turns on-or-off restarting of ADSR envelope for current track.

 It means,= that the note key will be retriggered for every row with non-empty

 input in = the note column (rows where note culumn is empty are not affected).<= /span>

 Parameter= 'x' gives the state to toggle:

 

   '2' is = OFF,

   '3' is = ON.

 

 

 [ZE4] PERFORM RESTART ENVELOPE

 ─&#= 9472;──────────= ──────────γ= 2;───────

 This comm= and restarts ADSR envelope for current instrument.

 

 

 [ZE5/ZE6] TOGGLE 4OP TRACK VOLUME= LOCK

 ─&#= 9472;──────────= ──────────γ= 2;────────── = 472;────

 This comm= and turns on-or-off 4OP Track Volume Lock.

 If 4OP Tr= ack Volume Lock is set, some of the volume effect commands

 will work= in 4OP mode instead of default (2OP) mode. This means,

 that volu= me attenuation is calculated according 4OP connection

 of the 2 = used instruments in track 2) and 1), and you don't have to

 manage carrier/modulator output level to get desired volume level

 during playback.

 Parameter= 'x' gives the state to toggle:

 

   '5' is = OFF,

   '6' is = ON.

 

 Here is a complete list of commands that are affected by this lock:=

 5xy/6xy, = Axy, Cxx, Gxy/Hxy, Kxy, Mxy, Rxy/Sxy, Txy/Uxy,

 Vxy/Wxy, Xxy/Yxy, ^xy, %xx

 

 Please no= te that when the 4OP Track Volume Lock is set for particular=

 4OP track= s, setting of 'Volume Scaling' is ignored (it is mandatory ON).

 

 

PERFORM BPM SLiDE USiNG >xx AND <xx COMMANDS

───────&= #9472;──────────= ;──────────^= 72;──────────&#= 9472;──────────=

 

 As descri= ption invokes, this command is intended to be used together

 with >= xx and <xx effect commands.

 It will c= ause the playback speed shift up/down by certain of Hz,

 depending= on the speed of slide.

 Parameter= 'xx' gives speed of slide.

 

 

RELEASE SUSTAiNiNG SOUND

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 This command causes the track volume to fade down immediately.

 Note that it nulls current Attack rate, Decay rate,

 Sustain level, and Release rate.<= /span>

 

 

RESET iNSTRUMENT VOLUME

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command resets back to modulator and ca= rrier volume

 defined in modulator and carrier slot of cur= rent instrument.

 

 

TOGGLE TRACK VOLUME LOCK

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 This comm= and turns on-or-off the Volume Lock for current track.

 It means,= that the track volume will remain constant for entire track.

 This cons= tant is updated when using volume effect commands,

 or when u= sing new instrument.

 Parameter= 'x' gives the state to toggle:

 

   '2' is = ON,

   '3' is = OFF.

 

 

TOGGLE VOLUME PEAK LOCK

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 This comm= and turns on-or-off the Volume Peak Lock for current track.

 It means,= that when performing a Volume Slide, the upper limit of track<= /p>

 volume wi= ll remain lower or equal to volume level specified in carrier

 and modul= ator slot of corresponding instrument.

 Note that= lock affects Volume Slide and Fine Volume Slide effects

 as well as Tremolo, Tremor and Multi Retrig Note effects.

 Parameter= 'x' gives the state of lock to toggle:

 

   '4' is = ON,

   '5' is = OFF.

 

 

TOGGLE MODULATOR VOLUME SLiDES

 ──────&#= 9472;──────────= ──────────γ= 2;────────

 

 This command toggles volume slide for modula= tor slot only. If used together

 with ZF7 effect command, it toggles volume s= lide for both slots.

 Note that command will affect Volume Slide a= nd Fine Volume Slide effects

 as well as Tremolo, Tremor and Multi Retrig = Note effects.

 

 

TOGGLE CARRiER VOLUME SLiDES

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 This command toggles volume slide for carrier slot only. If used together

 with ZF6 effect command, it toggles volume s= lide for both slots.

 Note that command will affect Volume Slide a= nd Fine Volume Slide effects

 as well as Tremolo, Tremor and Multi Retrig = Note effects.

 

 

TOGGLE DEFAULT VOLUME SLiDES

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 This command toggles default volume slides.<= o:p>

 It means, that replay routine will distingui= sh which slot (carrier or both)

 to proceed from connection type (see chapter= IV, part "Connection type").

 Note that command will affect Volume Slide a= nd Fine Volume Slide effects

 as well as Tremolo, Tremor and Multi Retrig = Note effects.

 

 

TOGGLE TRACK PANNiNG LOCK

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 This command enables the Panning Lock.<= /o:p>

 It means, that current panning position is forced for entire track,

 and can be updated only by ZBx effect comman= d.

 This comm= and turns on-or-off the Panning Lock for current track.

 It means,= that current panning position is forced for entire track,

 and can be updated only by ZBx effect command.

 Parameter= 'x' gives the state of lock to toggle:

 

   '9' is = ON,

   'A' is = OFF.

 

 

ViBRATO OFF

 ──────&#= 9472;──────────=

 

 This command marks the end of Vibrato effect= .

 It will restore the last frequency before Vibrato effect.

 

 

TREMOLO OFF

 ──────&#= 9472;──────────=

 

 This command marks the end of Tremolo effect= .

 It will restore the last volume before Tremo= lo effect.

 

 

FORCE FiNE ViBRATO (FORCE FiNE GLOBAL FREQ. SLiDE)

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──────

 

 This command has to be used together with 4x= y, 6xy or Hxy (>xx, <xx)

 effect command. It will cause the Vibrato (Global Freq. Slide Up/Down)

 effect to= be performed once per row instead of every frame.

 Note that the switch is reset at the end of effect.

 

FORCE FiNE TREMOLO (FORCE EXTRA FiNE GLOBAL FREQ. SLiDE)=

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;──────────= ;──

 

 This command has to be used together with Mxy (>xx, <xx)

 effect command. It will cause the Tremolo (Global Freq. Slide Up/Down)

 effect to= be performed once per row (once per every four frames).

 Note that the switch is reset at the end of effect.

 

 

FORCE NO RESTART FOR MACRO TABLES

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;

 

 1) This command can be used together with !xx (@xx) effect command.

    It will cause that the arpeggio (vibrato) table is swapped

    without restarting position. It means that the current position

    is maintained as the starting p= oint in new table.

 2) This command can be used while new note is triggered and the instrument

    that is played is using FM-regi= ster macro (arpeggio macro, vibrato

    macro resp.) In such case the m= acro is not restarted, which means that

    the current position in FM-regi= ster (arpeggio, vibrato resp.) macro

    table is maintained.=

 

 

SET CONNECTiON TYPE

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command sets the connection type of cur= rent instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Connection type".

 

 

SET MODULATOR'S MULTiPLiER

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 This command sets the modulator's multiplier= of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Frequency data multiplier".

 

 

SET MODULATOR'S KSL

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command sets the modulator's scaling le= vel of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Key scaling level".

 

 

SET MODULATOR'S TREMOLO

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command sets the modulator's tremolo on= -or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Tremolo (Amplitude modulation)".

 

 

SET MODULATOR'S ViBRATO

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command sets the modulator's vibrato on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Vibrato)".

 

 

SET MODULATOR'S KSR

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command sets the modulator's KSR on-or-= off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Key scale rate".

 

 

SET MODULATOR'S SUSTAiN

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command sets the modulator's sustain on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Sustain (Envelope generator)".

 

 

SET CARRiER'S MULTiPLiER

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 This command sets the carrier's multiplier of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Frequency data multiplier".

 

 

SET CARRiER'S KSL

 ──────&#= 9472;──────────= ──────

 

 This command sets the carrier's scaling leve= l of current instrument.

 Parameter 'x' gives the value.

 For more information see chapter IV, part "Key scaling level".

 

 

SET CARRiER'S TREMOLO

 ──────&#= 9472;──────────= ──────────=

 

 This command sets the carrier's tremolo on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Tremolo (Amplitude modulation)".

 

 

SET CARRiER'S ViBRATO

 ──────&#= 9472;──────────= ──────────=

 

 This command sets the carrier's vibrato on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Vibrato)".

 

 

SET CARRiER'S KSR

 ──────&#= 9472;──────────= ──────

 

 This command sets the carrier's KSR on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Key scale rate".

 

 

SET CARRiER'S SUSTAiN

 ──────&#= 9472;──────────= ──────────=

 

 This command sets the carrier's sustain on-or-off for current instrument.

 Parameter 'x' gives the state:

 

   '0' is OFF,

   '1' is ON.

 

 For more information see chapter IV, part "Sustain (Envelope generator)".

 

 

PATTERN DELAY (FRAMES)

 ──────&#= 9472;──────────= ──────────γ= 2;

 

 This command will delay the pattern 'x' fram= es.

 If two '&0x' commands are given, then the command in the

 higher track will take effect.

 

 

PATTERN DELAY (ROWS)

 ──────&#= 9472;──────────= ─────────<= /span>

 

 This command will cause a pause on the row f= or effectively 'x' rows longer.

 If two '&1x' commands are given, then the command in the

 higher track will take effect.

 

 

NOTE DELAY

 ──────&#= 9472;─────────

 

 This command will delay the note 'x' frames.=

 

 

NOTE CUT

 ──────&#= 9472;───────

 

 This command cuts the note (Key-Off will be performed) after 'x' frames.

 

 

FiNE-TUNE UP

 ──────&#= 9472;──────────= ─

 

 This command fine-tunes frequency up.

 If used together with a note, it overrides t= he default note frequency

 before the note is outputted (acts like fine-tune parameter

 included in instrument data).

 Parameter 'x' gives frequency shift.

 

 

FiNE-TUNE DOWN

 ──────&#= 9472;──────────= ───

 

 This command fine-tunes frequency down as st= ated above.

 

 

GLOBAL VOLUME SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;

 

 This command fades the global volume up at t= he given speed.

 Parameter 'x' gives speed of slide.

 

 

GLOBAL VOLUME SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;──

 

 This command fades the global volume down at= the given speed.

 Parameter 'x' gives speed of slide.

 

 

FiNE GLOBAL VOLUME SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;─────

 

 This command fades the global volume up at t= he given speed,

 once per row.

 Parameter 'x' gives speed of slide.

 

 

FiNE GLOBAL VOLUME SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 This command fades the global volume down at= the given speed,

 once per row.

 Parameter 'x' gives speed of slide.

 

 

EXTRA FiNE GLOBAL VOLUME SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;

 

 This command fades the global volume up at t= he given speed,

 once every four frames.

 Parameter 'x' gives speed of slide.

 

 

EXTRA FiNE GLOBAL VOLUME SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──

 

 This command fades the global volume down as stated above.

 

 

EXTRA FiNE VOLUME SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;────

 

 This command fades the volume up at the given speed,

 once every four frames.

 It means that you can do four times more accurate slide effects.

 Parameter 'x' gives speed of slide.

 

 

EXTRA FiNE VOLUME SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;──────

 

 This command fades the volume down as stated above.

 

 

EXTRA FiNE FREQUENCY SLiDE UP

 ──────&#= 9472;──────────= ──────────γ= 2;───────

 

 This command slides frequency up (pitch bend= ), once every four frames.

 It means that you can do four times more accurate slide effects.

 Parameter 'x' gives speed of slide.

 

 

EXTRA FiNE FREQUENCY SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;─────────

 

 This command slides frequency down as stated above.

 

 

EXTRA FiNE ARPEGGiO

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command is a variant of 0xy (Arpeggio) effect command.

 It executes the arpeggio once every four fra= mes.

 It means that you can do four times more accurate arpeggio effects.

 Note that the song speed doesn't have to be greater or equal to three

 as it is in case of normal arpeggio.

 

 

EXTRA FiNE ViBRATO

 ──────&#= 9472;──────────= ───────

 

 This command is a variant of 4xy (Vibrato) effect command.

 It executes the vibrato once every four fram= es.

 It means that you can do four times more accurate vibrato effects.

 

 

EXTRA FiNE TREMOLO

 ──────&#= 9472;──────────= ───────

 This command is a variant of Mxy (Tremolo) effect command.

 It executes the tremolo once every four fram= es.

 It means that you can do four times more accurate tremolo effects.

 

 

SWAP ARPEGGiO TABLE

 ──────&#= 9472;──────────= ────────<= /p>

 

 This command temporarily swaps the arpeggio table for current instrument.

 Parameter 'xx' gives number of new table.

 Note that the number of arpeggio table in instrument macro-table

 remains intact, and "temporarily" means that the change is valid until

 there is another note or instrument set.

 

 

SWAP ViBRATO TABLE

 ──────&#= 9472;──────────= ───────

 

 This command temporarily swaps the vibrato t= able for current instrument.

 Parameter 'xx' gives number of new table.

 Note that the number of vibrato table in instrument macro-table

 remains intact, and "temporarily" means that the change is valid until

 there is another note or instrument set.

 

 

FORCE iNSTRUMENT VOLUME

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command is a variant of Cxx (Set Instru= ment volume) effect command.

 The difference is in modulator's role when affecting volume, because

 it scales the modulator volume according to = 'xx' value, no matter what is

 the connection type of the instrument.<= /o:p>

 Note that the carrier volume is set as usual= .

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

SET GLOBAL VOLUME

 ──────&#= 9472;──────────= ──────

 

 This command sets the global volume of song.=

 Value of 'xx' ranges from 0 to 3F (softest -= > loudest).

 

 

GLOBAL FREQ. SLiDE UP

 ──────&#= 9472;──────────= ──────────=

 

 This command slides the frequency up (pitch bend) in all tracks

 from curr= ent to last, if it’s not overridden by using another

 '<xx' = or '>xx' in second effect column or one of succeeding tracks.

 Parameter 'xx' gives speed of slide.

 

 Note that= you can also use Fine or Extra Fine variant of this command

 by putting command switch 'ZFD' or 'ZFE' into second effect column.<= /p>

GLOBAL FREQ. SLiDE DOWN

 ──────&#= 9472;──────────= ──────────γ= 2;─

 

 This command slides frequency down as stated above.

SET CUSTOM SPEED TABLE

 ──────&#= 9472;──────────= ──────────γ= 2;

 This comm= and sets custom speed table for Vibrato/Tremolo effect,

 which is generated according given parameter 'xx':
 

   '00' =     Reset default speed table
   '01-FF'  Calculate custom speed table with param= eters
            table size, maximum va= lue and processing speed factor

           ┌───= ─────────┬γ= 2;─────┬──── = 472;───┬──────&= #9472;─┐
           PARAMETER  SiZE MAX.   FACTOR
           ╞═══&#= 9552;════════╪═= ═════╪════λ= 2;═══╪══════ = 552;═╡
           [01]..[EF] 32   │<= /span> 01..EF x1     │<= /span>
           [F0]..[F3] 32   FF     x1..x4
           [F4]..[F7] 64   FF     x1..x4
           [F8]..[FB] 128  FF     x1..x4
           [FC]..[FF] 256  FF     x1..x4
           └───&#= 9472;────────┴─= ─────┴────γ= 2;───┴────── = 472;─┘


 For information on custom speed ta= bles please refer to:
 http://www.adlibtracker.net/files/techinfo.htm

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

V= I. SONG VARiABLES         ∙<= o:p>

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 ──────&#= 9472;─

 

 You can specify how should be the song called here.

 The maximal length of string is 42 character= s.

 

 

 ──────&#= 9472;─

 

 You can specify who was the creative person = that made the song here.

 The maximal length of string is 42 character= s.

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──

 

 These are just values for information about number of common items used.

 You cannot change them since they are calcul= ated by the tracker.

 

 

 ──────&#= 9472;───

 

 With range 1-255, you can specify what will = be the initial song tempo here.

 The value is decimal, the unit used is "frames per second" (Hz).

 However, you can calculate the tempo also in "beats per minute" (BPM)

 with the following formula:

 

   (tempo_in_Hz * 2.5) =3D tempo_in_BPM<= o:p>

 

 

 ──────&#= 9472;───

 

 With range 1-FF, you can specify what will be the initial song speed here.

 The value is hexadecimal, the unit used is "frames per row".

 There is also an Update switch beside the so= ng speed field.

 You can specify there, whether the song speed should be reset to "initial"

 when song loops back to order 0.<= /span>

 

 

 ──────&#= 9472;────

 

 With optional range, you can specify what wi= ll be the multiplying factor

 for macro-definitions here.

 

 i.e. 1 means that the macro commands will be triggered once per frame,

      2 means twice per f= rame (speed-up is 2),

      3 means three times= per frame (speed-up is 3), and so on.

 

 

 ──────&#= 9472;──────────=

 

 You can specify the initial Volume Lock state here.

 If Volume Lock is set, you can also set its initial settings for all

 available tracks in the Initial Lock Setting= s.

 For more information see chapter V, part "Lock track volume".

 

 

 ──────&#= 9472;──────────= ─

 

 You can specify the initial Panning Lock sta= te here.

 If Panning Lock is set, you can also set its initial settings for all

 available tracks in the Initial Lock Setting= s.

 For more information see chapter V, part "Lock track panning".

 

 

 ──────&#= 9472;─────────

 

 You can specify the initial Peak Lock state here.

 If Peak Lock is set, you can also set its initial settings for all

 available tracks in the Initial Lock Setting= s.

 For more information see chapter V, part "Lock volume peak".

 

 

 ──────&#= 9472;──────────= ───

 

 You can specify whether to use the 4-operator track extension

 on corresponding tracks here.

 Note that this adjusts the number of tracks = if neccessary.

 This mode is a bit complicated so it is recommended=

 to experiment to gain familiarity with making 4-op instruments= :-)

 

 

 ──────&#= 9472;──────

 

 You can specify the initial tremolo depth he= re.

 See also chapter V, part "Tremolo"= .

 

 

 ──────&#= 9472;──────

 

 You can specify the initial vibrato depth he= re.

 See also chapter V, part "Vibrato"= .

 

 

 ──────&#= 9472;───────

 

 With range 1-256, you can specify what will = be the pattern length here.

 Note that the pattern length value affects w= hole song.

 

 

 ──────&#= 9472;─────────

 

 With range 1-20, you can specify what will be the number of tracks here.

 Note that value above 18 automatically toggl= es percussion mode ON.

 

 

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;────

 

 You can specify whether to use 5 percussion tracks here.

 Note that percussion mode automatically chan= ges the number of tracks to 20,

 but you can decrease the value as neccessary though.

 This mode is slightly hard to use (particularly the "SD/TT/TC/HH" tracks)

 so it is not recommended unless you know how it works or gain familiarity

 with it after several experiments :-)

 

 

 ──────&#= 9472;───────

 

 (iMPORTANT OPTiON)

 You can specify whether to use volume scaling mode here.

 Volume scaling mode differs from default mod= e in handling the volume

 when performing effect commands. When in def= ault mode, the volume is set to

 value requested in effect column whatever is= the base volume specified in

 carrier or modulator cell of instrument.

 When in volume scaling mode, any change of volume with effect command is

 calculated as scaled base volume of instrume= nt.

 

 

 ──────&#= 9472;──────────= ────

 You can specify the initial settings of Pann= ing Lock, Volume Slide type,

 Volume Lock, and Peak Lock for corresponding track here.

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

V= II. GETTiNG STARTED       ∙<= /span>

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 Any piece of music written with the /┤= DLiB TR/┤CK3R ][ is built up

 from patterns. Each pattern is built up from= 1 to 18/20 tracks.

 A pattern is 1 to 256 lines long. The line w= here the cursor is always

 the one you edit. If you need shorter patter= ns and you don't want

 to shorten the overall pattern length in song variables,

 use the Pattern Break effect command (Bxx).<= o:p>

 A track is built up like this:

 

        &n= bsp;     ┌────┬────γ= 2;────────── = 472;───┬────

        &n= bsp;     │LiNE1     &n= bsp;           │ 2

        &n= bsp;     ├────┼────γ= 2;────────── = 472;───┼────

        &n= bsp;     │ 37 │ ···  ··  ···  ··· │ ···

        &n= bsp;     │ 38 │ A#5  01  ···  ··· │ ···

        &n= bsp;     │ 39 │ A-4  ··  330  ··· │ C-2

        &n= bsp;     │ 3A │ ···  ··  300  ··· │ ---

        &n= bsp;     │ 3B │ ···  ··  300  ··· │ ···

        &n= bsp;     │ 3C │ ···  ··  ···  ··· │ D#2

        &n= bsp;     │ 3D │ D#1  02  ···  ··· │ ---

        &n= bsp;     │ 3E │ C-2  01  ···  ··· │ ···

   current ──>│ 3F │ C-4  01  C20  201 │ C-2<= o:p>

   line     &nb= sp; │    │           &n= bsp;       │

        &n= bsp;     │    │       =             │

        &n= bsp;     └────┴────γ= 2;────────── = 472;───┴────

        &n= bsp;            ^    ^   ^    ^

        &n= bsp;            │    │   │    = 474;

        &n= bsp;            │    │   │    = 492;─ effect command 2

        &n= bsp;      note ─┘    │   │

        &n= bsp;            = ;     │   └─ effect command 1

        &n= bsp;            = ;     │

        &n= bsp;            = ;     └─ instrument

 

 The C-4 is the note being played at pattern position 3F,

 01 is the instrument number, and the followi= ng six digits are the

 two effect commands, in this case, Set Volum= e to 20 Hex, and Frequency

 Slide Down by 1 unit per frame. Remember that values for instruments

 and effects are always hexadecimal!

 You can enter the note by switching into MBo= ard mode while the song

 is Stopped or while the song is Paused with = no Trace or by setting this

 mode OFF (Shift+Space to toggle) then by just typing the note into

 the corresponding fields.<= /p>

 Likewise, you can either type in the instrum= ent number.

 The instrument number corresponds to the act= ive instrument.

 You can check the active instrumet at the bo= ttom of main screen or directly

 in the Instrument Control panel.<= /span>

 If in MBoard mode, this will be entered automatically when a note

 is entered through the keyboard (MBoard keys= ).

 Typing in the instrument number (if "update_ins" option is ON) will affect

 the numbers in following lines and the active instrument in Instrument

 Control panel. After you have edited all your patterns, you have

 to determine the pattern order. For that sim= ply use the Pattern Order

 editor. Enter (while the song is Stopped or while it is

 Played with no Trace) will toggle the Pattern Order editor.

 Furthermore, you can define a restart positi= on.

 Here's an example:

 

 Let's say you have entered three patterns (numbers 0, 1 and 2) and

 want to play the pattern 2 twice, then patte= rn 0 and finally

 pattern number 1 three times. Afterwards the music should start

 from order 2 (with the pattern 0) again.

 Edit the pattern order like this:=

 

        &n= bsp;     ┌─────────γ= 2;─────

        &n= bsp;     │ 00 0204 = 01

        &n= bsp;     │ 01 02 │ 05 01

        &n= bsp;     │ 02 00 │ 06 82 <───&#= 9472; jump to order 2

        &n= bsp;     │ 03 01 │ 07 80

        &n= bsp;     └─────────γ= 2;─────

        &n= bsp;       ^  ^

        &n= bsp;       │  │

        &n= bsp;       │  └─ pattern number (entry)

        &n= bsp;       │

        &n= bsp;       │

        &n= bsp;     order number

 

 To enter the notes /┤DLiB TR/┤CK= 3R ][ uses a piano-like keyboard layout

 when in MBoard mode (see chapter III, part "I" for the layout).

 The program supports 8 octaves. You can see = the active octave in the bottom

 of main screen or directly in the Octave Con= trol panel.

 When both MBoard and Tracking mode are OFF, = you can type in the notes

 into their corresponding fields.<= /span>

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

V= III. USEFUL TiPS          ͨ= 9;

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

   The tracker is capable of highlighting corresponding lines.

         Y= ou can toggle this mode on-and-off with Alt+M, and setup by Alt+L.<= /span>

 

   You can preview an instrument before loading it.

         In the file open dialog or bank browser, use MBoard keys while

         cursor is positioned on instrument you want to preview.

 

   When in Debug mode, you can trace the song row by row

         w= ith Space key from Pattern Editor as well as from Debug info<= /p>

         window toggled by holding Ctrl+Alt. When the song is played

         w= ith Trace, you can temporarily turn on Debug mode and process=

         r= ow by row playing with Space key directly from Debug info window.

 

   When transposing patterns, it's somet= imes useful to keep some of

         n= otes intact from changes (e.g. drums).

         Y= ou can do that by holding Right-Shift key while putting notes

         u= sing MBoard keys, or you can remark already put notes to-or-from

         f= ixed state in single steps or in blocks by Shift+Enter.

 

   You can force /┤DLiB TR/┤= CK3R ][ to behave like Scream Tracker or

         FastTracker when typing in commands within the Pattern Editor

         a= nd Macro Editor window.

 

       &nbs= p;            &= nbsp;              ┌─────&= #9472;──────────= ;────────┐=

        &n= bsp;            = ;              ADTRACK2.iNi SETTiNGS  = │<= /span>

                                   │<= /span> FOR DEFAULT MODE:     

        &n= bsp;┌&= #9472;──────────= ;───────┬──^= 72;───┤ “command_typing=3D” AND  │<= /span>
         TYPiNG MODE      FLAG “cycle_pattern=3D”    =   

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>╞&= #9552;══════════= ;═══════╪══_= 52;═══╪══════&#= 9552;══════════= ═══════╡<= /span>

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> Adlib Tracker II   AT        1/OFF           

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> FastTracker      │<= /span>  FT  │<= /span>       1/ON &nbs= p;           │<= /span>

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> Scream Tracker     ST  │<= /span>       2/OFF           

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>└&= #9472;──────────= ;───────┴──^= 72;───┴──────&#= 9472;──────────= ───────┘<= /span>

 

         Y= ou can set each of these modes as default mode on program start
         with corresponding setting= s in configuration file as shown

         i= n the above table. You can, however, switch over these modes
         anytime later, using respe= ctive combination of keys.

         P= lease note that when you set command typing to 0 (mOrOn),
         you cannot switch over any= of these modes.

 

   You are reminded of changes you have = made to the song.

         In the status window, a small diskette icon appears in case there

         w= ere changes since last loading or saving.

 

   You can get information about track properties while Playing,

         Debugging, Tracking or even if song is Paused in the

         u= pper area of Pattern Editor (beside corresponding track number).

 

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>┌&= #9472;────┬─────= ;──────────^= 72;──────────&#= 9488;

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> ()  panning Center           │<= /span>

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> (   │<= /span> panning Left            = ; │<= /span><─ if panning indicator

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span>  )  panning Right            │<= /span>   changes color, it means that

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>├&= #9472;────┼─────= ;──────────^= 72;──────────&#= 9508;   the Panning Lock has been

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span>1'4OP first 4-op tr= ack (main)     activated/deactivated;

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span>2'4OP second 4-op track           f= or more information,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> BD  Bass Drum track          │<= /span>   see chapter V, effect ZBx,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> SD  Snare Drum track            a= nd effect ZF9, and also

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> TT  Tom Tom track            │<= /span>   chapter VI, part "Track Panning

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> TC  Top Cymbal track            Lock"

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> HH  Hi-Hat track           &nbs= p; │<= /span>

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>├&= #9472;────┼─────= ;──────────^= 72;──────────&#= 9508;

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> M^  Modulator vol= ume slides  <─ for more information,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> C^  Carrier volume slides       see chapter V, effects ZF6,<= o:p>

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> &^  Car w/ M= od volume slides    ZF7 and ZF8

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>├&= #9472;────┼─────= ;──────────^= 72;──────────&#= 9508;

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> P+  Peak Lock active         <─ for more information,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>│<= /span> V+  Volume Lock active          see chapter V, effect ZF2,

         <= span style=3D'color:gray;mso-themecolor:background1;mso-themeshade:128'>└&= #9472;────┴─────= ;──────────^= 72;──────────&#= 9496;   and effect ZF4

 

   You are able to gain different setups= for corresponding directory

         by creating directory-specific configuration.

         Simply place your "ini" file where you want to use corresponding<= o:p>

         setup, and run the tracker from within this directory (it's useful

         to make a batch file there).

 

   You can use shortkey [BackSpace] for upper-dir and [\] for root

         in File Selector.

 

  You can play your songs one after another by pressing Shift+Enter

         instead of Enter key in File Selector.

 

  While working with 4-op tracks, marking instruments

         in Instrument Control panel will choose a set of instruments=

         f= or corresponding 4-op tracks. Two instruments will be then

         always used as "current" instead of one.

         Y= ou can keep track of them in the Instrument Control panel as well

         a= s in the Status Line.

 

  While working with 4-op tracks, panning wor= ks within both

         channels if you have used some AM connection at least in one

         of the two instruments. You are then able for example play some

         operators in one channel and others elsewhere.

 

  While working with instrument macro-definitions, don't forget

         to paste appropriate instrument data to FM-register table

         f= irst in order to use it. You can do that with ^Enter key, which

         pastes default instrument data to current row.

 

  While working with clipboard, you can use p= aste same copied object

         t= o more pattern(s) quite easily. Simply copy the object to clipboard

         as usual, and press [Alt][Shift] P key.

         T= hen the Pattern List will appear, where you can select a single pattern

         or multiple patterns with [Space] as a destination.

         T= hen press Enter key to apply.

 

  You can load a pattern to a multiple destination--pattern(s) when

         in Pattern List and there are some marked patterns.

         Simply mark one or several patterns with [Space] and load=

         desired pattern file.

 

  If working with percussion mode (respect th= en :) percussion

         tracks SD/TT/TC/HH may stop responding. Go to the File Variables=

         window and set the percussion mode switch off-and-on.

         A= fter 1-3 retries the tracks should start responding again.

 

  While testing/previewing an instrument with= in Instrument Control,

         Instrument Editor or bank browser, you can check the macro table=

         k= ey-off phase of this instrument. In order to do that,

         h= old [Ctrl] key before releasing the MBoard key, and note(s) will

         t= rail in key-off phase until you release [Ctrl] key.

         Furthermore, you can check the key-off phase with "key-off loop".=

       &nbs= p; In this case, hold the Ctrl+Alt keys pressed when releasing<= /p>

         t= he MBoard key.

 

  The tracker features both simple playback m= ode and playback mode

         w= ith synchronization. The advantage of synchro-playback is that

         y= ou can gain authentic and accurate sound at any time and any point.=

         T= he playback is synchronized everytime when it's neccassary, so

         a= ll the playing effects, song tempo, song speed, song timer a.o. are=

         j= ust the same as they are when playing whole song from start.<= /p>

         T= he disadvantage is that it sometimes takes awhile (maybe longer :)<= /span>

         w= hen playback synchronizes (depending on CPU and song structure)

         Anyway, you can leave the sync-mode using [Alt] variant of playback

         shortkey (i.e. Alt+F5, Alt+F8 and Alt+F9) even if the song

         is already playing. Note that you can set up playing without=

         synchronization as the default action in configuration file (set=

         option "nosync_by_default" to ON).

 

  You can play the current pattern in single-playing mode.

         It means, that you are able to play patterns that are not signed

         in pattern order. The whole pattern is played with repeating then.<= /span>

         Y= ou can toggle this playback mode with Alt+F6.

 

  If working with macro-definitions, you can disable one or more

         columns in FM-register table. This is useful when you need

         to change only single or a few parameters (i.e. volume fading,

         p= itch sliding) with macro-definitions and other parameters

         w= ith pattern effects. This mode works similary as disabling tracks

         in Pattern Editor, but using Ctrl+Backspace for single

         ON/OFF instead.

 

  When making macro-instruments, it's sometim= es useful to reset

         t= he ADSR envelope several times during macro-cycle. You can do this<= /span>

         by setting the note retrigger for appropriate row of macro-table;

         Ctrl+N toggles ON the retrigger for corresponding row and Ctrl+Alt+N

         resets flags on all rows.

 

  You can control the playback from within the Instrument Control

         p= anel. Following commands are functional:

 

         F5            &= nbsp;  Play

         F6            &= nbsp;  Pause

         F7            &= nbsp;  Stop

         F9            &= nbsp;  Play current pattern or order only=

         [Ctrl] Home,End  * Skip to previous/next pattern while Tracing

         +,-              * Same as above; play pattern from st= art

 

         N= OTE: Commands marked with asterisk (*) work only while the name

        &n= bsp;      of instrument is not being edited.

 

  You can control current instrument directly= in Macro Editor window

         u= sing Ctrl+[] keys. It is even possible to control current instrument
         and octave while in macro-preview mode.

 

  When working with /┤DLiB TR/┤CK= 3R ][ native bank files (A2B, A2W),
         you can force loading comp= lete bank instead of going to bank browser.
         This can be done easily by pressing Shift+Enter instead of Enter key
         in File Selector.

 

 TiP 25  All options from config file can be controlled also directly

         f= rom command line. Syntax for usage is as following:

 

           "adtrack2.exe [[/cfg:option] [...]]"

           e.g. "adtrack2.exe /cfg:sdl_screen_mode=3D2 /cfg:sdl_frame_rate=3D150"<= /span>

 

 TiP 26  When deleting notes in Note Recorder mode, you can fast-forward=

         o= r rewind playback while deleting them. All you need to do is

         p= ress Up or Down key while still holding the Backspace key.

         Furthermore, you can delete all notes within marked group of tracks<= o:p>

         a= t once with pressing Ctrl+Backspace.

 

 TiP 27  When deleting notes in Note Recorder mode, you can fast-forward=

         or rewind playback while deleting them. All you need to do is

         p= ress Up or Down key while still holding the Backspace key.

 

 TiP 28  When working with banks containing 4OP instruments, it may be

         sometimes useful to put instrument data from one of the 2 paired

         instruments only. This can be done by pressing Shift+Enter

         i= nstead of Enter (which puts instrument data for complete 4OP pair).

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

I= X. KNOWN PROBLEMS         ∙<= o:p>

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 There are no major issues known for this version of program J

 REMiNDER<= /span>
 ────────
 If you are encountering any proble= m with this program, please send
 a bugreport to my email address (s= tated below in this document).<= /o:p>

 

 

┌──────&= #9472;──────────= ;───────∙∙  ∙

X. EPiLOGUE          &nb= sp;     ∙

∙       &= nbsp; ∙∙────────γ= 2;────────┘

 

 

 HON= EST 'THANK YOU' TO FOLLOWiNG PEOPLE

 ──────&#= 9472;──────────= ──────────γ= 2;──────────

 

 (in random order)

 

 Florian Klaempfl and others [Free Pascal Compiler 2.6.4]

 Simple DirectMedia Layer [SDL 1.2.15]

 Daniel F. Moisset [SDL4Freepascal-1.2.0.0]

 Alexey Khokholov [NukedOPL3 1.6]

 Haruhiko Okomura & Haruyasu Yoshizaki [LZH algorithm]

 Markus Oberhumer, Laszlo Molnar & John Reiser [UPX 3.91w]

 

 (further in alphabetical order J)

 

 Daniel Illgen (insane/Altair)

 David Cohen = (Diode Milliampere)

 Dmitry Smagi= n

 Janwillem Ja= gersma

 Florian Jung (Windfisch)

 Maan M. Hamz= e

 Mikkel Hastrup (encore)

 Nick Bale= ga

 PissMaste= rPlus

 Slawomir = Bubel (Malfunction/Altair)

 Sven Renn= er (NeuralNET)

 Tyler Montbriand (Corona688)

 

 

 ──────&#= 9472;──────────= ──────────=

htt= p://www.adlibtracker.net

 

 For compl= ete AT2 revision history please refer to:

 http://www.adlibtracker.net/files/revision.htm

 For complete AT2 file format description please refer to:
 http://www.adlibtracker.net/files/techinfo.htm

 

 SEN= D YOUR QUESTiONS, SUGGESTiONS, AND CRiTiCiSM TO

 ──────&#= 9472;──────────= ──────────γ= 2;────────── = 472;──────────&= #9472;

 = subz3ro.altair@gmail.com

                                                =                            

∙              &nb= sp;            =             &nb= sp;            =             &nb= sp;          ∙=

∙       &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;            &= nbsp;           &nbs= p;     │

└──────&= #9472;─────────∙= ;∙           ∙∙────────γ= 2;─∙∙        &nbs= p;        ∙∙────────γ= 2;────┘

 

This document was last updated on December 24, 201= 8.

------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/item0033.xml Content-Transfer-Encoding: quoted-printable Content-Type: text/xml ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/props034.xml Content-Transfer-Encoding: quoted-printable Content-Type: text/xml ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/themedata.thmx Content-Transfer-Encoding: base64 Content-Type: application/vnd.ms-officetheme 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 AACbCgAAAAA= ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/colorschememapping.xml Content-Transfer-Encoding: quoted-printable Content-Type: text/xml ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image001.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 U10cjLdndaqdnSqONFx9pxp2r1ZPdaqvA9WplqE61TKgq+pUy1Cd6uJgvD2rU6071U8P1amWoTrV MqCr6lTLUJ3q4mC8PatTTXeq7VWoO9XXiepUy1CdahnQVXWqZahOdXEw3p7VqfpO1Xamyld3qq8f 1amWoTrVMqCr6lTLUJ3q4mC8Pa9T9R2p8gQH2nWqcro4VeqpTvV1oDrVMlSnWgZ0VZ1qGapTXRyM t+d1qvWZ6ieH6lTLUJ1qGdBVdaplqE51cTDentepymn6TrXjWBOnSj3Vqb4OVKdahupUy4CuqlMt Q3Wqi4Px9rxOtT5T/eRQnWoZqlMtA7qqTrUM1akuDsbb8zpVpZ0JXNmpHoWwO9Wwe7V6qlN9HahO tQzVqZYBXVWnWobqVBcH4+15nWrdqX5yqE61DNWplgFdVadahupUFwfj7Xmdqpxmu1MV+H3V2Kna ThVfVZ3qq0F1qmWoTrUM6Ko61TJUp7o4GG/P7lSn7VT9+LfuVF8PqlMtQ3WqZUBX1amWoTrVxcF4 e16nqjRzpsGpslON7+tO9fWhOtUyVKdaBnRVnWoZqlNdHIy353eq8U4151RVR92pvh5Up1qG6lTL gK6qUy1DdaqLg/H2rE7VHKeAE+XZqu1Uxy8oWZri6k71FaE61TJUp1oGdFWdahmqU10cjLfnd6rB ifIRCPtR8tSpqo66U309qE61DNWplgFdVadahupUFwfj7fmdquA71cO6U331qE61DNWplgFdVada hupUFwfjbXOcarxTJS6k1Z3q60J1qmWoTrUM6Ko61TJUp7o4GG/P61TlQGOnepgc/4bnrHWn+opQ nWoZqlMtA7qqTrUM1akuDsbb8zpVpc3cqVan+qpQnWoZqlMtA7qqTrUM1akuDsbb8zrVulP95FCd ahmqUy0DuqpOtQzVqS4OxttGOdV0p1qd6utDdaplqE61DOiqOtUyVKe6OBhvG+VU60719aM61TJU p1oGdFWdahmqU10cjLeNcqrsVLnaTpU4XatTfV2oTrUM1amWAV1Vp1qG6lQXB+Nto5xq3am+flSn WobqVMuArqpTLUN1qouD8VadagHGHapOdVFUp1qG6lTLgK6qUy1DdaqLg/H2vE5Vaenxb+xUSatO 9XWhOtUyVKdaBnRVnWoZqlNdHIy353Wqdaf6yaE61TJUp1oGdFWdahmqU10cjLfndapKy+5UiQtp 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 J1cAAAAASUVORK5CYIJ= ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image002.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 54iTBAOTgv834qADiYdv31kAAAAASUVORK5CYIJ= ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image003.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAAXNSR0IArs4c6QAABW9JREFUSEut Vm+IVFUUP+++e9+fnTdvZ5zZrV0tIwuFMgupD5qa9IfIsloVhKLsQ32IvhiBRCiZFmShqaGIJSYS IeRaRCKRIJlZbSGFGlmQkGma6+Y6Mzt/3nudc8+8t29mNfrQ5TBz3znn/s7v3HPPfc8AGA9gwv8w AsQ4duzBPTsPrnrtaAWuZUgBoPRv8pjM0zFR2SZpfzYhjmmacOP1Wc236Y9/hhZUJnmwjTUs7MMy lkpiErZt1AIjBiLnhG8aSAKg8EiHGRuMPUd5lEoNIU1jlLRkprxLCeux8zRrhsMlKG3ZmN3dPYWu gmyGJPaMleSY5simdB5X2kzWk39tpFwpj6gmY1Iy66SAzIslvTktFXbtTN+jvblcMfYZ9TeEYUSR MBJYk2e8lSjpMrbtL7uZ+w/OL4+8+PKzIxeHTrSuIkKGQYUNo3qCiQGsFGvmgppEyXngIyV64Mt5 c2dO+e7jNXfdeziESpx6soqOT71arUAtaYC24zj2zHAwOuYDPy6cPWPO4d0b5z787TCVZkpMJVll RVFYGr7UICtzsrhBEtZp7omerEd+Wjj95um/HFo/b8H3SK8OMy6XugoaQRBFug8YigKkQXlup4TQ o+j+aZP9I3tXz5y5D5dWYVa8Ku1JaxuNEMvgULWYtMIA6JSAtgVj9DsBap9sfvXuBw4h+iDcB9AR M2jSjBEsIUzHdTwrkzDAUBjgSgOP3FSA0vK+dW/3k89ZmK9d8ahE06bCrNkYAJQ0a7WaAZHnO1dd bXt5XykDag67Sancy8AHIVaoXpsMMLxy8fpN/ZTjoFhEFwidbBpzbv31jTXTjQhTxEOghGkaIsTT Wb54sVqpSmGzp5ErLBGAFrThWSEVz8+eKiq7tGLB5k27Cb1SWEIO2JhkJB938GBW/Zb17GyXlSu6 1Vpw5lxl565FX3z+9frVv592HmFnY8KkpRi8mQRh07V+8rgS8q/lfdve6dfX3g1LU1lq5yiA5NJs 2mjh0QF374eH3t0wdLx0j1YH0u+dKPRmJRADn/0h5IVVj23b3g+4fe6Mt4g7weou1Z7xJZXWEEgQ nPn73PlyJfS7J+CSMAhlttgL2N/YIRDccVt9w/ITAupvPrPjvfcBj0KubxcBJm+BtnKNskIMA58i +LN8qVwpQfamXmITBLKj2AV4N0Xh7bdUXn/uZwBn8/ObdmytZm3IP3GAGJO1DTgOyXodXjMEqVSH 5zm+tPJduIVREEmns4CHN6wHjz80gId3+4q1W9addzqN4tM/NKs6BlxXWdeaB13JzYF5uF6mMH5c Y1yRtdLy86ZhUoFMa+uylzauOe10qmteOIkaM66NEHqvwxRhrkRaj/MwQpd6vWqalvALWGHycby8 5ftuxt/zqb3/qx6/JzfplQuW3+n6najHCYr0fBSea6Vv5fIoLXrPVxkfEfGVU6mOONh1Xh7FeHJL 1P7VwuR1hrixlx1sbY7YB5PasHjljrUffLTvuvFP7cUE0CKkB9JtFR9kBkzsRHuMKfa0XEBhHxMn LBaWmjbTVIowPcBbQigHlAX0y5NYLAf+RRiRV+HNhsITaoUwlMpiTCQhTPwEsEDiDYvSoUXPR3kl BFEZC/Pg1E2lRZtqjerw4FADXwkWMLIwO8DqaOHOi4UiUSyclj0qtB41bNV6S2v06x7CBjAshhRK gkAD/sbCi3EBCpnwUXPE1ifRgZusGZQ1GA+vLSGkklhthiWiBtp0Lom0BENTa2ByTrFBZ9bQwUMo YWALYj/jHDsZ8xHIJflqMSSQoO0/SsqfUlRw6kLPxO4o43dylhjeWPYN9WRyYeM8oAZsaq40b2mO VIPbog4jQ+XAE46rP5HgH9MJcp6kBVhZAAAAAElFTkSuQmCC ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image004.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg /9j/4AAQSkZJRgABAQEAeAB4AAD/2wBDAAoHBwkHBgoJCAkLCwoMDxkQDw4ODx4WFxIZJCAmJSMg IyIoLTkwKCo2KyIjMkQyNjs9QEBAJjBGS0U+Sjk/QD3/2wBDAQsLCw8NDx0QEB09KSMpPT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT3/wAARCAAsACwDASIA AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3 ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3 uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDxyilx RivQ9mybiUV3vh7wnZaRpB8ReLkK2mP9Gsm4e4PbjriuP1W+TUtRluIraO1iY/JDGPlQdhXPCqql Rwir269PQbVlc6Xw3Hv+HfiU4HymM81xtdp4bbZ8OvEvqWjH864zFZ4eF6tVea/JDlsi6dOlAyRx XYaH4fs/DOnp4g8TR72PNjYH70rdmYeldHYQadosVxqOoWpuWgUeTAFzvb3FZj6dfa7ftq2tfNO/ +qh/hhXsMV14mNatV+rUlZfafl2RjCpBQ9pL5I5LXdR1XxLfG71F2P8AzziH3Yx2AFWdEh0KG3ZN asL6abdw8LALj8a6z+xF/u0n9iL/AHa6v7PiqSpQbivLQy+tpu7GKujt4D1xNDs7qIFkDtcMDk9s V53/AGdL6V6nJp6W/g/UkPyh5o+lURoi4Hy9vSuXA4fkrVoXvZrf0NKldckX3udb9lHpS/ZR6VfC ikwMV6XtGeNzFH7KPSj7KPSr+BmjaKPaMOYxNeTyfDE4xw1xGKtC1G1eOwq3eWkV9Zm2mBMZYPgH HIqbYuBxXJh1KFarJ/aa/JHRUqJ04Ltf8z//2T== ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image005.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image006.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg /9j/4AAQSkZJRgABAQEAeAB4AAD/2wBDAAoHBwkHBgoJCAkLCwoMDxkQDw4ODx4WFxIZJCAmJSMg IyIoLTkwKCo2KyIjMkQyNjs9QEBAJjBGS0U+Sjk/QD3/2wBDAQsLCw8NDx0QEB09KSMpPT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT3/wAARCAEuAqYDASIA AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3 ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3 uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwDtvCfh Pw/c+DtFmn0LS5ZZLCB3kezjZmYxqSSSOSTWt/whnhr/AKF7SP8AwCi/+Jo8Gf8AIkaD/wBg63/9 FrW1QBi/8IZ4a/6F7SP/AACi/wDiap32h+CtL2f2hpfh+23/AHfOtoUz9MiumrlbRbA+I9V/tlbb 7QWXyftGOYsD7ueMZo6gTv4e8HpZyXX9i6I0Ef3nSziYD8h70mn+HvCOpwvLaaDpLojtGSbCMfMO vVaw/FUemWvg2dNCF6lt5rbv7NwVLHGd2e30rQ+HIl/seYzDVMtISPt23B91x+tNWd/67f5g3axr f8IZ4a/6F7SP/AKL/wCJo/4Qzw1/0L2kf+AUX/xNbVFIDlLrT/AVjO0F3ZeG4Jl+8kkECsPwIq1J 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 HdrOTcIirtCOvZjzlhRQB//Z ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image007.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAQUAAACECAMAAACu085qAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAMDAwNTU1KioqODg4OTk5MzMzNDQ0Li4uLy8vNzc3Ozs7 NjY2PT09Pz8/Q0NDRUVFRERETU1NRkZGT09PR0dHTk5OUFBQUVFRUlJSSUlJU1NTVFRUSkpKS0tL VVVVVlZWV1dXWlpaWFhYW1tbXFxcXV1dX19fXl5eWVlZTExMSEhIYGBgYWFhZGRkZWVlZ2dnaGho aWlpa2trbGxsbm5ucHBwcXFxc3NzcnJydHR0dnZ2eHh4dXV1eXl5d3d3e3t7enp6fX19fHx8f39/ fn5+b29vbW1tampqnp6enJycmpqamJiYlZWVl5eXk5OTkZGRj4+PkJCQjo6OioqKjIyMiIiIh4eH hYWFg4ODgICAgYGBlJSUmZmZn5+fv7+/vr6+u7u7ubm5urq6sbGxs7OzuLi4vb29t7e3tbW1tLS0 srKyr6+vra2trKysvLy8qamppaWlpKSktra2oKCgsLCwrq6uqqqqp6eno6OjoqKiqKioq6urzs7O ycnJy8vLwcHBwMDAxsbGx8fHw8PDwsLCxcXFxMTEysrK1NTU9PT09fX17+/v/v7+6+vr8PDw7Ozs +/v78vLy/Pz88fHx7e3t/f397u7u+fn58/Pz+Pj49vb29/f3+vr66urq4ODg////AQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID+UBlNgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAkA 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image008.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image009.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAKysrPT09MTExLCwsODg4KSkpXFxcQkJCS0tLXV1dQ0ND VFRUTU1NWVlZUFBQV1dXT09PVVVVXl5eU1NTW1tbUlJSVlZWSkpKRERETk5OQEBAa2trdHR0cHBw dnZ2b29vbGxsampqaGhoZ2dnZmZmfn5+ZWVlf39/fX19aWlpZGRkbW1td3d3cnJycXFxeXl5enp6 bm5ue3t7fHx8c3NzdXV1YmJiY2Njg4ODkJCQjIyMioqKi4uLh4eHkpKSjo6OgoKClJSUmZmZgICA np6ehISEl5eXlpaWhYWFn5+fkZGRgYGBiYmJmpqanZ2dj4+PnJycjY2NiIiIlZWVk5OTu7u7sLCw tra2urq6tbW1vLy8v7+/vb29t7e3oKCguLi4srKypaWlr6+vs7Ozubm5vr6+qqqqrKysqKiorq6u sbGxpKSkp6enra2toqKiq6uro6Ojpqamqampx8fH0dHRy8vLz8/PzMzM2tra29vb2NjY1dXV0tLS ysrKyMjIzs7O2dnZxMTEw8PDwMDAycnJ1tbWxcXFxsbG09PT3d3d0NDQ1NTU19fXzc3N39/fwsLC 3Nzc3t7ewcHB8fHx5ubm7e3t4uLi+fn57u7u8PDw8/Pz5eXl+/v79vb2/Pz8+vr65OTk8vLy6urq 7Ozs9/f36enp4ODg4+Pj/f394eHh6+vr/v7+6Ojo+Pj49fX15+fn7+/v////AQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDWtGavgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAe3 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image010.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAASYAAACkCAYAAAA6y4O9AAAAAXNSR0ICQMB9xQAAAAlwSFlzAAAS dAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUATWljcm9zb2Z0IE9mZmljZX/tNXEAABuBSURBVHja 7Z2Hl1VFtofnrffPsJyXRx0V3syoa4aFggmXS0UZn2SJKqKAIAq00I3EJkuQINAkEQmC0NDwCC3d IChBgqKCIIg5h3r11dThXdoON5x77znn/r619gKavunUvvvs+tWuXb979tlnfyeTyWRRMl0EmUwW 3cBkjLnH2giZTCYroj3UMDC9ZoQQorict/b31MC0QtdECFFkvrO2PzUwVemaCCGKzCFrf1BgEkJE iUvWViswCSGixEfWRigwCSGixDFrtyswCSGixNfW9ikwCSGiBOL31QpMQogo8am1lQpMQogogfj9 nAKTECJKSPwWQkQOid9CiMiB+H2NApMQIkogfi9XYBJCRAmJ30KIyIH43UGBSQgRJRC/6xSYhBBR 4m0j8VsIETEKI35/88035rvvvtPlFjnx66+/mq+++sp88cUX5uuvv9YFSS5nrI3Ka2A6duyYmT59 upk/f7758MMPdclF1hw+fNhMmjTJlJWVmcrKSvPBBx/ooiSTo9ba5yUwcXc7ceKEqaioMB06dDAd O3Y0c+fONefPn9dlFxnz0UcfmfHjx5t27dqZG2+80bRv397d8M6dO6eLkzzyJ36fOnXK3dn69etn qqurzerVq02vXr3M1KlTzeeff65LL9LmwoULZvTo0WbAgAFmz5495siRI2bnzp2md+/eZtu2bbpA ySM/4vfx48fNuHHjTI8ePcwbb7zhfobGxHSuS5cuZvbs2ebTTz/V5RctcunSJZd19+nTx+zYseOK /9u9e7epr683n332mS5UsiA4VIUamL788kszb948061bN/Pqq6+6KV3AxYsXzbRp00z37t3Na6+9 Zn7++WcNgWgWbmZk2hs3bmz0/5EHgpufSAyI32WhBaZffvnFnDlzxixZssRZalAKOHv2rFmwYIFZ sWKFW11p7HeEwC9YzUXkXr9+faN+8u2337r/X7t2rfnxxx910ZID4vctoQUmtKM333zTpdfNZUME pL1795oDBw6ojEA0yg8//GBqamqcnvTTTz81+3v40v79+3XRkkO44jfLt5MnT3bpd3MgZjKlmzNn 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image011.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAPT09Pj4+PDw8Xl5eTExMV1dXUVFRUFBQX19fWlpaTk5O VVVVT09PWFhYWVlZW1tbXV1dU1NTVFRUUlJSVlZWS0tLSkpKfHx8fX19bW1tbm5ucHBwfn5+Z2dn cnJyd3d3dXV1dHR0ZGRka2trcXFxc3Nzampqenp6e3t7YGBgbGxsYWFhdnZ2aWlpYmJif39/eHh4 eXl5b29vY2NjaGhojo6Ol5eXjIyMmZmZhISEgYGBhYWFioqKnZ2dhoaGiIiIn5+flZWVnp6eh4eH i4uLm5ubgoKCjY2NiYmJlpaWk5OTmJiYnJycj4+PlJSUg4ODkJCQgICAkpKSkZGRmpqasrKypaWl tbW1vb29tLS0rKysqampoKCgoaGhurq6u7u7uLi4tra2o6Ojs7OzsLCwpqamv7+/pKSkvr6+r6+v sbGxrq6uq6urubm5qqqqqKiovLy8p6enoqKira2t09PT1dXV29vb3Nzc3d3d2dnZ0tLSwcHBwsLC xMTEwMDAzc3N2traysrK39/fz8/Pzs7O3t7e19fX2NjYy8vLzMzMycnJ1tbWyMjI1NTUxcXFw8PD 0dHRx8fHxsbG8/Pz+/v78vLy9/f3+fn58PDw9fX14uLi/Pz87u7u/f396+vr6enp5eXl7e3t4eHh 7+/v5ubm4+Pj4ODg9vb25OTk9PT05+fn6urq7Ozs+vr66Ojo8fHx/v7++Pj4////AQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDcjw+rgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAhh 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image012.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAASYAAACkCAYAAAA6y4O9AAAAAXNSR0ICQMB9xQAAAAlwSFlzAAAS dAAAEnQB3mYfeAAAABl0RVh0U29mdHdhcmUATWljcm9zb2Z0IE9mZmljZX/tNXEAABsdSURBVHja 7Z2Hs1XFloff1PwzlBPem3nqM817b7REEfSVoXAcA1iKYEYExAgiAiIiImbFgCgSDGAWRIIJCSYQ BFRERSSYI2pPf23vmsPxhhP2PnvtfX5fVZfl5d4TenevXuu3Vnf/4corr/yDmpqamqWmTlBTU7Nr mJxzfX0bpaamppZj619tmB53QgiRL9t861dpmOaoT4QQOfO9b6srDdMs9YkQImfe8u3PMkxCCEvs 8u0RGSYhhCU+8m2UDJMQwhLrffuHDJMQwhLf+LZChkkIYQnE771lmIQQltjp21wZJiGEJRC/R8sw CSEsIfFbCGEOid9CCHMgfu8jwySEsATi92wZJiGEJSR+CyHMgfh9pAyTEMISiN8rZZiEEJZ420n8 FkIYQ+K3EMIcH/s2RoZJCGGJdb71kWESQlhC4rcQwhwSv4UQ5kD8niXDJISwBOL3WBkmIYQlEL+P kGESQlhC4rcQwhyI3/vKMAkhLLHDt5kyTEIISyB+j5dhEkJYQuK3EMIciN+rZJiEEJZA/P6LDJMQ whKI3w/IMAkhLCHxWwhhDsTvXjJMQghLSPwWQpgD8Xs/GSYhhCUkfgshzPGJbxNkmIQQlnjHt8Nk mIQQlpD4LYQwh8RvIYQ5EL9nyDAJISyB+D1RhkkIYQnE754yTEIIS0j8FkKYA/F7fxkmIYQltvs2 XYZJCGGJrb5NkmESQlhC4rcQwhzfOonfQghjSPwWQpgD8fteGSYhhCWKJ37v2LHDffbZZ3p0nfDN N9+43bt3u59//tl98sknbteuXeqUTqBvPvroozCefvzxR3VIB9Avn376qfv444/d119/3aq3Rfw+ 1Kxh+uWXX9wPP/zgvvvuO/f999+79957z912223uxhtvdO+//374ufj/AUR/PPHEE27FihXu9ddf d1dffbW799573eeffx76Ubgwjuin7du3u/vuu89dccUVYTy98sor4d9oGPV2hoWNPvryyy/diy++ 6CZNmuS8fXCPPfaY27p1a/i3jMcT4vdqk4bp119/dW+++aabOXOmmzZtmpsxY0booBNPPNEdf/zx 7pprrnF33323++CDD2SUvFHCIN1xxx3uvPPOc5dffnkYSEcddZTr37+/u/nmm93s2bODt9nO4B1h qBk3N910kzv11FNdr169wniiz/g3xtnLL78cDFQ7gtFZtmxZ6KM777zTXXzxxe7YY491vXv3dmef fXYw4szHRx991G3bti2rj7HGtwNMGiaMEqvZMccc4/r06eMOP/zwMOnmz58fOuX8888PE+/aa68N lnzDhg1tN4i++uqrMIhmzZrl+vXrFwYPRmj8+PHBMD399NPBsDOwjj76aHfXXXe5RYsWhVWvHY3S ddddF8bSkUce6c4444xghJ566in35JNPBu+S/mNMDR482C1evLjtPCe8IPrizDPPDPMNgz1hwoSw 6DGWMFQDBgxwPXv2dCeffHIYa88++2zwPlPGpviNUWIFGzZsmLv++uvD6oa3xCBKWLBggbvlllvc kCFDwsQbO3ZscMc3btzYNoNo3rx57qSTTgpt4sSJYaBgdNasWeNWrVoVfu+nn34KK9zkyZPDZKSv GGCEd+1klPj+5557bljxGU8sbpVeEWOOf7vhhhvcpZde6i666KLQv3jkZdefCN3WrVsXFrjhw4cH L4l+wGvi5wl43I888kjoS+YljgIGCnkl5cWOF5tswjARun3xxRdBGxkzZkxwG5csWdLt3z333HOh I1nlTj/9dDdy5MjSh3cYpWeeecYNHTo0rG7jxo1z3377bbd/h0EaOHBg6Cu8BcRx+rys7Ny5M+iS LGD0E952Laxdu9aNGjUqhHqjR492L730Upi8ZQSjyzwbMWJECPvxkN59991u/46Qb+7cucGA40Ux thDJUwLx+xAThglP55577gmThrZw4cKaBDbcbSYlncukO+WUU4L+tGXLllIOJL4v35XVnzCWVazW JAD9SWYFo0RfMekeeOCBYJxYGMoE2UkmywUXXBBW9jlz5tRsXOgLPAWkhOOOOy4sdsuXLw/JmLIZ JaSACy+8MHjdSAC1GKUEvHEEcrQ5jBOeeUoLnQ3xmwzblClTQpgxaNCgmo1SdSezOi5dujQMRIwT HkHZeO2114K+hldJCrcRGDxkpNBUWCUfeuihVqaCM4cQbfr06e6EE04IY6qR74dxYvygyeGRIysQ 7pUFvh8iP4YbA4zhRcxuZIFiPN1+++0hYmHRSyFbnr/4jYVGH8KYkFVi4jWbimQw4boTC5ep5omJ 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 G33b5Nsr8WfPx9950bfN7rdrg1f69lnF+/Ie3Nr5ZmyfVLzvovi7K+Pfbo6v9Xl87Z3xvTbF9341 /mxR/J1l8bOujZ99W/wuyftujd/17fjdl1S87/bYR+u76Uv6enlVXy6t6MvVvn1a8b4vxP/n52t8 2xJ/P+nLHfH1eN33fHu5oi93xe//QRfPkGwI8f0bHfTltoq+rHyGlX25MbbqZ5j0ZfIMt3XwDN+I 7/1xVV/yDFe431LIyTPcVfG+L8fvuiE+wx0Vz3Bp7KM13fRl8gyXVj3D5S2YD1uq5sOO+D02xO9V pPnQ2TOsdz58zWtjmP45PrzjfBvj21TfDol/0CM+/IN9uxlL5tuxvi307V/ioNnXtwd9G+zb6b49 6tt/xE74d9+e8O1k30b4do9vB8YPsFf8An18m+DbJN96xU7oETvnr77d6dulvv2Pb8/69q/xtf/s 2xzfzoptTvzZyvg7z8a/uTS+xl/ja/aI79ErvueE+BmWxM+0PH7Ge+JnPtG3J+N34bX/M37H0+N3 fjD2wYrYJwtjH42OfXZw7MMesU8PiX1MXx8dH9Be8e/3822Gb0N8O9W3eb79Kb7vH32b71s/34b6 Nt23/eND3ysOlH/4Nta3Kb4dGgdfjzjoWHxu9W1UfNYLKp7h3u63UP4c3wb5Njd+T97333x7yrf/ 9e0S36b5dlDspx5xQh/h28TYjog/6xF/56D4N5fE13gqvmbSl3Pje54TP8Pe8TPxDJ/zra9vl/t2 u29/i98leYaHxQV1vG9HxT7YK/bJ/rGPhsY+mx/7cGXs03mxj4fEPt8vvu9e8ZkcnfF8GO7bfb4d UPEMF8fvMT5+r6LMh0d8O8O383yb6ds+FfNhQRxvtc6HlURw/wdm/aI8slB/6AAAAABJRU5ErkJg gk== ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image013.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAANzc3PDw8Ojo6RUVFUVFRQUFBRkZGWFhYSUlJX19fSkpK XV1dWVlZW1tbUlJSVlZWXl5eVFRUU1NTTExMUFBQWlpaTk5OV1dXcXFxYWFhZWVlcHBwfX19dHR0 bm5uf39/b29vY2NjYmJifHx8aWlpfn5+ZmZmcnJybGxse3t7dXV1d3d3dnZ2eXl5ampqbW1taGho enp6hYWFlZWVhoaGlJSUnJyciIiIgICAlpaWi4uLgoKCiYmJmpqamJiYl5eXn5+fmZmZgYGBnp6e hISEnZ2dk5OTg4ODjY2Nm5ubioqKjo6OkpKSkJCQjIyMj4+Ph4eHkZGRvb29rq6uq6uroaGht7e3 rKysvr6+p6entLS0paWlvLy8r6+vqqqqtra2qKiosrKysbGxu7u7qampsLCwuLi4ra2tpKSko6Oj s7Ozv7+/ubm5urq6oKCgpqamtbW1oqKi2dnZ1dXV3d3d0NDQ1NTU09PTzMzM29vbz8/PysrKxsbG wcHByMjI2tra3t7e0tLSwsLCxcXF19fX0dHRxMTEw8PDycnJzs7Ox8fH3Nzc1tbW39/fy8vLzc3N 5eXl/Pz8+fn55OTk/v7+8/Pz7e3t4+Pj+vr66urq5+fn/f396enp+/v79vb28fHx9PT08vLy4uLi 8PDw9fX19/f36+vr5ubm+Pj44ODg4eHh6Ojo7+/v7Ozs////AQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDG1zwPQAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAbU 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 gk== ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image014.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 QmCC ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image015.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAANzc3ODg4Ojo6PT09Pz8/XFxcXV1dUFBQXl5eWFhYW1tb UlJSVlZWWVlZVFRUV1dXWlpaVVVVX19fU1NTTExMUVFRTk5OT09PYGBgaGhoYmJiYWFhZGRkZmZm Z2dnaWlpampqa2trbW1tcXFxdHR0eXl5enp6fX19fn5+dnZ2c3Nzb29veHh4fHx8bm5ukZGRk5OT lpaWjY2Ni4uLj4+Ph4eHkpKSlJSUlZWVl5eXnZ2dnp6em5ubmpqakJCQjo6OnJycmJiYjIyMgoKC hISEhoaGiYmJiIiIhYWFn5+fg4ODmZmZgICAgYGBioqKrq6urKysqqqqq6urpqamoaGhsrKyoqKi ra2to6OjqKiov7+/paWlu7u7ubm5tbW1vb29vr6+sbGxoKCgr6+vtLS0s7OzzMzMzs7O0tLSyMjI wsLCxcXFzc3N0dHR09PTxMTEy8vLz8/Px8fHxsbGw8PD39/fycnJ3NzcysrK3d3d29vb2dnZ19fX 2NjY1dXV0NDQ1NTU3t7e1tbWwMDA+fn5+/v7/v7+/f39/Pz89PT09/f34ODg8/Pz9vb29fX18vLy 7u7u+vr67e3t6enp5ubm5OTk4eHh8fHx6urq5eXl4uLi6Ojo4+Pj7+/v////AQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDy2O5sgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAYt 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 RK5CYIJ= ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image016.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image017.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAJycnPDw8Ly8vOjo6NjY2KCgoMTExPj4+KysrKSkpKioq Li4uOTk5NTU1LS0tLCwsMjIyMDAwNzc3UFBQQ0NDSkpKVFRUWFhYTU1NU1NTV1dXXV1dREREQkJC UVFRXl5eWVlZWlpaX19fS0tLT09PUlJSRkZGSEhIXFxcd3d3f39/fX19enp6bm5uYWFhcHBwaGho b29vZGRkaWlpYmJidXV1ZWVla2trZmZmeXl5eHh4Y2NjdHR0cXFxcnJylpaWjY2Njo6Ol5eXiYmJ mJiYk5OTi4uLlZWVhYWFgYGBmZmZhoaGjIyMgICAmpqaj4+PkZGRnp6enZ2dg4ODh4eHnJycsbGx pKSkpqamqqqqp6env7+/tbW1tLS0tra2vr6+oaGhubm5paWlqampo6Ojrq6uurq6qKiorKyst7e3 r6+vsrKys7Oz1NTU3Nzc19fX0tLS29vb2NjYw8PD0dHRzc3N09PTycnJwMDAz8/P3t7e39/fy8vL 2dnZxsbG1dXVzs7Ox8fH0NDQxMTEwsLC3d3d2traysrKzMzMwcHBxcXFyMjI1tbW7u7u7e3t7+/v /Pz88vLy4ODg+Pj48/Pz/v7++fn59vb2/f39+vr65ubm9fX1+/v74eHh7Ozs6+vr8PDw4uLi6urq 5+fn5eXl6Ojo5OTk6enp9PT09/f34+Pj////AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDlVpxbgAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAX/ 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 d9njPwAAAABJRU5ErkJggk== ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image018.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image019.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAQQAAACEAgMAAAALob31AAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAAxQTFRFAAAAAAAA////AQIDb7EEKAAAAAF0Uk5TAEDm2GYAAAAJcEhZ cwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAB09tt6UAAAGySURBVGje7ZdBjsMgDEWz GWnU+7HpPovhJHOBRCPvgwqnnLQphPxiTCZZjFR7B9jf7xNC2q77B3EJB+Owwk0ZlEEZlEEZlEEZ 3obBI8MACZOFiSuMR2DwWECo6ADBAgOszwkggYou2C0DBQsJEBxjUpBMeEaRfxao6EAjjaKCD0IQ M58YXjZSUkwFUYG4BM5VLEgMXILMVDnVjh08W1LO4LGtDfVYmVrfLOJUI8PfH0UzA+sqMhDMuyDE WvBUsEIB74p7LygIsbZcFHZsXCsDukKmrOWiIG4cHwyDR2vI5Na+Z30vCKzsOA6NDB7LXhjQJgUh soI2hoqrhYG7yQVXexgqrhaG3bdDHm0M6CpruTAQnyC7amKouVoYEJLK7GXhJobaB+zB4GXWyvYU GRhXxX15MBy4XxgG8ZDnLU/6TYs2dx2oKkNMZB+SjQw2nwj77pe2fYiuyiyzwlRrUWLaKN0ZrpCQ FB2jOG6ku4tJK8Os1fdmVZyXyJg1wdgwTsYkxWlO/ek+8u7GUIbsgzH9pvtgvjbEd7m3/5+lDMqg DMqgDMqgDMqgDMqgDOcxfH4fjF/uRX0OYFcM4QAAAABJRU5ErkJggk== ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image020.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 xne7Hc+2/wOgjNPikX6hVwAAAABJRU5ErkJggk== ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image021.png Content-Transfer-Encoding: base64 Content-Type: image/png iVBORw0KGgoAAAANSUhEUgAAAP8AAACDCAMAAAB1Nj1CAAAAGXRFWHRTb2Z0d2FyZQBNaWNyb3Nv ZnQgT2ZmaWNlf+01cQAAAwBQTFRFAAAAW1tbXV1dX19fVFRUVlZWV1dXXl5eUVFRUFBQYGBgYmJi aGhoa2trb29vcnJydXV1eHh4YWFhZ2dncHBwZGRkcXFxZWVlZmZmbW1taWlpampqbm5udHR0f39/ Y2NjdnZ2bGxseXl5c3Nzfn5+fHx8d3d3fX19g4ODm5ubioqKkZGRn5+fnZ2dnJyciYmJmpqaiIiI mJiYlZWVkJCQlpaWkpKSnp6ej4+PhoaGk5OTgYGBh4eHtLS0qKiorq6ura2to6Ojp6envr6+vLy8 sLCwoqKiqampvb29t7e3ubm5srKypKSkr6+vtbW1urq6q6urpaWlpqamqqqqrKysv7+/sbGxs7Oz 0dHRxcXFyMjIzMzMw8PD3t7exMTEwMDAzc3Nzs7O0tLS2tra39/f0NDQ3d3dy8vLysrKwcHBxsbG 1tbWwsLC19fX2dnZ3Nzc29vbz8/P/Pz88fHx+fn54ODg/f395eXl5OTk+/v78vLy9fX16Ojo9/f3 8/Pz9PT0/v7+7+/v9vb2+Pj46urq5ubm+vr64uLi7u7u6+vr8PDw5+fn////AQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQID AQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDAQIDDTaJQwAAAAF0 Uk5TAEDm2GYAAAAJcEhZcwAAAEAAAABAAGJDY1sAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAAAS+ SURBVHhe7Vv5WxMxEEUQRYWqrYBLqVweFAVBCh6IFFEE5VYUkEM8iicoFAoFBEQFNX+0uy2oQNvN ZCeG/XaWn/i+mffe5CWTZNumpdHj8BFgDn4M6x1cPmMOr5/8d/b8J//Jf+r/zh0BWv+0/p07+/XK 6fxH538HLwDq/9T/HTz9qf87fP+j/d/Z/Y/8J/+dvP/R+c/Z85/8J/+d3P9o/3f2/Cf/yX9A/5tu nAFE2yAUuP+HD8yqLWpgEJnfZu8/bpXj1g/0n7EmpQtgYAi3fOD7v7lgJH0eWwEEr7n86TAk3jQW 5v/C0RFTRMkB/gpcAputf9ziY9Mf9vlf+HYUW4NSPGj9i8eWlOpFJgf7j8wPhxttgeekyID6j0ou Aua/KJKVLAfu//Klz5gCVGOB/Y9mT6vV3HIHkR/uP2OVK4gCQFBDd/VwfysoxyQY4v9qldH7Z3Iw +UFYwctG+CDiBAD5v+qKH/+qQKLRg6vvIUJC/N+iXcuo+YKoAA41hncLAvm/rXTuOFwzZsaVg21o cAL+69y162gCRIBaG0WyEuUI+c++nsDiF8RpRzsEivm/GggLKsdJq7uPgwO//8V5l04i8YvCPHgm mrkrT8x/tlCPxC8IU5c5Lpi5M01s/TP2zY38HgZazdXMAWhKwnhB/9mi59Q1FAGiIJWHnoum/pMn 6j9j33PTUW+i4GL87rwNcNKeBFH/daDNw2pnQEd+7gurAyDuv87847SmaSovA7VuXcCmpTGw4L9+ FSwoKPDmxJ5OSypEk6t0ATq5tl4jeCk1/I8XsP00A7VEdAl/h2EnFvy/NVaR3M+26kTaAsYYeI1h AD++qHEA2pUWK6crEVP5y+Rj8wpMnjBBr8Or07sSEiWu3witWWZnBAT4onvXf0hfUpqW4/HsvWNd l//hb722eMPgz/Z4/s8dI8n6n3C5vPnDwKWAGN7gchW6fYiASaBS9P/hPG/Ra/kKkjMUl2SUSudP 1f9bytLfSBeQisDnKZX8stlk/2/KUrgG9JEJB2SPv8n+35T1VraClPjRs3LpTc9/waxuuQpSo0e0 c3LpTc9/Pe/kCjBBX9GkzgBT/xkLTCgdgM8lUt81mfrPOo6gvWwUGsiflUJpfEkc/rMexV/62TjP V4tQlLn/jN1UewoYQf3Ac+co8fjPehHeswiZs5UUkngV4PGfNby3It9ybqgvBtGF/N1PA5PLf9b3 wXINlgAmYzeh8aAlkMTJXP7HUzVlJ4GpXgmVxyD5/Ge+UT22OSJLhUJcPv8fflQoUaceLZPEz+m/ JHZu2KlH3KHAQD7/gaD2Cef1X1N7DWb9eZLGlNP/TvmvPlMWOPVYTv28/sth3weonP4zD953rvZB 1X8kcPv/ZL7ok0rh3RfaimXw8/rPWPuSDH5ezNDYLOLXPuH+s6JJXqm2iuP2v/2X2roaC2Xwc69/ GeQgzFA/KJw3mNt/XkB7xdnHf0njSv7Dfv8nyQZlsOQ/+a9s8qknpv4P/P2zestQFZD/5D/qhLIb GO3/tP/bbc4i6qX+T/0fcTrZD4r6P/V/+81aNMXU/6n/o00mOwJR/6f+b8d5i6SZ+j/1f6SpZE8Y 6v/U/+05c1FUU/9PY47++w1+zF6eEmSNjgAAAABJRU5ErkJggk== ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image022.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 A+onsGMGB9Y9AAAAAElFTkSuQmCC ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image023.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg 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 iiiiiiiiiiiiiiv/2S== ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image024.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image025.png Content-Transfer-Encoding: base64 Content-Type: image/png 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 Nw3+97//B/9qrJQ5EIe7AAAAAElFTkSuQmCC ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/image026.jpg Content-Transfer-Encoding: base64 Content-Type: image/jpeg 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 ------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/header.htm Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="windows-1250"





------=_NextPart_01D49B5D.3D5D5E60 Content-Location: file:///C:/EF521992/adtrack2.files/filelist.xml Content-Transfer-Encoding: quoted-printable Content-Type: text/xml; charset="utf-8" ------=_NextPart_01D49B5D.3D5D5E60-- adlibtracker2-2.4.24/package/ver/sdl/windows/0000755000000000000000000000000013414570764017470 5ustar rootrootadlibtracker2-2.4.24/package/ver/sdl/windows/adtrack2_hq2.bat0000644000000000000000000000021413411003760022402 0ustar rootrootstart adtrack2.exe /cfg:sdl_screen_mode=2 /cfg:sdl_frame_rate=150 wmic process where name="adtrack2.exe" CALL setpriority "high priority" adlibtracker2-2.4.24/package/ver/sdl/windows/adtrack2_hq1.bat0000644000000000000000000000021313411003760022400 0ustar rootrootstart adtrack2.exe /cfg:sdl_screen_mode=1 /cfg:sdl_frame_rate=150 wmic process where name="adtrack2.exe" CALL setpriority "above normal" adlibtracker2-2.4.24/package/ver/sdl/revision.txt0000644000000000000000000006075013411003760020365 0ustar rootroot+====================- -=+ | | | /|DLiB TR/|CK3R ][ SDL Revision History | | | +=- -=======================+ For complete AT2 revision history refer to: http://www.adlibtracker.net/files/revision.htm * version 2.4.24 released: 12/24/2018 (* 12/27/2018) . fixed version check for Reality ADlib Tracker modules . fixed instrument preview bug in Arpeggio/Vibrato Macro Browser window . fixed C-9 note replacement bug on invalid flat-sharp conversion . fixed linefeed option not being evaluated for some actions and added possibility to disable it for MidiBoard (refer to option 'lf_in_mboard_mode' in config file) . fixed broken Global Freq. Slide Up/Down effect command . implemented native BPM handling: - implemented BPM calculation (predicted according to rows per beat taken from Line Marking Setup window) - added possibility to manually control playback speed (hotkey: [Ctrl]{Shift} Up,Down) and controlling it using effect commands (refer to extended command 'ZE7') - added overview of current BPM and playback speed shift in Hz . changes in Song Variables window: - changed cursor movement to be more predictable/convenient - added key shortcut for each option - added preview and prediction of BPM speed - added access to quick setup of rows per beat (hotkey: ^Enter) . improved behavior of temporary song status in the upper left corner . optimized window arrangement in case of enlarged screen size . improved string input (quick change of decimal and hexadecimal values with +/-) * bufgfixes (...) * version 2.4.23 released: 07/27/2016 . fixed typing behavior bugs in Message Board window . fixed pattern names not being read from A2M file . fixed typing with Alt-codes; changed alternative hotkey for adjusting volume of sound output (new hotkey: [Alt][Shift] Up,Down) . fixed ADSR preview being shown for KSR instead of Envelope type . fixed incorrect pitch calculation in instrument preview . fixed bug when preview of non-macro instrument in File Selector overwritten macro data of current instrument . fixed interface bug occurring on instrument preview in File Selector . fixed replace function for Key-Off notes . added back and improved 'per instrument' positional memory . improved functionality of Pattern List window . added operator preview functionality to Instrument and Macro Editor . added automatic 4OP track volume manipulation (4OP+) for much more convenient work with volume for some volume-based commands and added command switches for toggling old (2OP) handling (for more information, refer to documentation of extended command 'ZE5/ZE6') . fixed 'Bxx' command not being evaluated correctly in 2nd effect column . fixed mistyped frequency multiplier values . added 'reset envelope' and 'ZERO frequency' triggers to FM-macro table . added short keys for copying data between carrier/modulator column in Macro Editor window and copying data between carrier/modulator slot in Instrument Editor window . added possibility to apply table indexes to current instrument in Arpeggio/Vibrato Macro Editor window . completely redesigned handling of notes within 4OP channels and improved user interface . fixed slow reading of instrument bank files . fixed preview of empty instrument with FM-register macro . slightly fixed channel ON/OFF for percussion tracks SD/TT/TC/HH . added possibility to slow down SDL timer so playback speed is more accurate to real hardware (refer to option 'sdl_timer_slowdown' in config file) . implemented new (improved) OPL3 emulator * version 2.4.22 released: 09/20/2015 (* 12/17/2015) . changes/improvements in Instrument Editor window: - added operator connection graphics - added browsing through all 4 operators with Enter and Tab/Shift+Tab keys - added status hints for current operator/instrument/4OP track - rearranged carrier/modulator/general settings - improved browsing through radio button sections - added separate color for percussive instruments - added section hotkeys for quick navigation - removed 'per instrument' positional memory (obsolete now) . improved speed of user interface in Macro Editor window . improved changing current instrument when 4OP instrument is selected . changed behaviour after releasing MBoard keys in instrument preview mode to Key-Off trailing . fixed Key-Off phase preview with 4OP instruments . improved functionality of Macro Browser under different conditions of use . fixed unintentional setting of octave while forcing KeyOff trailing with Ctrl key upon instrument preview . fixed interface bug in Macro Editor window when changing current instrument upon macro preview . fixed interface bug when loading complete content from A2B/A2W files . fixed macro restart with 4OP tracks upon note retrigger . changed compression algorithm to LZH / new file format versions . added fast-forward / rewind multiplication factor options (refer to options "fforward_factor" and "rewind_facotr" in config file) . updated file system and overall improved manipulation for more convenience when working with 4OP instruments . added new effect commands for restarting envelope (refer to "ZEx") . fixed non-functional hotkey for operation Paste object from clipboard to more patterns (new hotkey: [Alt][Shift] P) . added one step undo operation in Pattern Editor window (hotkey: ^Z) . added hotkey to delete complete note/instrument columns of track group when in when in Note Recorder mode (hotkey: ^Backspace) . fixed program freeze upon reaching last marked line when jump to next marked line was activated while cycle pattern was disabled . added option to keep track position (column) when jumping over tracks with Tab/Shift+Tab keys (refer to option "keep_track_pos" in config file) . improved seeking to pattern / position when song is played without trace . fixed several bugs in OPL3 recording; invoke of recording mode 'per channel' is now ignored when recording to single file is set by user configuration . pretty much improved internal logic for preview of 4OP instruments . added key shortcut for Instrument Editor window (hotkey: ^E); changed hotkey for Arpeggio/Vibrato Macro Editor window (new hotkey: ^G) . added Message Board window (hotkey: ^B) . (LINUX) fixed case sensitivity issue for filename extension * fixed bug that may lead to program crash when previewing TT/HH instrument * fixed cursor behavior on typing instrument name and in Message Board window * upgraded SDL to version 1.2.15 * version 2.4.21 released: 04/12/2015 (* 05/11/2015) . fixed/improved precision of playback calibration with pattern jumps . fixed typing in effect columns with NUMPAD keys . added alternative key combo for setting volume level of sound output on keyboards without NUMPAD keys (hotkey: [Alt] Up,Down) . fixed reading RGB color palette settings from config file . fixed occasional playback mute issue with F7 key in MBoard mode . fixed occasional messy behavior of +/- keys in Macro Editor window . fixed/improved fast-forward/rewind speed . added 'per instrument' positional memory to Instrument Editor window . improved track data processing during playback * fixed interface bug (misplaced cursor) in Instrument Editor window * added option to turn off positional memory for Instrument Editor (refer to option 'remember_ins_pos' in config file) * fixed sound glitch in OPL3 emulation for channels with null ADSR data * fixed some bugs in Macro Arpeggio / Vibrato performer * version 2.4.20 released: 12/23/2014 (* 01/08/2015) . changed hotkey for toggle of typing modes (hotkey: F11) . added toggle of line feed (hotkey: F12) . added toggle of jump to marked line (hotkey: [Shift] F12) . added back quick file load for modules (hotkey: [Shift] F3) . enhanced MBoard and Note Recorder with jump to marked line option . fixed stuck keyboard issues in MBoard mode . fixed fade in WAV recording with impossible start of playback . added possibility to remove song trace and continue playing while cursor position is maintained (hotkey: [Shift] Esc) . changes in Note Recorder mode: - fixed quick reset last group of tracks action - fixed behavior of some keys for mode exit - added row correction parameter . changes in Macro Browser: - fixed return to browser after selecting arp/vib table - improved arpeggio/vibrato table selection and indication . added Global Freq. Slide Up/Down commands and added command switches for Fine resp. Extra Fine variant (refer to new commands "xx" and enhanced functionality of old "ZFD","ZFE" commands) . fixed processing of new effects in Debug Info window . fixed some typing check bugs in Replace window . fixed bug when after swapping instruments one name was incomplete . fixed cursor key navigation within Remap and Replace window . removed sdl_sample_rate and sdl_sample_buffer options . added Rearrange Tracks function (hotkey: ^X) . added automatic activation of debug mode and switchover from offline to normal debug mode with Space when in Debug Info window . fixed/improved precision of fast-forward/rewind pattern function . added navigation to program home directory in File Browser window with Shift+Backspace key (refer also to option "home_dir_path") . added quick selection for muting track numbers above 9 with Shift key . fixed treating of all +/- combos for keyboards without NUMPAD . fixed player calibration issue with pattern break command * fixed interface bugs in Instrument Editor window * fixed fast-forward/rewind outside Pattern Editor window; added functionality to Instrument Control panel * fixed interface bug with ~xy effect command in 2nd effect column * fixed bug when entering notes for 4OP tracks in midiboard mode caused putting wrong instrument in left track of the pair * fixed rearrange function (faulty reordering of tracks) * version 2.4.19 released: 10/27/2014 (* 11/04/2014) . fixed switchover from offline to normal Debug mode with ^Enter . fixed not working instrument selection with no 4OP track extension . fixed position bugs in File Selector and updated layout for Linux . fixed lately introduced bug in Tone Portamento (arrgh) . fixed Tone Portamento with offline Debug mode and Note Recorder . fixed usage of non-NUMPAD asterisk (*) key for track ON/OFF flags . fixed/improved Replace function and added new shortkey functions . fixed pattern/order editor refresh bug occuring with small song speeds . added synchronized instrument/command processing for selected tracks when Note Recorder mode is armed . added quick reset of track group selection (hotkey: [Alt] Q) . improved layout in Instrument Control panel * fixed interface bug in Remap window occuring with sdl_screen_mode=2 * version 2.4.18 released: 09/05/2014 . changes in Note Recorder feature: - fixed bug when deleting notes was operating in wrong track if current track view on screen was moved by user; fixed precision with high song speeds (all notes are deleted now :) - added possibility to switch between using custom instrument and using present instruments in tracks (hotkey: Space / [Alt] Space) - improved keyboard reference on Help screen * version 2.4.17 released: 07/28/2014 (* 07/30/2014) . fixed ADSR preview update with enhanced screen modes . added Note Recorder feature (hotkey: ^Space) . changed file cache buffer for OPL3 recording to 512kb . added startup files for HQ-modes to program package * fixed some missing usage of non-NUMPAD +/- keys * version 2.4.16 released: 07/14/2014 . fixed cursor blink speed for non-default sdl_frame_rate value . improved current track movement in Debug Info window . added macro details section to Debug Info window . added flipped paste block feature (hotkey: Alt+Shift+V) . fixed/improved File Browser and Replace window . enhanced cursor movement in File Browser and Replace window . fixed in MAME OPL3 emulator: - experimental treatment of ADSR envelope restart for instruments with Attack Rate = 0 . enhanced Help screen navigation for effect columns . added FX volume information processing in marked block . small changes in user interface * version 2.4.15 released: 06/13/2014 . added 'Set Custom Speed Table' effect command (`xx) . fixed speed of decay bars for different sdl_frame_rate values; also minimum sdl_frame_rate value was limitied to 50 due to key processing issues with too low values . fixed conversion of FMK files . fixed listing of modules with '.' in filename within File Selector . fixed Tone Portamento in KeyOff-ed channel . fixed processing of Force instrument volume effect for 'AM' connections . fixed bug in processing of Arpeggio effect . fixed non-responding keyboard issue (hopefully :-) . small fixes in Arpeggio import from S3M files . fixed/improved/enhanced ADSR preview feature . optimized/enhanced color scheme options in config file . added possibility to control config file options with command line (refer to tip #25 in program documentation) . fixed handling of ON/OFF flags for 4-OP track pair . added positional memory for Song variables and Replace window . majorly improved Debug Info window functionality (hotkey: ^D) . fixed worse keyboard responsiveness upon instrument preview * SDL/Linux version 2.4.14 released: 04/24/2014 . Linux port made from SDL/Win32 2.4.14 sources * SDL/Win32 version 2.4.14 released: 04/09/2014 . fixed current instrument control in Macro Browser window . fixed macro speed manipulation and Song Variables value update . fixed filename sorting/filtering in File Selector window . fixed macro table preview bug with positive/negative columns . added macro speed control to Instrument Editor window . added FM-register macro table preview to Instrument Macro Browser . fixed FM-register table interface bug occurring with enhanced screen modes in Macro Editor window . improved layout in Arpeggio/Vibrato Macro Editor window . improved positional memory logic . major fixes/cleanups/optimizations of source code . updated incomplete key reference information in Help and .mht file . fixed waiting for key release when putting notes with MidiBoard . fixed non-blinking track flag and file overwrite bug in ‘per track’ recording mode . reverted back to “FT” as default typing mode * SDL/Linux version 2.4.13 released: 03/17/2014 . Linux port made from SDL/Win32 2.4.13 sources * SDL/Win32 version 2.4.13 released: 03/14/2014 . fixed faulty behavior of save-required notification with A2W files . fixed wrong instrument naming when loading complete A2W bank . fixed position behavior of instrument selection for load/paste register data operation in Macro Editor window; fixed interface bug in Instrument Control panel occurring upon these operations with enhanced screen . fixed arpeggio/vibrato macro table pointer in Macro Editor window * SDL/Win32 version 2.4.12 released: 03/11/2014 . added “per track” mode to WAV recorder (alter key: [Ctrl]) . added fully-featured macro browser . added bank browser for A2B and A2W files (finally :) . added file-dependent positional memory to all bank browsers . added positional memory to Macro Editor window . fixed command typing bug in arpeggio macro table . fixed not showing save-required notification . fixed sorting of filenames, filtered extra filename characters and optimized layout in File Selector window . switched back from MPRESS executable packer to UPX (due to reported malware alerts with some antivirus software) . improved paste operation in more places of the tracker . improved navigation system in Macro Editor window . improved layout of Macro Editor window . overall major improvements in macro data exchange and user handling * SDL/Linux version 2.4.11 released: 03/04/2014 . fixed case-sensitiveness problem when saving files . file issue fixed in more places (2.4.11.2) * SDL/Win32 version 2.4.11 released: 02/21/2014 . fixed cursor and decay bar speed to match DOS version parameters . fixed occasionally appearing interface bug in Pattern Editor window . improved CPU saving feature (refer to option “sdl_frame_rate”) . improved screen rendering routine (back to pure assembler roots :) . added Fade in/out feature for WAV recorder (alter key: [Shift]) . added new modules from Diode Milliampere . removed emergency unfreeze flash screen confirmation and changed key combo (Ctrl+Tab does the job now) . fixed in MAME OPL3 emulator: - rollback of current (experimental) changes for treating 4-OP channel volume attenuation - completely rewritten (according YMF262 specification) parts of code responsible for setting and changing total output level for 4-OP channels * SDL/Linux version 2.4.10 released: 02/14/2014 . first Linux port by Florian Jung * SDL/Win32 version 2.4.10 released: 02/13/2014 . fixed drive list being not shown in File Selector window . removed DBOPL emulation core (no more necessary I think :) . added WAV recording feature (hotkey: [Alt] F11/F12); check out config file and comments around option “sdl_wav_directory” for more information about how to setup output files * SDL/Win32 version 2.4.09 released: 02/12/2014 . fixed bug in playback calibration (macros were not processed) . fixed interface bug with long filenames in Status window . fixed not working block marking to left/right . fixed some false recognized key presses . fixed bad keyboard responsiveness when testing instrument in Instrument Editor window . fixed back treating of maximum macro speedup value (IRQ at 1000Hz with SDL works surprisingly without issues now :) . added emergency unfreeze command (hotkey: Ctrl+Shift+F10) . added command typing behavior mode handling in Macro Editor window . added instrument type indicators in Macro Editor window . added instrument type indicators and possibility to change current instrument in Instrument Editor window . added some new modules (Madbrain’s awesome A2M collection is hopefully complete now :) and a bit put to order some old ones . changed length of filename in File Selector to 23 chars . changed handling of F2/F3 related actions over instrument data . added wide enhanced screen mode (option “sdl_screen_mode=2”); extended screen content to 180/60 chars at 1440x960 pixels . fixed cursor position in Pattern Order with wide enhanced screen * SDL/Win32 version 2.4.08 released: 02/06/2014 . fixed interface bugs in Transpose and Pattern List window . fixed some non-functional keyboard combinations . changed F2/F3 related key combos: - some quick-load functionality was disabled for safety reasons; only single instruments and patterns can be quick loaded now - all quick-save functionality disabled except for saving A2M file in Pattern Editor / Pattern Order window - hot key for saving instrument bank w/ macros ([Shift] ^F2) in Instrument Control panel was simplified to [Shift] F2 . changed loading process of A2W files: - only FM-register / FM-register Macro Table instrument data is loaded within Instrument Control panel - only Arpeggio/Vibrato Macro Table data is loaded within Arpeggio/Vibrato Macro Table Editor window . fixed in MAME OPL3 emulator: - increased volume level by 50% for 4OP instruments with AM-AM, FM-AM and AM-FM connection (experimental) . improved playback rewind with low song speed values . improved enhanced screen mode; extended screen content to 120/50 chars at screen resolution 960x800 (check yourself with setting “sdl_screen_mode=1” :) * SDL/Win32 version 2.4.07 released: 01/30/2014 . fixed division by zero bug in playback fade out routine . added some modules from OxygenStar, a.o. to Modules directory . added new “AT” command typing behavior mode (like FT but without cycling pattern moves) (hotkey: Shift+F11); if not overriden by config file, this mode is set by default . removed console window (here you go Mikkel :) . added window icon and activated window close button functionality . fixed wrong position of bye-bye screen under some circumstances . fixed in MAME OPL3 emulator: - increased volume attenuation level in rhythm mode for all percussion channels except BD (experimental) * SDL/Win32 version 2.4.06 released: 01/26/2014 . fixed bug in replay routine (playback never advanced to order #7f) . fixed Status window update during playback calibration . fixed bug in treating KSL by MAME emulator (lucky at 4th attempt :); rollback of all previous changes to KSL – this trivial bug caused all the annoying discrepancies in sound compared to DBOPL emulator . fixed some serious interface bugs in Macro Editor and Remap Instrument window, which raised during portation to Free Pascal (btw, those ‘wtf’ table pointers had their meaning, Dmitry :) . added quick access key for Macro Editor window (^Q) . added macro-preview mode for Arpeggio/Vibrato Macro Editor window . added possibility to change current instrument directly within Macro Editor window (new key combo: Ctrl+[]) . added possibility to change current instrument and octave while macro-preview mode is activated . fixed treating of macro speedup (if unsafe, forced to lower value); SDL seems to have max. usable timer frequency at 650Hz, while DOS has been working just fine all the way up to 1000Hz ? * SDL/Win32 version 2.4.05 released: 01/22/2014 . fixed bug in replay routine (frequency data output for 4OP channels) . fixed bug with channel calculation in 4OP binding mode . added ADSR preview indication to Instrument Control panel . fixed first bugfix of KSL in MAME emulator ? * SDL/Win32 version 2.4.04 released: 01/20/2014 . fixed drive listing in File Selector (no more ‘insert disk’ messages without accesing drive :) . fixed calculation of KSL table in MAME OPL3 emulator (leads in those arcade-like Benjamin Gerardin’s songs sound finally correct :) * SDL/Win32 version 2.4.03 released: 01/17/2013 . fixed track binding not being displayed without panning lock on in Song Variables window . fixed binding of two 4OP instruments in Instrument Control panel . fixed toggle of ADSR preview (new key combo: Ctrl+LShift/RShift) . improved program exit procedure (it’s more DOS-like again :) . MAME OPL3 emulator: - updated according latest modifications from MAME (0.148u1) - fixed bug with setting KSL on 4OP channels . DOSBox OPL3 emulator: - added DBOPL emulator from DOSBox 0.74 - fixed stereo panning bug on percussion channels . added key combo for switching over OPL3 emulators ([Alt] F11/F12); current OPL3 emulator is always indicated by flag “MME” resp. “DBE” in Status window . added options to config file: - set sampling rate (sdl_sample_rate) - set sample buffer size (sdl_sample_buffer) - set default OPL3 emulator core (sdl_opl3_emulator) . complete conversion and update of program documentation (mht,htm) * SDL/Win32 version 2.4.02 released: 12/23/2013 . fixed program freeze with marking block at 4OP channel . fixed quick setting of octave and some other keyboard related issues * SDL/Win32 version 2.4.01 released: 12/18/2013 . code cleanup . removed MPU-401 code (not functional within SDL Win32) . removed some obsolete options from config file . fixed song timer / refresh rate decay bars . upgraded SDL to version 1.2.14.0 adlibtracker2-2.4.24/package/ver/sdl/readme-sdl.txt0000644000000000000000000000066613411003760020544 0ustar rootroot Please distribute this file with the SDL runtime environment: The Simple DirectMedia Layer (SDL for short) is a cross-platfrom library designed to make it easy to write multi-media software, such as games and emulators. The Simple DirectMedia Layer library source code is available from: http://www.libsdl.org/ This library is distributed under the terms of the GNU LGPL license: http://www.gnu.org/copyleft/lesser.html adlibtracker2-2.4.24/package/instr/0000755000000000000000000000000013411003760015537 5ustar rootrootadlibtracker2-2.4.24/package/instr/dan.sgi0000644000000000000000000000003213411003760017000 0ustar rootroot adlibtracker2-2.4.24/package/instr/pian1c.sbi0000644000000000000000000000006413411003760017411 0ustar rootrootSBIpian1c.sbiWõõúúadlibtracker2-2.4.24/package/instr/sachso2.sgi0000644000000000000000000000003213411003760017600 0ustar rootrootadlibtracker2-2.4.24/package/instr/leed2.cif0000644000000000000000000000006413411003760017215 0ustar rootrootbC²Åleed2.cifadlibtracker2-2.4.24/package/instr/brass1.sbi0000644000000000000000000000006413411003760017431 0ustar rootrootSBIbrass1.sbi!!q®žadlibtracker2-2.4.24/package/instr/pan.cif0000644000000000000000000000006413411003760017000 0ustar rootrootâfi÷÷pan.cifadlibtracker2-2.4.24/package/instr/floete.sgi0000644000000000000000000000003213411003760017514 0ustar rootroot  adlibtracker2-2.4.24/package/instr/tom.cif0000644000000000000000000000006413411003760017021 0ustar rootroot2Dõøÿtom.cifadlibtracker2-2.4.24/package/instr/shrtviol.cif0000644000000000000000000000006413411003760020074 0ustar rootrootâÈ fuö÷shrtviol.cifadlibtracker2-2.4.24/package/instr/fuzguit2.sbi0000644000000000000000000000006413411003760020015 0ustar rootrootSBIfuzguit2.sbi12HñòS'adlibtracker2-2.4.24/package/instr/cello2.sbi0000644000000000000000000000006413411003760017416 0ustar rootrootSBIcello2.sbippÅ„R1þadlibtracker2-2.4.24/package/instr/moogsynt.sbi0000644000000000000000000000006413411003760020115 0ustar rootrootSBImoogsynt.sbi õôž[ adlibtracker2-2.4.24/package/instr/bpiano.sbi0000644000000000000000000000006413411003760017506 0ustar rootrootSBIbpiano.sbiLóÔ |adlibtracker2-2.4.24/package/instr/bells.sbi0000644000000000000000000000006413411003760017337 0ustar rootrootSBIbells.sbiOòò`radlibtracker2-2.4.24/package/instr/celesta.sbi0000644000000000000000000000006413411003760017656 0ustar rootrootSBIcelesta.sbi“¶sbadlibtracker2-2.4.24/package/instr/cbassoon.sbi0000644000000000000000000000006413411003760020045 0ustar rootrootSBIcbassoon.sbi01Å€R1.adlibtracker2-2.4.24/package/instr/cymbal2.sbi0000644000000000000000000000006413411003760017567 0ustar rootrootSBIcymbal2.sbi$@µÕT…adlibtracker2-2.4.24/package/instr/laser.sbi0000644000000000000000000000006413411003760017344 0ustar rootrootSBIlaser.sbiæ0%ðµ@adlibtracker2-2.4.24/package/instr/kuorsau2.sbi0000644000000000000000000000006413411003760020011 0ustar rootrootSBIkuorsau2.sbipÖÄ€¤EBadlibtracker2-2.4.24/package/instr/syntbell.cif0000644000000000000000000000006413411003760020056 0ustar rootroot$‘¿Bsyntbell.cifadlibtracker2-2.4.24/package/instr/snare1.fin0000644000000000000000000000006213411003760017424 0ustar rootrootSNARE1.FIN Snare 1 òö%õ adlibtracker2-2.4.24/package/instr/church.sgi0000644000000000000000000000003213411003760017512 0ustar rootrootadlibtracker2-2.4.24/package/instr/tamb_g.cif0000644000000000000000000000006413411003760017453 0ustar rootrootÇvñôôtamb_g.cifadlibtracker2-2.4.24/package/instr/jump2.sgi0000644000000000000000000000003213411003760017273 0ustar rootrootadlibtracker2-2.4.24/package/instr/sftfl2.sbi0000644000000000000000000000006413411003760017436 0ustar rootrootSBIsftfl2.sbiæã'p`Ÿ adlibtracker2-2.4.24/package/instr/start.fin0000644000000000000000000000006213411003760017370 0ustar rootrootSTART.FIN Startsound Iòòôö adlibtracker2-2.4.24/package/instr/bagpipe1.sbi0000644000000000000000000000006413411003760017726 0ustar rootrootSBIbagpipe1.sbi1"Cn‹ adlibtracker2-2.4.24/package/instr/belshort.sbi0000644000000000000000000000006413411003760020060 0ustar rootrootSBIbelshort.sbiàpc€ø÷óóadlibtracker2-2.4.24/package/instr/trumpet3.sbi0000644000000000000000000000006413411003760020021 0ustar rootrootSBItrumpet3.sbi1¡€A’;adlibtracker2-2.4.24/package/instr/bass2.cif0000644000000000000000000000006413411003760017234 0ustar rootrootAŽc1tbass2.cifadlibtracker2-2.4.24/package/instr/deep.sgi0000644000000000000000000000003213411003760017153 0ustar rootrootadlibtracker2-2.4.24/package/instr/celpno2.sbi0000644000000000000000000000006413411003760017600 0ustar rootrootSBIcelpno2.sbi" òõ$Dadlibtracker2-2.4.24/package/instr/string1.cif0000644000000000000000000000006413411003760017611 0ustar rootrootB@=string1.cifadlibtracker2-2.4.24/package/instr/celpiano.sbi0000644000000000000000000000006413411003760020030 0ustar rootrootSBIcelpiano.sbi"òõCadlibtracker2-2.4.24/package/instr/acidbass.sgi0000644000000000000000000000003213411003760020007 0ustar rootrootadlibtracker2-2.4.24/package/instr/eguitarl.sgi0000644000000000000000000000003213411003760020052 0ustar rootrootadlibtracker2-2.4.24/package/instr/base.sgi0000644000000000000000000000003213411003760017150 0ustar rootrootadlibtracker2-2.4.24/package/instr/nice2.sgi0000644000000000000000000000003213411003760017236 0ustar rootrootadlibtracker2-2.4.24/package/instr/horror3.sgi0000644000000000000000000000003213411003760017634 0ustar rootroot adlibtracker2-2.4.24/package/instr/elguit2.sbi0000644000000000000000000000006413411003760017611 0ustar rootrootSBIelguit2.sbi–€ÿÿ! adlibtracker2-2.4.24/package/instr/tom1.sbi0000644000000000000000000000006413411003760017116 0ustar rootrootSBItom1.sbi÷ÖµOadlibtracker2-2.4.24/package/instr/vibra3.sbi0000644000000000000000000000006413411003760017424 0ustar rootrootSBIvibra3.sbiSQ—€ª¬!adlibtracker2-2.4.24/package/instr/loop.cif0000644000000000000000000000006413411003760017173 0ustar rootroot!!qž®loop.cifadlibtracker2-2.4.24/package/instr/vol.sgi0000644000000000000000000000003213411003760017036 0ustar rootroot  adlibtracker2-2.4.24/package/instr/organ2.sbi0000644000000000000000000000006413411003760017426 0ustar rootrootSBIorgan2.sbi$!€€ÿÿadlibtracker2-2.4.24/package/instr/flute.cif0000644000000000000000000000006413411003760017341 0ustar rootrootâÄ V6ö÷flute.cifadlibtracker2-2.4.24/package/instr/cbanjo.sbi0000644000000000000000000000006413411003760017472 0ustar rootrootSBIcbanjo.sbi1‡…¡}Cadlibtracker2-2.4.24/package/instr/battle.sgi0000644000000000000000000000003213411003760017511 0ustar rootroot adlibtracker2-2.4.24/package/instr/broguit.fin0000644000000000000000000000006213411003760017706 0ustar rootrootBROGUIT.FIN BrokGuitar Cŧò#adlibtracker2-2.4.24/package/instr/galaxy3v.sgi0000644000000000000000000000003213411003760017774 0ustar rootroot  adlibtracker2-2.4.24/package/instr/fight.sgi0000644000000000000000000000003213411003760017337 0ustar rootrootadlibtracker2-2.4.24/package/instr/piano1.sbi0000644000000000000000000000006413411003760017425 0ustar rootrootSBIpiano1.sbiOñÒStadlibtracker2-2.4.24/package/instr/syn5.sbi0000644000000000000000000000006413411003760017134 0ustar rootrootSBIsyn5.sbiOqRS|adlibtracker2-2.4.24/package/instr/marimba1.sbi0000644000000000000000000000006413411003760017727 0ustar rootrootSBImarimba1.sbiNÚù% adlibtracker2-2.4.24/package/instr/chorn.sbi0000644000000000000000000000006413411003760017347 0ustar rootrootSBIchorn.sbi!¡‹cc2 adlibtracker2-2.4.24/package/instr/ykabass1.sbi0000644000000000000000000000006413411003760017754 0ustar rootrootSBIykabass1.sbi@•ÿˆadlibtracker2-2.4.24/package/instr/trumpet4.sbi0000644000000000000000000000006413411003760020022 0ustar rootrootSBItrumpet4.sbi1¡€A’ ; adlibtracker2-2.4.24/package/instr/btgo.sbi0000644000000000000000000000006413411003760017171 0ustar rootrootSBIbtgo.sbiN@tdS|adlibtracker2-2.4.24/package/instr/xylo.cif0000644000000000000000000000006413411003760017215 0ustar rootrootNùÚ% xylo.cifadlibtracker2-2.4.24/package/instr/belpiano.sbi0000644000000000000000000000006413411003760020027 0ustar rootrootSBIbelpiano.sbiOñòRGadlibtracker2-2.4.24/package/instr/base3.sgi0000644000000000000000000000003213411003760017233 0ustar rootrootadlibtracker2-2.4.24/package/instr/tensax.sbi0000644000000000000000000000006413411003760017540 0ustar rootrootSBItensax.sbiQKqRX| adlibtracker2-2.4.24/package/instr/bdrum.sbi0000644000000000000000000000006413411003760017347 0ustar rootrootSBIbdrum ¨ÖLOadlibtracker2-2.4.24/package/instr/harpsi4.sbi0000644000000000000000000000006413411003760017610 0ustar rootrootSBIharpsi4.sbi òò± adlibtracker2-2.4.24/package/instr/chord.ins0000644000000000000000000000003313411003760017345 0ustar rootroot` ct85chord.insadlibtracker2-2.4.24/package/instr/laser.sgi0000644000000000000000000000003213411003760017344 0ustar rootroot adlibtracker2-2.4.24/package/instr/englhrn1.sbi0000644000000000000000000000006413411003760017754 0ustar rootrootSBIenglhrn1.sbiáä#q‚®ž adlibtracker2-2.4.24/package/instr/terzm.sgi0000644000000000000000000000003213411003760017377 0ustar rootrootadlibtracker2-2.4.24/package/instr/ebass.sgi0000644000000000000000000000003213411003760017333 0ustar rootroot    adlibtracker2-2.4.24/package/instr/blob.sgi0000644000000000000000000000003213411003760017154 0ustar rootrootadlibtracker2-2.4.24/package/instr/gun2.sgi0000644000000000000000000000003213411003760017111 0ustar rootrootadlibtracker2-2.4.24/package/instr/sitar.sbi0000644000000000000000000000006413411003760017360 0ustar rootrootSBIsitar.sbi@òòTEadlibtracker2-2.4.24/package/instr/rksnare1.sbi0000644000000000000000000000006413411003760017764 0ustar rootrootSBIrksnare1.sbi ÐÇp´adlibtracker2-2.4.24/package/instr/string5.cif0000644000000000000000000000006413411003760017615 0ustar rootroot(A‘üstring5.cifadlibtracker2-2.4.24/package/instr/phone1.sbi0000644000000000000000000000006413411003760017430 0ustar rootrootSBIphone1.sbiOòña²adlibtracker2-2.4.24/package/instr/leen4.cif0000644000000000000000000000006413411003760017231 0ustar rootrootbrRQleen4.cifadlibtracker2-2.4.24/package/instr/orgel.cif0000644000000000000000000000006413411003760017332 0ustar rootrootä ÿorgel.cifadlibtracker2-2.4.24/package/instr/bells.cif0000644000000000000000000000006413411003760017323 0ustar rootroot‘ÿ€!ÿbells.cifadlibtracker2-2.4.24/package/instr/koto1.sbi0000644000000000000000000000006413411003760017273 0ustar rootrootSBIkoto1.sbi@ ÷S”adlibtracker2-2.4.24/package/instr/strings2.sgi0000644000000000000000000000003213411003760020011 0ustar rootroot  adlibtracker2-2.4.24/package/instr/popbass1.sbi0000644000000000000000000000006413411003760017766 0ustar rootrootSBIpopbass1.sbiuõ“‚adlibtracker2-2.4.24/package/instr/bassdrum.fin0000644000000000000000000000006213411003760020053 0ustar rootrootBASSDRUM.FINBassdrum ¨¨Kadlibtracker2-2.4.24/package/instr/epicbell.cif0000644000000000000000000000006413411003760020001 0ustar rootroot%€ˆôû"epicbell.cifadlibtracker2-2.4.24/package/instr/bdrum1.sbi0000644000000000000000000000006413411003760017430 0ustar rootrootSBIbdrum1.sbi ¨ÖLOadlibtracker2-2.4.24/package/instr/cymbal1.sbi0000644000000000000000000000006413411003760017566 0ustar rootrootSBIcymbal1.sbiõÖµOadlibtracker2-2.4.24/package/instr/tensax3.sbi0000644000000000000000000000006413411003760017623 0ustar rootrootSBItensax3.sbiP‘RqRf‹adlibtracker2-2.4.24/package/instr/basedrum.sgi0000644000000000000000000000003213411003760020040 0ustar rootrootadlibtracker2-2.4.24/package/instr/roehr.cif0000644000000000000000000000006413411003760017341 0ustar rootrootåà—(óroehr.cifadlibtracker2-2.4.24/package/instr/bass.fin0000644000000000000000000000006213411003760017163 0ustar rootrootBASS.FIN Bass Ñ^¥“2adlibtracker2-2.4.24/package/instr/tensax4.sbi0000644000000000000000000000006413411003760017624 0ustar rootrootSBItensax4.sbiP‘’qRf‹adlibtracker2-2.4.24/package/instr/piano4.sbi0000644000000000000000000000006413411003760017430 0ustar rootrootSBIpiano4.sbiMñÒ`{adlibtracker2-2.4.24/package/instr/shppizz.sbi0000644000000000000000000000006413411003760017745 0ustar rootrootSBIshppizz.sbiâpF€ø÷óóadlibtracker2-2.4.24/package/instr/cool.sgi0000644000000000000000000000003213411003760017172 0ustar rootrootadlibtracker2-2.4.24/package/instr/bassoon.sbi0000644000000000000000000000006413411003760017702 0ustar rootrootSBIbassoon.sbi0±Í€Õa adlibtracker2-2.4.24/package/instr/hihat.sgi0000644000000000000000000000003213411003760017333 0ustar rootroot  adlibtracker2-2.4.24/package/instr/lullbass.sbi0000644000000000000000000000006413411003760020057 0ustar rootrootSBIlullbass.sbiAŽc1tadlibtracker2-2.4.24/package/instr/sunrise2.sgi0000644000000000000000000000003213411003760020010 0ustar rootroot adlibtracker2-2.4.24/package/instr/tuba1.sbi0000644000000000000000000000006413411003760017252 0ustar rootrootSBItuba1.sbi!!€C…Œ/ adlibtracker2-2.4.24/package/instr/triangle.sgi0000644000000000000000000000003213411003760020043 0ustar rootroot   adlibtracker2-2.4.24/package/instr/acid.cif0000644000000000000000000000006413411003760017122 0ustar rootrootZP‘¹ F6_acid.cifadlibtracker2-2.4.24/package/instr/water.sgi0000644000000000000000000000003213411003760017360 0ustar rootroot adlibtracker2-2.4.24/package/instr/future.sgi0000644000000000000000000000003213411003760017550 0ustar rootrootadlibtracker2-2.4.24/package/instr/harp.sbi0000644000000000000000000000006413411003760017170 0ustar rootrootSBIharp.sbi!£ÄC" adlibtracker2-2.4.24/package/instr/strings3.sgi0000644000000000000000000000003213411003760020012 0ustar rootroot  adlibtracker2-2.4.24/package/instr/eguitar.sgi0000644000000000000000000000003213411003760017676 0ustar rootrootadlibtracker2-2.4.24/package/instr/mdrnphon.sbi0000644000000000000000000000006413411003760020063 0ustar rootrootSBImdrnphon.sbi0nÀþñadlibtracker2-2.4.24/package/instr/brass2.sbi0000644000000000000000000000006413411003760017432 0ustar rootrootSBIbrass2.sbia`q®.adlibtracker2-2.4.24/package/instr/galaxi.sgi0000644000000000000000000000003213411003760017503 0ustar rootrootadlibtracker2-2.4.24/package/instr/keybrd3.sbi0000644000000000000000000000006413411003760017601 0ustar rootrootSBIkeybrd3.sbiäðóð6adlibtracker2-2.4.24/package/instr/verplant.cif0000644000000000000000000000006413411003760020055 0ustar rootroot$@Õµ…Tverplant.cifadlibtracker2-2.4.24/package/instr/alien.cif0000644000000000000000000000006413411003760017312 0ustar rootroot, þ##alien.cifadlibtracker2-2.4.24/package/instr/celguit.sbi0000644000000000000000000000006413411003760017672 0ustar rootrootSBIcelguit.sbi–ˆÿÿ! adlibtracker2-2.4.24/package/instr/flapbas.sbi0000644000000000000000000000006413411003760017646 0ustar rootrootSBIflapbas.sbi´Ãrsadlibtracker2-2.4.24/package/instr/contrab.sbi0000644000000000000000000000006413411003760017666 0ustar rootrootSBIcontrab.sbi”ƒ¶&adlibtracker2-2.4.24/package/instr/elorgan4.sgi0000644000000000000000000000003213411003760017751 0ustar rootroot    adlibtracker2-2.4.24/package/instr/harpsi2.sbi0000644000000000000000000000006413411003760017606 0ustar rootrootSBIharpsi2.sbi3‡€¡}Cadlibtracker2-2.4.24/package/instr/flute2.sbi0000644000000000000000000000006413411003760017437 0ustar rootrootSBIflute2.sbià¡ìne*adlibtracker2-2.4.24/package/instr/hammer.sgi0000644000000000000000000000003213411003760017507 0ustar rootroot  adlibtracker2-2.4.24/package/instr/trumpet1.sbi0000644000000000000000000000006413411003760020017 0ustar rootrootSBItrumpet1.sbi1¡€A’ ;adlibtracker2-2.4.24/package/instr/steelgt1.sbi0000644000000000000000000000006413411003760017766 0ustar rootrootSBIsteelgt1.sbi¡Fñ1ƒ†adlibtracker2-2.4.24/package/instr/scratch.sbi0000644000000000000000000000006413411003760017665 0ustar rootrootSBIscratch.sbið\ðÜadlibtracker2-2.4.24/package/instr/trompet.cif0000644000000000000000000000006413411003760017714 0ustar rootroot1¡A€ ’;trompet.cifadlibtracker2-2.4.24/package/instr/ultra.sgi0000644000000000000000000000003213411003760017365 0ustar rootroot  adlibtracker2-2.4.24/package/instr/harp1.sbi0000644000000000000000000000006413411003760017251 0ustar rootrootSBIharp1.sbi)ƒõòuóadlibtracker2-2.4.24/package/instr/syn2.cif0000644000000000000000000000006413411003760017115 0ustar rootrootÄá‘ÿósyn2.cifadlibtracker2-2.4.24/package/instr/coolbass.sgi0000644000000000000000000000003213411003760020043 0ustar rootrootadlibtracker2-2.4.24/package/instr/keybrd1.sbi0000644000000000000000000000006413411003760017577 0ustar rootrootSBIkeybrd1.sbi€ðòúúadlibtracker2-2.4.24/package/instr/pianof.sbi0000644000000000000000000000006413411003760017512 0ustar rootrootSBIpianof.sbiÏñòSƒadlibtracker2-2.4.24/package/instr/trumpet.sbi0000644000000000000000000000006413411003760017736 0ustar rootrootSBItrumpet1¡€A’ ;adlibtracker2-2.4.24/package/instr/bassdrm1.sgi0000644000000000000000000000003213411003760017752 0ustar rootroot  adlibtracker2-2.4.24/package/instr/organ1.sbi0000644000000000000000000000006413411003760017425 0ustar rootrootSBIorgan1.sbi¥±Ò€ñadlibtracker2-2.4.24/package/instr/logdrum1.sbi0000644000000000000000000000006413411003760017770 0ustar rootrootSBIlogdrum1.sbi2Døõÿadlibtracker2-2.4.24/package/instr/deepstri.cif0000644000000000000000000000006413411003760020041 0ustar rootrootâðÀdeepstri.cifadlibtracker2-2.4.24/package/instr/kupfer.cif0000644000000000000000000000006413411003760017516 0ustar rootrootäÄu„÷÷kupfer.cifadlibtracker2-2.4.24/package/instr/claps1.sbi0000644000000000000000000000006413411003760017421 0ustar rootrootSBIclaps1.sbiñrçÿÿadlibtracker2-2.4.24/package/instr/dungeon.sgi0000644000000000000000000000003213411003760017675 0ustar rootrootadlibtracker2-2.4.24/package/instr/base.cif0000644000000000000000000000006413411003760017134 0ustar rootrootÀàö¨øXbase.cifadlibtracker2-2.4.24/package/instr/syn6.sbi0000644000000000000000000000006413411003760017135 0ustar rootrootSBIsyn6.sbi$!Añ~^ adlibtracker2-2.4.24/package/instr/acidbas4.sgi0000644000000000000000000000003213411003760017710 0ustar rootroot adlibtracker2-2.4.24/package/instr/v42-2.sgi0000644000000000000000000000003213411003760017010 0ustar rootroot   adlibtracker2-2.4.24/package/instr/technol.sgi0000644000000000000000000000003213411003760017672 0ustar rootrootadlibtracker2-2.4.24/package/instr/long2.sgi0000644000000000000000000000003213411003760017257 0ustar rootroot   adlibtracker2-2.4.24/package/instr/bbass.sbi0000644000000000000000000000006413411003760017330 0ustar rootrootSBIbbass.sbi‘€ÿÿ! adlibtracker2-2.4.24/package/instr/kupfer2.cif0000644000000000000000000000006413411003760017600 0ustar rootrootâäöô÷÷kupfer2.cifadlibtracker2-2.4.24/package/instr/tuba2.sgi0000644000000000000000000000003213411003760017253 0ustar rootrootadlibtracker2-2.4.24/package/instr/eguitar4.sgi0000644000000000000000000000003213411003760017762 0ustar rootroot  adlibtracker2-2.4.24/package/instr/leed.cif0000644000000000000000000000006413411003760017133 0ustar rootrootò"@aAleed.cifadlibtracker2-2.4.24/package/instr/bass1.sbi0000644000000000000000000000006413411003760017247 0ustar rootrootSBIbass1.sbi!€%e/l adlibtracker2-2.4.24/package/instr/master.sgi0000644000000000000000000000003213411003760017531 0ustar rootrootadlibtracker2-2.4.24/package/instr/basemax.sgi0000644000000000000000000000003213411003760017656 0ustar rootroot adlibtracker2-2.4.24/package/instr/organ4.sbi0000644000000000000000000000006413411003760017430 0ustar rootrootSBIorgan4.sbi>±)€û ð›adlibtracker2-2.4.24/package/instr/bassoon1.sbi0000644000000000000000000000006413411003760017763 0ustar rootrootSBIbassoon1.sbi0±È€Õa adlibtracker2-2.4.24/package/instr/eguhigh.sgi0000644000000000000000000000003213411003760017656 0ustar rootroot adlibtracker2-2.4.24/package/instr/flute.sbi0000644000000000000000000000006413411003760017355 0ustar rootrootSBIflute.sbiáa'€SSŠWadlibtracker2-2.4.24/package/instr/woodbloc.fin0000644000000000000000000000006213411003760020043 0ustar rootrootWOODBLOC.FINWoodblock :QÎø†öadlibtracker2-2.4.24/package/instr/cymbal.sbi0000644000000000000000000000006413411003760017505 0ustar rootrootSBIcymbal.sbid@²—¢Ôadlibtracker2-2.4.24/package/instr/epiano1b.sbi0000644000000000000000000000006413411003760017734 0ustar rootrootSBIepiano1b.sbiWõõúúadlibtracker2-2.4.24/package/instr/saxafone.sbi0000644000000000000000000000006413411003760020042 0ustar rootrootSBIsaxafone.sbiQRS| adlibtracker2-2.4.24/package/instr/viol.sgi0000644000000000000000000000003213411003760017207 0ustar rootroot adlibtracker2-2.4.24/package/instr/banjo.sbi0000644000000000000000000000006413411003760017327 0ustar rootrootSBIbanjo.sbi1‡€¡}Cadlibtracker2-2.4.24/package/instr/trainbel.sbi0000644000000000000000000000006413411003760020036 0ustar rootrootSBItrainbel.sbiOòòatadlibtracker2-2.4.24/package/instr/claves.sbi0000644000000000000000000000006413411003760017513 0ustar rootrootSBIclaves.sbi€ûèÿÿ adlibtracker2-2.4.24/package/instr/harpsi5.sbi0000644000000000000000000000006413411003760017611 0ustar rootrootSBIharpsi5.sbi6‡€Š3adlibtracker2-2.4.24/package/instr/oboe.sbi0000644000000000000000000000006413411003760017162 0ustar rootrootSBIoboe.sbiqbÅn‹adlibtracker2-2.4.24/package/instr/pipes.sbi0000644000000000000000000000006413411003760017356 0ustar rootrootSBIpipes.sbi¥±Ò€ñadlibtracker2-2.4.24/package/instr/notbig.sbi0000644000000000000000000000006413411003760017520 0ustar rootrootSBInotbig.sbi°µ5Žû ð›adlibtracker2-2.4.24/package/instr/clar2.sbi0000644000000000000000000000006413411003760017241 0ustar rootrootSBIclar2.sbi1 €AB; adlibtracker2-2.4.24/package/instr/fstrp2.sbi0000644000000000000000000000006413411003760017456 0ustar rootrootSBIfstrp2.sbi°à€U‡/ adlibtracker2-2.4.24/package/instr/mars.sbi0000644000000000000000000000006413411003760017200 0ustar rootrootSBImars.sbiÅÙO1BSradlibtracker2-2.4.24/package/instr/$gmopl.ibk0000644000000000000000000000620413411003760017412 0ustar rootrootIBKòòô÷8Kòòô÷8Iòòôö8Aòò÷÷6Wñò÷÷0“ñò÷÷0€¡òòõ8’ÂÂøø: \öóôõ0—€óòòñ2!Tôôô2˜bóòöö0#öçö÷0‘öööö4EY€Ó£óó<I€uµõõ4q1’öñ2r0ÇÇX2p±DªŠ4#±“—U#4a±€—U0$±H˜F*<a!‘a:!¡‰qa6Aœ€óó”È<Tóñšç<#!_ñò:ø0!‡€öó"ø6!GùöT:0#!J‘„A8#!J•”8 „¡€ ÑOø8!¢”æ211ññ(:11ññèx:12[Qq(H<!‹@¡òšß8!!‹¢¡ß811‹ôñèx:11ññ(:1!ÝV&81!Ýf8q1IÑa 8!#M€qr2ñá@ño!2€õ…u50€õóuô0AõòÃ2!¢›±r%>¡!˜?0¡a“ÁO:!aÁO"<1r[ƒôŠ0¡atq9g0qrWTz<AT¥cE8!!’… <!!”u <!a”v‚7<1!Cžb,2!!›aj 2a"Šut8¡!†ƒrqU0!!MT¦<81a“r 81aŽ“r 81a‘“‚ :1aŽ“r:!!Kª 81!~‹ 612ua02!›r!4áá…e_0ááFˆe_0¡!œuu 21!‹„eX0á¡LfeV&0b¡ËvUF60b¡™WV;b¡“wv;"!Yÿÿ0!!ÿÿ0"!F€†dU0!¡Ef– 0!"‹’‘**0¢až@ßo2 `ï0!!€ñô) :w¡¥S ”2a±€¨%:aa‘U4<qr]Tj0!¢—!BC58¡!¡1wG0!a‰B3%:¡!ÏG0:QÎø†ö2!!!A#0[t¥•r0"a’ƒ±ò&<ABMñòQõ0a£”€Q6a¡Œ€16¤aLós#4…ÒòSö0 €£¢å0öòAæ4“‘‘Ôë28OúÂV<!"I|o 61!…ÝV3: !Ú 6j€ñÃåå6ìø&:gß58–úø(å:†¨ú6AøóG4Žñó>Àÿ>€ˆøV$„>Ðø4>Àö>ÕÚ•@7V£705\²ôa:ÐöOõ>&äÿ>óöðÉ>ACGPIANOACPIANO"ELGPIANOHONKTONKELPIANO1ELPIANO2HARPSCHDCLAVICHDCELESTAGLOCKMUSICBOXVIBES P MARIMBAXYLOPHONTUBEBELLPIANOBELBARORGANPRCORGANROCKORGNPIPEORGNREEDORGNACCORDNHARMNICATANGONYLONACOUSTJAZZGTRELGUITARELGMUTEOVERDRIVHVYMETALGUITHARMACOUBASSELECBASSPICKBASSFRETLESSSLAPBASSWRDBASSSYNBASS1SYNBASS2VIOLINVIOLACELLODBLBASS©STRINGS1PIZZHARPVTIMPANIEXCELSTRSTRSECT©SYNSTR1èSYNSTR2©AAHSÒOOHSÒVOXSYNTHORCHHITSTRUMPET1TROMB1TUBA3SOFTRUMPFRHORN1BRASSECTSYNBRASSBRASSOFTSOPRANO©ALTOSAXTENORSAXBARISAXOBOEENGLHORNBASSOONCLARINETPICCOLOFLUTERECORDERPANPIPESBOTTLE ´SHAKAHU©WHISTLEWOODLEAD1LEAD2LEAD3LEAD4LEAD5WUZZLE1ELEAD7SYNBASS1NEWAGE"WARMPADÒPAD3PAD4PAD5PAD6PAD7PAD8FX1/FX2FX3FX4FX5FX6FX7FX8SITARBANJOSHAMISENKOTOKALIMBABAGPIPEFIDDLEETHNICHANDBELLAGOGOSTEELDRMWOODBLOCTAIDRUMMELDRUMSYNSNARREVCYMBCHICKENBREATHSEASHOREINSECTSOINKEYHELICPTRCROWDSHOTadlibtracker2-2.4.24/package/instr/hack.cif0000644000000000000000000000006413411003760017130 0ustar rootrootòâõ¯öòhack.cifadlibtracker2-2.4.24/package/instr/synth.ins0000644000000000000000000000001413411003760017412 0ustar rootrootAÂCòÿÿadlibtracker2-2.4.24/package/instr/elclav2.sbi0000644000000000000000000000006413411003760017566 0ustar rootrootSBIelclav2.sbiIññStadlibtracker2-2.4.24/package/instr/bsynth.sbi0000644000000000000000000000006413411003760017545 0ustar rootrootSBIbsynth.sbiŠ@ññ³adlibtracker2-2.4.24/package/instr/jungle.sgi0000644000000000000000000000003213411003760017522 0ustar rootroot  adlibtracker2-2.4.24/package/instr/strings1.sbi0000644000000000000000000000006413411003760020010 0ustar rootrootSBIstrings1.sbiq¡‹@qBadlibtracker2-2.4.24/package/instr/meri.sbi0000644000000000000000000000006413411003760017172 0ustar rootrootSBImeri.sbit@Áöadlibtracker2-2.4.24/package/instr/deadbass.cif0000644000000000000000000000006413411003760017770 0ustar rootrootÒÀóøõdeadbass.cifadlibtracker2-2.4.24/package/instr/bass5.fin0000644000000000000000000000006213411003760017250 0ustar rootrootBASS5.FIN Bass ÿÿadlibtracker2-2.4.24/package/instr/knarbass.cif0000644000000000000000000000006413411003760020026 0ustar rootrootââ òñöòknarbass.cifadlibtracker2-2.4.24/package/instr/bassnew.fin0000644000000000000000000000006213411003760017675 0ustar rootrootBASSNEW.FIN Bass new Áóó÷adlibtracker2-2.4.24/package/instr/violin.ins0000644000000000000000000000001413411003760017545 0ustar rootrootBâdA^ÿadlibtracker2-2.4.24/package/instr/elorgan1.sbi0000644000000000000000000000006413411003760017746 0ustar rootrootSBIelorgan1.sbirqÍ€‘‘**adlibtracker2-2.4.24/package/instr/powersn.sgi0000644000000000000000000000003213411003760017733 0ustar rootrootadlibtracker2-2.4.24/package/instr/marimba.sbi0000644000000000000000000000006413411003760017646 0ustar rootrootSBImarimba.sbiNÚù% adlibtracker2-2.4.24/package/instr/altovio2.sbi0000644000000000000000000000006413411003760017775 0ustar rootrootSBIaltovio2ðñЀR1þadlibtracker2-2.4.24/package/instr/aalto.sbi0000644000000000000000000000006413411003760017336 0ustar rootrootSBIaaltoð€ ¢¤adlibtracker2-2.4.24/package/instr/briss4.sgi0000644000000000000000000000003213411003760017444 0ustar rootroot adlibtracker2-2.4.24/package/instr/bass6.cif0000644000000000000000000000006413411003760017240 0ustar rootrootäâ÷¤ööbass6.cifadlibtracker2-2.4.24/package/instr/cool.cif0000644000000000000000000000006413411003760017156 0ustar rootrootââô¤ööcool.cifadlibtracker2-2.4.24/package/instr/steelgt2.sbi0000644000000000000000000000006413411003760017767 0ustar rootrootSBIsteelgt2.sbi¡Gñ‘ƒ†adlibtracker2-2.4.24/package/instr/$mt32.ibk0000644000000000000000000000620413411003760017061 0ustar rootrootIBKPñÒPvPñÒPvKñÒPvPñÒPv2’‹ÿÿ 4’ ÿÿ 4’ ÿÿ SQN ñÒ†(!Ï øÀåÿâáÊ øÀå,¡Ô ùÀÿÿ+!Ê øÀåÿ)!Í ðà‘†$!Ð ðà†#!È ðà†daÉ °ð†3…‹¡r#1…‹¡s31‹¡Â0tŠ‹ðô{{Š€ðô{{#Š€òô{{2€‹r32€‹s31! s€Žž0! s€~ž1!”3 s—1!” Ó s—12E ñòS' òò¶ òò¶ þò½áM úñññ@ º$1aá§‹rPŽáM 2Qã1À‹A1!‹õóU3áM úñññC 1øäL‚ð—ò@ ÑQSqñ! wñá 2ñsqH ññSqaKqr×ÒO òña² ððÿø 1a‹ A"1a‹ ÿD! 1a‹ A2q! ýçÖq! QTgq! QTq! TSIqaV QTq! QT)‹õòuó)‹ðôu3I ññSt‰ ññSt‰ ññSt€ ññSt@KññSS!!‹ÓÃ,, !‹ÔÄòŠ N ðô{ÈD ðó««S ôñÈ»S òòÈÅ!! ´”L¬ !! ”d¬ !¡‹w`*!¡‹w`¿*¡â‹Ö`¯*¢â‹•`$*2aš‹Q`9 ¤â‹ô`0*!! cc 1! cc !! cc ! cc 2a‹‚` 2á‹Qb6 1"à ‡‹q"ÃŽ‹p" nk$1O òR1a dÐg1a aÒ6 1a 1P6 1a A 6 !!š‹S V!!š‹S Va! S X a! s W !! q¡¦–…¡‘ õðDEaQ õð3%Œ€ÿÿ!8±Œ@óõ 3‡"‘ õðUT³J ¶Ñ21ÂþöðµN€Úð @ ÷S”°×Ä‹¤@Bàaìne*055 õðð›õöš€ `Ç¥ S…?_ â[€P %€ðÐØØ––  ôö FŠKññ³@ ÑòSV2Døõÿ@ ÷S”€€__ P òòpr@ öS”‘R ¨ÖLO  å][ú1‡€¡}E0ôôI3 $1TUPý-ACOUPNO1ACOUPNO2ACOUPNO3ELECPNO1ELECPNO2ELECPNO3ELECPNO4HONKTONKELECORG1ELECORG2ELECORG3ELECORG4PIPEORG1PIPEORG2PIPEORG3ACCORDN HARPSI1 HARPSI2 HARPSI3 CLAVI1P CLAVI2P CLAVI3P CELESTA1CELESTA2SYNBRSS1SYNBRSS2SYNBRSS3SYNBRSS4SYNBASS1SYNBASS2SYNBASS3SYNBASS4FANTASY HARMOPANCHORALE GLASSES SOUNDTRKATMOSPHRWARMBELLFUNNYVOXECHOBELLICERAIN OBOE2001ECHOPAN DOCSOLO SCHLDAZEBELLSINGSQWAVEP STRSECT1STRSECT2STRSECT3PIZZICTOVIOLIN1 VIOLIN2 CELLO1P CELLO2P CONTRABSHARP1 P HARP2 P GUITAR1 GUITAR2 ELECGTR1ELECGTR2SITAR P ACOUBS1 ACOUBS2 ELECBS1 ELECBS2 SLAPBS1 SLAPBS2 FRETLS1 FRETLS2 FLUTE1P FLUTE2P PICCOLO1PICCOLO2RECORDERPANPIPESSAX1P P SAX2P P SAX3P P SAX4P P CLARINT1CLARINT2OBOEP P ENGHORN BASSOON HARMONCATRUMPET1TRUMPET2TROMBON1TROMBON2FRHORN1 FRHORN2 TUBAP P BRSSECT1BRSSECT2VIBES1P VIBES2P SYNMALLTWINDBELLGLOCK P TUBEBELLXYLOPHONMARIMBA KOTOP P SHO P P SHAKUHCHWHISTLE1WHISTLE2BOTTLBLOBREATHPPTIMPANI MELODTOMDEEPSNAROBERHEIMNOISE P TAIKO P TAIKORIMREVCYMB JAWHARP TRIANGLEORCHEHITBASSDRM BIRDTWT BANJO P MOOGSYN JUNGLTUNadlibtracker2-2.4.24/package/instr/xylo1.sbi0000644000000000000000000000006413411003760017312 0ustar rootrootSBIxylo11-Èõ/õ adlibtracker2-2.4.24/package/instr/fantapan.sbi0000644000000000000000000000006413411003760020026 0ustar rootrootSBIfantapan.sbitׇ€¤EBadlibtracker2-2.4.24/package/instr/deepdapb.cif0000644000000000000000000000006413411003760017766 0ustar rootrootÄÂööÿÿdeepdapb.cifadlibtracker2-2.4.24/package/instr/hihat2.cif0000644000000000000000000000006413411003760017401 0ustar rootrootÇvñôôhihat2.cifadlibtracker2-2.4.24/package/instr/altoviol.sbi0000644000000000000000000000006413411003760020067 0ustar rootrootSBIaltoviol.sbipqЀR1þadlibtracker2-2.4.24/package/instr/elguitar.sbi0000644000000000000000000000006413411003760020052 0ustar rootrootSBIelguitar.sbi2‡€¡}3adlibtracker2-2.4.24/package/instr/pian1a.sbi0000644000000000000000000000006413411003760017407 0ustar rootrootSBIpian1a.sbiAc€óòXXadlibtracker2-2.4.24/package/instr/helicptr.sbi0000644000000000000000000000006413411003760020050 0ustar rootrootSBIhelicptr.sbiðâÀadlibtracker2-2.4.24/package/instr/violin3.sbi0000644000000000000000000000006413411003760017621 0ustar rootrootSBIviolin3.sbiá"ˆƒdS),adlibtracker2-2.4.24/package/instr/luola.sbi0000644000000000000000000000006413411003760017352 0ustar rootrootSBIluola.sbiÊÌ„ðYðb adlibtracker2-2.4.24/package/instr/dot2.sgi0000644000000000000000000000003213411003760017106 0ustar rootroot adlibtracker2-2.4.24/package/instr/popcorn.sbi0000644000000000000000000000006413411003760017716 0ustar rootrootSBIpopcorn.sbi¹zL~o?ÿÿadlibtracker2-2.4.24/package/instr/eklavie.cif0000644000000000000000000000006413411003760017642 0ustar rootrootèâõ¤öö eklavie.cifadlibtracker2-2.4.24/package/instr/3klang1.sgi0000644000000000000000000000003213411003760017476 0ustar rootrootadlibtracker2-2.4.24/package/instr/cstacc.sbi0000644000000000000000000000006413411003760017476 0ustar rootrootSBIcstacc.sbi"òöu˜adlibtracker2-2.4.24/package/instr/epiano.sbi0000644000000000000000000000006413411003760017511 0ustar rootrootSBIepiano.sbiA£¢"adlibtracker2-2.4.24/package/instr/powerbas.sgi0000644000000000000000000000003213411003760020060 0ustar rootrootadlibtracker2-2.4.24/package/instr/dshrtbas.cif0000644000000000000000000000006413411003760020034 0ustar rootrootäâ÷¤öödshrtbas.cifadlibtracker2-2.4.24/package/instr/keybrd2.sbi0000644000000000000000000000006413411003760017600 0ustar rootrootSBIkeybrd2.sbi€ò‚½½adlibtracker2-2.4.24/package/instr/xylo2.sbi0000644000000000000000000000006413411003760017313 0ustar rootrootSBIxylo3.sbiÄÿøðµadlibtracker2-2.4.24/package/instr/violin2.sbi0000644000000000000000000000006413411003760017620 0ustar rootrootSBIviolin2.sbiá"ˆ€bS), adlibtracker2-2.4.24/package/instr/strom2.sgi0000644000000000000000000000003213411003760017464 0ustar rootrootadlibtracker2-2.4.24/package/instr/wamm.cif0000644000000000000000000000006413411003760017163 0ustar rootrootâ ññö÷ wamm.cifadlibtracker2-2.4.24/package/instr/atari.sgi0000644000000000000000000000003213411003760017336 0ustar rootrootadlibtracker2-2.4.24/package/instr/guit2.fin0000644000000000000000000000006213411003760017265 0ustar rootrootGUIT2.FIN Guitarko AQõóÿ adlibtracker2-2.4.24/package/instr/bassdrum.sgi0000644000000000000000000000003213411003760020056 0ustar rootroot adlibtracker2-2.4.24/package/instr/string0.cif0000644000000000000000000000006413411003760017610 0ustar rootrootòò 2ó#string0.cifadlibtracker2-2.4.24/package/instr/jewsharp.sbi0000644000000000000000000000006413411003760020061 0ustar rootrootSBIjewsharp.sbiPòòpradlibtracker2-2.4.24/package/instr/highlow.sgi0000644000000000000000000000003213411003760017677 0ustar rootrootadlibtracker2-2.4.24/package/instr/3klang2.sgi0000644000000000000000000000003213411003760017477 0ustar rootrootadlibtracker2-2.4.24/package/instr/snare2.cif0000644000000000000000000000006413411003760017414 0ustar rootrootdA—²Ô¢snare2.cifadlibtracker2-2.4.24/package/instr/elpiano2.sbi0000644000000000000000000000006413411003760017747 0ustar rootrootSBIelpiano2.sbi"òõCadlibtracker2-2.4.24/package/instr/harpsi1.sbi0000644000000000000000000000006413411003760017605 0ustar rootrootSBIharpsi1.sbi2‡€¡}3adlibtracker2-2.4.24/package/instr/pling.cif0000644000000000000000000000006413411003760017333 0ustar rootroot€èûÿÿ pling.cifadlibtracker2-2.4.24/package/instr/javaican.sbi0000644000000000000000000000006413411003760020012 0ustar rootrootSBIjavaican.sbiJVM€x…BT adlibtracker2-2.4.24/package/instr/piffclap.sgi0000644000000000000000000000003213411003760020022 0ustar rootrootadlibtracker2-2.4.24/package/instr/hihat2.sgi0000644000000000000000000000003213411003760017415 0ustar rootroot  adlibtracker2-2.4.24/package/instr/solovln.sbi0000644000000000000000000000006413411003760017732 0ustar rootrootSBIsolovln.sbi° QTgadlibtracker2-2.4.24/package/instr/harpe1.sbi0000644000000000000000000000006413411003760017416 0ustar rootrootSBIharpe1.sbi)õòuóadlibtracker2-2.4.24/package/instr/tom2.sbi0000644000000000000000000000006413411003760017117 0ustar rootrootSBItom2.sbi0Èà—@adlibtracker2-2.4.24/package/instr/brush2.sbi0000644000000000000000000000006413411003760017443 0ustar rootrootSBIbrush2.sbiÞ~€Á‡‘çadlibtracker2-2.4.24/package/instr/hihat.ins0000644000000000000000000000001413411003760017342 0ustar rootroot vððadlibtracker2-2.4.24/package/instr/string3.cif0000644000000000000000000000006413411003760017613 0ustar rootroot(A‘üstring3.cifadlibtracker2-2.4.24/package/instr/warp.sgi0000644000000000000000000000003213411003760017207 0ustar rootroot  adlibtracker2-2.4.24/package/instr/blip.cif0000644000000000000000000000006413411003760017150 0ustar rootrootÄÈ÷–a blip.cifadlibtracker2-2.4.24/package/instr/piano3.sbi0000644000000000000000000000006413411003760017427 0ustar rootrootSBIpiano3.sbiOñÒP|adlibtracker2-2.4.24/package/instr/base2.cif0000644000000000000000000000006413411003760017216 0ustar rootroot Ö¨OLbase2.cifadlibtracker2-2.4.24/package/instr/whistle.cif0000644000000000000000000000006413411003760017701 0ustar rootroot ‰ whistle.cifadlibtracker2-2.4.24/package/instr/vibra1.sbi0000644000000000000000000000006413411003760017422 0ustar rootrootSBIvibra1.sbiD`S€õý3%adlibtracker2-2.4.24/package/instr/fupp.cif0000644000000000000000000000006413411003760017174 0ustar rootrootr7HYÿÿfupp.cifadlibtracker2-2.4.24/package/instr/cviolin.sbi0000644000000000000000000000006413411003760017701 0ustar rootrootSBIcviolin.sbirbQRadlibtracker2-2.4.24/package/instr/sunrise4.sgi0000644000000000000000000000003213411003760020012 0ustar rootrootadlibtracker2-2.4.24/package/instr/funnybas.sbi0000644000000000000000000000006413411003760020063 0ustar rootrootSBIfunnybas.sbi K{Åradlibtracker2-2.4.24/package/instr/st1.sbi0000644000000000000000000000006413411003760016745 0ustar rootrootSBIst1.sbi´Ùadlibtracker2-2.4.24/package/instr/hihathi.sgi0000644000000000000000000000003213411003760017654 0ustar rootroot  adlibtracker2-2.4.24/package/instr/bdrum.ins0000644000000000000000000000001413411003760017356 0ustar rootrootàÀ¨öXøadlibtracker2-2.4.24/package/instr/bass3.cif0000644000000000000000000000006413411003760017235 0ustar rootrootÁáõ¡õõbass3.cifadlibtracker2-2.4.24/package/instr/topcbl2.sgi0000644000000000000000000000003213411003760017603 0ustar rootroot   adlibtracker2-2.4.24/package/instr/snare7.sbi0000644000000000000000000000006413411003760017435 0ustar rootrootSBIsnare7.sbi$@µÕT…adlibtracker2-2.4.24/package/instr/koto.sgi0000644000000000000000000000003213411003760017212 0ustar rootroot  adlibtracker2-2.4.24/package/instr/vibra2.sbi0000644000000000000000000000006413411003760017423 0ustar rootrootSBIvibra2.sbiAsöòT³adlibtracker2-2.4.24/package/instr/logdrum.sgi0000644000000000000000000000003213411003760017707 0ustar rootrootadlibtracker2-2.4.24/package/instr/banjo1.sbi0000644000000000000000000000006413411003760017410 0ustar rootrootSBIbanjo11‡¡}Cadlibtracker2-2.4.24/package/instr/marimba.sgi0000644000000000000000000000003213411003760017646 0ustar rootroot adlibtracker2-2.4.24/package/instr/fstrp1.sbi0000644000000000000000000000006413411003760017455 0ustar rootrootSBIfstrp1.sbiðà€U‡ïadlibtracker2-2.4.24/package/instr/basdr3.sbi0000644000000000000000000000006413411003760017414 0ustar rootrootSBIbasdr3.sbiA@ªú' adlibtracker2-2.4.24/package/instr/gun.sgi0000644000000000000000000000003213411003760017027 0ustar rootrootadlibtracker2-2.4.24/package/instr/contra2.sbi0000644000000000000000000000006413411003760017606 0ustar rootrootSBIcontra2.sbi”ƒ¶&adlibtracker2-2.4.24/package/instr/dragbass.sgi0000644000000000000000000000003213411003760020024 0ustar rootrootadlibtracker2-2.4.24/package/instr/strnlong.sbi0000644000000000000000000000006413411003760020104 0ustar rootrootSBIstrnlong.sbiá!O±Ótadlibtracker2-2.4.24/package/instr/sax1.sbi0000644000000000000000000000006413411003760017112 0ustar rootrootSBIsax1.sbiOqRS| adlibtracker2-2.4.24/package/instr/space.cif0000644000000000000000000000006413411003760017315 0ustar rootroot#!‘#[xÈ2space.cifadlibtracker2-2.4.24/package/instr/hardsynt.cif0000644000000000000000000000006413411003760020056 0ustar rootroot@@ññSShardsynt.cifadlibtracker2-2.4.24/package/instr/violin.sbi0000644000000000000000000000006413411003760017536 0ustar rootrootSBIviolin.sbirbQRadlibtracker2-2.4.24/package/instr/shaker.cif0000644000000000000000000000006413411003760017477 0ustar rootrootÍÌYðlðshaker.cifadlibtracker2-2.4.24/package/instr/oboe1.sbi0000644000000000000000000000006413411003760017243 0ustar rootrootSBIoboe1.sbiq"Ån‹adlibtracker2-2.4.24/package/instr/gpb.sgi0000644000000000000000000000003213411003760017006 0ustar rootroot  adlibtracker2-2.4.24/package/instr/sitar2.sbi0000644000000000000000000000006413411003760017442 0ustar rootrootSBIsitar2.sbi@@ññSSadlibtracker2-2.4.24/package/instr/elecfl.sbi0000644000000000000000000000006413411003760017470 0ustar rootrootSBIelecfl.sbià¡mWg}adlibtracker2-2.4.24/package/instr/seashore.sbi0000644000000000000000000000006413411003760020047 0ustar rootrootSBIseashore.sbi bTog>ÿÿadlibtracker2-2.4.24/package/instr/drum4.ins0000644000000000000000000000003313411003760017301 0ustar rootroot éödrum4.insadlibtracker2-2.4.24/package/instr/mltrdrum.sbi0000644000000000000000000000006413411003760020104 0ustar rootrootSBImltrdrum.sbi åÈ;¶Úadlibtracker2-2.4.24/package/instr/strloop.fin0000644000000000000000000000006213411003760017735 0ustar rootrootSTRLOOP.FIN Strongloop a Só/"adlibtracker2-2.4.24/package/instr/shaker.sbi0000644000000000000000000000006413411003760017513 0ustar rootrootSBIshaker.sbi€ûèÿÿ adlibtracker2-2.4.24/package/instr/piano2.sbi0000644000000000000000000000006413411003760017426 0ustar rootrootSBIpiano2.sbiòòQñadlibtracker2-2.4.24/package/instr/bguit.sbi0000644000000000000000000000006413411003760017350 0ustar rootrootSBIbguit.sbi!£ÄT2 adlibtracker2-2.4.24/package/instr/key2.sgi0000644000000000000000000000003213411003760017110 0ustar rootrootadlibtracker2-2.4.24/package/instr/guitar1.sbi0000644000000000000000000000006413411003760017612 0ustar rootrootSBIguitar1.sbiòõˆ adlibtracker2-2.4.24/package/instr/accordn.sbi0000644000000000000000000000006413411003760017647 0ustar rootrootSBIaccordn.sbi$1OòR adlibtracker2-2.4.24/package/instr/syn2.sbi0000644000000000000000000000006413411003760017131 0ustar rootrootSBIsyn2.sbi—€š›adlibtracker2-2.4.24/package/instr/bell.sgi0000644000000000000000000000003213411003760017154 0ustar rootroot adlibtracker2-2.4.24/package/instr/phone2.sbi0000644000000000000000000000006413411003760017431 0ustar rootrootSBIphone2.sbiO òña´adlibtracker2-2.4.24/package/instr/flute1.sbi0000644000000000000000000000006413411003760017436 0ustar rootrootSBIflute1.sbiaa'€te*adlibtracker2-2.4.24/package/instr/clar1.sbi0000644000000000000000000000006413411003760017240 0ustar rootrootSBIclar1.sbi2!€su$Wadlibtracker2-2.4.24/package/instr/belguit2.sbi0000644000000000000000000000006413411003760017753 0ustar rootrootSBIbelguit2.sbi”€ÿÿ! adlibtracker2-2.4.24/package/instr/asbass.fin0000644000000000000000000000006213411003760017507 0ustar rootrootASBASS.FIN AsBass @¤¤¡adlibtracker2-2.4.24/package/instr/techno.sgi0000644000000000000000000000003213411003760017516 0ustar rootrootadlibtracker2-2.4.24/package/instr/synbass1.sbi0000644000000000000000000000006413411003760020001 0ustar rootrootSBIsynbass1.sbi0±ˆ€Õa adlibtracker2-2.4.24/package/instr/alien.sbi0000644000000000000000000000006413411003760017326 0ustar rootrootSBIalien.sbiõÓOòó@Badlibtracker2-2.4.24/package/instr/modacid.sgi0000644000000000000000000000003213411003760017636 0ustar rootrootadlibtracker2-2.4.24/package/instr/snare.ins0000644000000000000000000000001413411003760017355 0ustar rootrootÏàÅðö„øadlibtracker2-2.4.24/package/instr/leed3.cif0000644000000000000000000000006413411003760017216 0ustar rootrootHŠññ³leed3.cifadlibtracker2-2.4.24/package/instr/alien2.sbi0000644000000000000000000000006413411003760017410 0ustar rootrootSBIalien2õÓOòó@Badlibtracker2-2.4.24/package/instr/drum1.ins0000644000000000000000000000003313411003760017276 0ustar rootroot éê(*drum1.insadlibtracker2-2.4.24/package/instr/tech2.sgi0000644000000000000000000000003213411003760017243 0ustar rootroot adlibtracker2-2.4.24/package/instr/dipp2.cif0000644000000000000000000000006413411003760017240 0ustar rootrootââXöòõô dipp2.cifadlibtracker2-2.4.24/package/instr/bell#2.ins0000644000000000000000000000001413411003760017310 0ustar rootrootaâõõòô adlibtracker2-2.4.24/package/instr/sdrum2.sbi0000644000000000000000000000006413411003760017452 0ustar rootrootSBIsdrum2.sbiðöð´adlibtracker2-2.4.24/package/instr/scratch4.sbi0000644000000000000000000000006413411003760017751 0ustar rootrootSBIscratch4ð\ðÜadlibtracker2-2.4.24/package/instr/crystal.sbi0000644000000000000000000000006413411003760017717 0ustar rootrootSBIcrystal.sbi×ÑMAóóÅäo?ÿÿadlibtracker2-2.4.24/package/instr/tom2.cif0000644000000000000000000000006413411003760017103 0ustar rootroot2Dõøÿtom2.cifadlibtracker2-2.4.24/package/instr/jazzguit.sbi0000644000000000000000000000006413411003760020105 0ustar rootrootSBIjazzguit.sbi^…ÒQqadlibtracker2-2.4.24/package/instr/jungdrum.sgi0000644000000000000000000000003213411003760020071 0ustar rootrootadlibtracker2-2.4.24/package/instr/drum3.ins0000644000000000000000000000003313411003760017300 0ustar rootroot éödrum3.insadlibtracker2-2.4.24/package/instr/bellsngr.sgi0000644000000000000000000000003213411003760020046 0ustar rootroot  adlibtracker2-2.4.24/package/instr/bstacc.sbi0000644000000000000000000000006413411003760017475 0ustar rootrootSBIbstacc.sbiMóôV|adlibtracker2-2.4.24/package/instr/deepbell.cif0000644000000000000000000000006413411003760017776 0ustar rootroot.‘¿Bdeepbell.cifadlibtracker2-2.4.24/package/instr/cello.sbi0000644000000000000000000000006413411003760017334 0ustar rootrootSBIcello.sbipqÅ€R1þadlibtracker2-2.4.24/package/instr/piano.sgi0000644000000000000000000000003213411003760017344 0ustar rootrootadlibtracker2-2.4.24/package/instr/zong.cif0000644000000000000000000000006413411003760017177 0ustar rootrootG@ÿÿzong.cifadlibtracker2-2.4.24/package/instr/marimba2.sbi0000644000000000000000000000006413411003760017730 0ustar rootrootSBImarimba2.sbiEAN€Úù adlibtracker2-2.4.24/package/instr/hihat.cif0000644000000000000000000000006413411003760017317 0ustar rootrootàÏÀ—ðô„hihat.cifadlibtracker2-2.4.24/package/instr/basemed.sgi0000644000000000000000000000003213411003760017636 0ustar rootrootadlibtracker2-2.4.24/package/instr/sitar1.sbi0000644000000000000000000000006413411003760017441 0ustar rootrootSBIsitar1.sbi@@ññSSadlibtracker2-2.4.24/package/instr/jet.cif0000644000000000000000000000006413411003760017004 0ustar rootroot $jet.cifadlibtracker2-2.4.24/package/instr/drum5.ins0000644000000000000000000000003313411003760017302 0ustar rootrootéödrum5.insadlibtracker2-2.4.24/package/instr/vlnpizz1.sbi0000644000000000000000000000006413411003760020033 0ustar rootrootSBIvlnpizz1.sbi11œ€ñ÷ùæadlibtracker2-2.4.24/package/instr/xylo3.sbi0000644000000000000000000000006413411003760017314 0ustar rootrootSBIxylo3Äÿøðµadlibtracker2-2.4.24/package/instr/horn.cif0000644000000000000000000000006413411003760017170 0ustar rootroota1€’A; horn.cifadlibtracker2-2.4.24/package/instr/briss5.sgi0000644000000000000000000000003213411003760017445 0ustar rootroot adlibtracker2-2.4.24/package/instr/cromorne.sbi0000644000000000000000000000006413411003760020062 0ustar rootrootSBIcromorne.sbi€ððÿÿadlibtracker2-2.4.24/package/instr/synsnr2.sbi0000644000000000000000000000006413411003760017654 0ustar rootrootSBIsynsnr2.sbiðöð´adlibtracker2-2.4.24/package/instr/violin1.sbi0000644000000000000000000000006413411003760017617 0ustar rootrootSBIviolin1.sbi1¡€QTgadlibtracker2-2.4.24/package/instr/snakefl.sbi0000644000000000000000000000006413411003760017661 0ustar rootrootSBIsnakefl.sbi¡± €a adlibtracker2-2.4.24/package/instr/piano.sbi0000644000000000000000000000006413411003760017344 0ustar rootrootSBIpiano.sbi!Lñòcradlibtracker2-2.4.24/package/instr/jazzbass.sbi0000644000000000000000000000006413411003760020065 0ustar rootrootSBIjazzbass.sbi !@{õr adlibtracker2-2.4.24/package/instr/astring.sbi0000644000000000000000000000006413411003760017705 0ustar rootrootSBIastring.sbi"!öû'adlibtracker2-2.4.24/package/instr/fuzguit1.sbi0000644000000000000000000000006413411003760020014 0ustar rootrootSBIfuzguit1.sbiñ% —ñ adlibtracker2-2.4.24/package/instr/synbal2.sbi0000644000000000000000000000006413411003760017610 0ustar rootrootSBIsynbal2.sbi(àèðadlibtracker2-2.4.24/package/instr/bass295.fin0000644000000000000000000000006213411003760017423 0ustar rootrootBASS295.FIN Bass 295 ÐÈ„£òadlibtracker2-2.4.24/package/instr/sftbrss1.sbi0000644000000000000000000000006413411003760020005 0ustar rootrootSBIsftbrss1.sbiááq®ž adlibtracker2-2.4.24/package/instr/geige.sgi0000644000000000000000000000003213411003760017316 0ustar rootrootadlibtracker2-2.4.24/package/instr/harmonca.sbi0000644000000000000000000000006413411003760020026 0ustar rootrootSBIharmonca.sbi"ò@Aaadlibtracker2-2.4.24/package/instr/strom.sgi0000644000000000000000000000003213411003760017402 0ustar rootroot  adlibtracker2-2.4.24/package/instr/clarinet.sbi0000644000000000000000000000006413411003760020037 0ustar rootrootSBIclarinet.sbi2¡€Q‚E adlibtracker2-2.4.24/package/instr/syn3.cif0000644000000000000000000000006413411003760017116 0ustar rootrootSs+7Isyn3.cifadlibtracker2-2.4.24/package/instr/xylofone.sbi0000644000000000000000000000006413411003760020101 0ustar rootrootSBIxylofone.sbi1-Èõ/õ adlibtracker2-2.4.24/package/instr/$at2demo.a2w0000644000000000000000000001366213411003760017561 0ustar rootroot_A2insbank_w/macros_ØlÀâR­ŽQ!P&¸u¤ÿïwwwtî“¥’I'Kd“Ý%)*´mFŠ[:X/²VÈZŽ/I:IØI:Ó­mй#d´ 8 ¦ŠÜ@¢éŽb¡ à€®8è¸c˜†¡E]G¤—§u ûÿ¿ÿ÷»§»ª\A¤²tî’@3ÔÐuÝè‚éº$~SDt߀'Yøø…;{Ý[r6å]³ëì—ï¯AÝm¾ý^\ÛÀxúÿâ!|ðzìlàsiH/æÁ qúÖˆ„ªÅS³¦*ì6îû ‰eJ³ÒÍì¾u‚p ² Ý¡²öŠ‘X¨%kùÈ´=ýÁàÐÊJ׬•t¶+t²Wf²W8ª–JUþõì ˜‡æaR2ʧ,CNÁ‚5îk+å•#íW¬•¯Y*éd«¥’»5’»5’½JÉ^§E+©óm›üİ.ÃMÅ´2 ƒ,`À{|þ÷×m©[}¼´Ä¢¬íÝ?¸í=ŒX©V~­5ݘ4-ÄÍ,U}0ª~ÅàwläÅ]L¹Ì™VƒÑÈJß=àpô_Å*X$®^€ôÁ+«ýÚ\öâñþ¼Äü=´­ì †2®G^L\’7×*d˜!¿mônx%Dûmôâ$ª^/Ÿ“Šììó\,©é =«yX¬ïsÊÐë¯q++à{دÝJí®’{ðoÃF=Ïÿ4«7V§•*ÏjõJ‘ÿ4Î;¼êÝ=‚÷B\V¥ÄµÛ]…~¾d,Í€,Rx{(³cËH‰sà˜OU±ØÞpÛ:ø®Ý~ú±½RªõŠ,U³éh %‹×¶ß]B½¸'Æ,»»%>‚"¦ÎÉ «Ä [ÕLÚÓ#¢U=i€öÿ®}xó–·ØK¢ï`>A"ä/ _ÐNQ$U¹{ròöi_E*(:}rGTC­ØXhPÊ‘R:ESû[„Ú¶¾ã>× %H¬Tï:Ô^jV½d«¥’®¦égõÕyíã×ÂÓtç íb©p´mg üU)o “’TŒÚc•hPË–U/Ïḉ(/7Óms’Uïè å­ëÁ5‘wF•­êhT&ÂÔCIï±j#M奥•ŽâÑÞB}pŽöÃî\ºíb¤òUÂEÄØ’U-*×r^–î’ ¦°#KKwïtø2£•"±WüJϨ•A[Y:I]M­lR¡/­ô » ©­Åtµ¸³":)1"ðV†÷¨ƒnøïöUÑ»ËýU'X¨çj°êëÅbÃôHK½»%Cãd5Â…"VéÀ%]Â}pó¬;àû¢ö=ÔJÐZïïðErÖ©×Ñšá>¡VdngŸ¯Å'£hÞ^•f\9¥H¬Uî¥EÉÄ”adWì÷¶Ùö+ÿ½Hަ€ô~Skæô.ªT¿ÇMÿÒ¿õ+EÎàuv±R>½˜bþ‹âsìéU(©V}Á¶ž'UíÄÞ*HåS:ÆaïEmX‚n Þ:eJ‘Ïî¸zN ±_ˆIÜçGƒšU™f›QÛ×÷zuJ&U£û± "`Ïø…Ûûœþ¥é%YÚÚÉø¨GÙŒT‚©·Nu£ˆxrS>ƒ¥tâ…Z=¸ õ*›4Z½R¬ö¯Þ ¡½.˜MjùSZ¿Þ·ÃS’ ¼ÊÐ4ù•™»~Np8X:tžB†Ði9&q)z…YdÖÈšYÖŠ°É‰®`‘Q:Ê_¬7>É•J½[“ô ÷ƒC(©°¿wÓÊJŽX¡§I¼Oî˜áí¥Yn\éBÅB¤ÍÚ“ ÔÚÖ rèû5nF%$¬t£©R>ý¸¿Û`„ÃII†÷~npi{$©Š¿šV~Ú¸ØD¨¾g½––æ•f¥¨%fÞMêf%ÛˆðB$ I«²S‡/@d•KÐCW niVn€·ë·â@c¢ÏOÉ*Gûñgê%[«òB¨N7g¡L”‚©”Ÿ4Kš³Ùå)L«K•ÿv"zúÿM*™WÀ•¨7w:]ÜC—^Ë`4ȆÖ6Hg7¡yx£øйÃ(‘6ÑWy=lWVʉeyµH] †™Y[hÃÅ!{ª‰•e1k©Ž‰ËÛrÌ,Ôƒxª ó޶m“å„%4vNB^¦»’.Œó 8ÂõYbé*/²§TXÃ*‹µ¢*Ló ¥0¶Dõræ› áwÃÕº^µŒé®`r1™à ÕâIâH¼º©>ºÉDI²*M’I?žå£O¥¾†àÛ*=A´;¸t¦õ&5iÝd©—Ï 8¡Î+Î á_ĆIöígj°q¡Ñ2 º¢z¶ªºñaúCÕ¡}[_/T…‘'IÊQ&?4gdd'úƒ ŸL¿Ãüѽ3išóÙÓý¿»Ë±…nP-ÃUEÎÉOªT\þ®@²+éñò}exå=c?çáy÷LÙϤ…xÚƒoÕѶDOè±ÊéÓ‰ ŠÜ=LXÅô§x €»âþ†®@³È·€f¾)â.Ú¡ œ¦LÊnpvZN»º`‘¹J5&ÑÃØÐ†XK†Ð§!ÿu¬Jïã ŽÞd>cCk]w9÷<нøØŠvGý6<>ò–()IΚ/샱ò„vÊÓÉ kÄT[‰"è7Ê‹¨,b\÷[Þ¸._+éÐPV/ÇȉØ.®™ÕxÕÈÙFõÙVêλ…DÌÑ#ñ«[VÝohºseð,%sÔ³T\÷L¨½c~y¸ÁzÂnlHÆ‘m]%GÃå—^O®JNiá–¬þ¿MãäQYZ7 Ü{N@r öñωÚÒ…xf³Ûm\W·UÀ‘©Mèð·Ð)ú³ äu¿"ÕÀÚ„ä’¨²F*«C¨ã:>·ðQñ"ħå¦,¡ÉµR éR–ôçõŒÉ½&%Îûd¾¦š.-Si™ u™0TI^ª.'¬.ÇÊü}ê^¥’¹ÿî2bÉA#}Ìf†åŽ$±½?44*bõÄ7ØÇvO]¢‚Ï#®FûÞO’quw“ÉëØvÏ~c„åþr«%×bÑÃŒFK+k®­$"d$îUIÊùs‘ ®ÅË„ÊmÚNcÝ$nœ™xRdÊÎD™]y¾ž+¶QűT_"P±Fo²zƒæñÄ’`»b`û_¾"µ‘‹ ‚û΀ºœ+¬I)>‰4µç!ì:e5ä‚þL>œÂÃ7Q±üœ»-Ó%ßuÁªbäVÃ35“ˆFKfŸ«ZBz§íÃ?]?’>Šcp.¡¤„Iœl{SΤnfI8ÏR’”¨f‘‘"ÒÏ‘1=4ž²ª.2”£¤C àœÈ2J üqÁŸ<-NñqŒã ¦­‡wÈ`°M+@wáH#¿Î•'PÚ!i¶Ee4^b nm9!» 9„/Ëù^$bz–nuÃ3åCüL“ŠÚ Ð&%dÉ6=ðI„M,ˆD‰Uг‘*¹R¹$hºÁ45áÿ\7‹J•H‰ ® i`œhW„á‘K©îCè¶¶,“hQm(dFN'¯p3ÞA¦ÃCCêJ,ýsù‚ÆûóŹòèø©@Ô+ùÐ5ý¯ŠFK»Q™È¯oÏIí{W âþ›HÔ'ˆ|ÞˆR‘ÑÍSaüczÌ«NÇ’EíÔ:C/K¯;Å5ä1èŒLL“‹nž¶p‹†f×a©aa¨/ά´íñòÛâzñ«8Éú¤…üúîǸ˯ìø|r b `5:`’4ÿ™þæfï]Ñ`ÒŒ½ÍyD^ÀC•IêXôKo[A‚ƒàƒ%|ÈíEîè)¿çùÝÛ¹þŠ0,¾'|ľd+–Kà€>ËíºÇ°í»Yw­nô]‘è£õ~\<ý%ãíÿ¯£ÛÿLzâö´K.Î\¿³V^ätShçåíì?_“°ürãùËäËø=Ÿk/wèÛ·ÙÒý9ñüûnì{Uüwû?v+û¾ÝÏÏ–´&.ǽÉâÛëß—ÜÂþ—oæ· %ÚcÙ_Üë|¼;.üåîmõz½¸õ‰ãþ2å¯Â:r:Ÿú‚#ß&^ôŸSÊjÂzgÕofn*ðš}qXÚ"ÝÞ•1[÷îCÁ“ ¼3›>9ñ–a7pC\Ôì™óèæ~×{sNî~iÝíýóa\ó_(‹½¹)ÞÞM1Ýuªïl¦ðÎmW{nã,ÂmW{e6«»Û&ýt·‘€ÝÞÚç53›îöÁw´ÿÛQ»Ûµ…ÞÝ»WLÙü¹º®öèÝéMÞœÓô[yþ2S“©Ãï÷}~.LݨB›pýXÍïûM½¹„ÝŸo ¾MޜݜÞì¾}þU]ã^]ýý\|p³=²Âº¶ð›æ³_¦\þ›WÿŸKåõ]÷hî»Ûè_-qóÕ4nïSëkš«;1›ô曯tÝÛåúïmR»KŒ ÖݱªsS³6æ„0™w´ô2d–êŒônïpÅE–Q£Lw]x*é›?—7¿‹ ¸!„ÝéÌùôú»ÛŽøåË¿¿mØ8ÿQê[.**£–j.›z{8ÈO6™æË›ã£Šþn›¹¾)M,Ø>}<ÊîñËVin«¢ýÑ´Ëw·GT·]kš𛦳š`ó±× tÛ»ÚWh¸xy®Âsnö»v\9÷{rÍ &Ú‡Å)TE ­¨ÿ?ù%·(é¼/p)tVèÛ u\oPì“ÿˆ ”71@t%Ðd@Ò»tÀ݇­s·„,¿â§ËÐeÞK¹wµý¸ù·´}íí½€«{SÊÞÐ[Øü·µÖö†vö‚ÞÀÚÊã+Laoj1·µ8[Ú{Q-©Ën~^²9óaŸ7wþ£~6ö—»ß†Ú¥Þ8<Û6t[ÛÝáÂzÿ:rÚã dŒ¼aE¿®þ;·h–ЖßÜ6Û.`ÕóF»¼uÕm»¯]Ž©[ž«­ï.n‰ÜNœöŽ[YÞWTm¢+£k½F7^†šéÇ»Ýww³öö†Þ7éé·VÉËo.o^{_óKn~¿nÏŠõØ`%Œ²Dÿï{K)ZG¥i PÒ5 àÈ/€´ŽSb_V”‚~R¸%ྜÃ7­Ü5öæf÷;wÀÒ2Q#ED”pK~q.à(€|Kþ{žæ>þŸ7–ˆÃÕl%î·v {-÷Ûz7[Áâè³Ñ€í,>£Ÿ“ÓfxbñÝøã*xõûgj:z·Û«ðùÞ)>½£™¶U^ÉQwnxú'j}uu¹ìñøÛÛ—v»vÑ ;sﶉíîè°}{{JXónªÛ#ŠþÜü²žÞÝ5qNͽ ç·´ûoÓ–ÚíªˆßÛÚëh®Í¼,ñ÷ÛÛ“6ÆÞÐý·¶SÛ½ºí½°Ãol³á·¶ÞÀ÷om ½ ÿom ½ ó·¶,tÏ··6Øb¾³·jŸ%Ömí?]½©ëÛvÞÞ–¬;{NÞööæágˆÀ>{{aOo\ööOomööï]fÞÐ>)aó,™¶Um‘Å«}cË;S¦®)Ú‹ìñöííS—uvÕD/íÏ;gË¢»6ð³Ä` 3Ž SÿßW¾L´’LÜ™$©“2Ö÷¥ÑqI$¯RK‚I$“37vfàÌn Í›fI%T—ÁRI)*¤’g›y™™¾ù<Æã߀w.ü]¿(‰U@?éïçκT¯Ý qÔ0Á˜ “e7éCÉduV+x'Zgç­=¬ç[†+OÇo ëlEiÚLëhEh\ —ÐOÃAס¢£¤¥¦ìö»}Îí=EMUem}…{¿eg&ÒÖÚÞâæêîò]þ&.6>FNW‹Çäòù¼þO«×í÷|>9y™¹Ùú:zšºÚû;[{›»Ü|¼Üý?)Ÿ9¿_·ßñúÚêãÍîÿ¿±ìâ•Õ=(ó,÷ƒ ÿ«NæB a83€@©š‹€Ç°GP)üÄ hä@v¬€ÿÿêÝ› @nÐÐÑ !Œ”€ êår: € |qIØÎ&¥]<î×YtÇhj­BÈÎë6Ëë%wàŸHJ=QA?é¬»Çøy]ßúpâ;dGz«³¤kšÅ ÄŽÞ:aï¼<¥ÿ…ÞþûzeÛþ°>“œ¸ì|å adlibtracker2-2.4.24/package/instr/elguit4.sbi0000644000000000000000000000006413411003760017613 0ustar rootrootSBIelguit4.sbi€Úù adlibtracker2-2.4.24/package/instr/tincan1.sbi0000644000000000000000000000006413411003760017573 0ustar rootrootSBItincan1.sbiOï˜ñadlibtracker2-2.4.24/package/instr/softpizz.sbi0000644000000000000000000000006413411003760020126 0ustar rootrootSBIsoftpizz.sbiàpc€ø÷óóadlibtracker2-2.4.24/package/instr/muteclav.sgi0000644000000000000000000000003213411003760020056 0ustar rootroot adlibtracker2-2.4.24/package/instr/jump.sgi0000644000000000000000000000003213411003760017211 0ustar rootroot   adlibtracker2-2.4.24/package/instr/tech.sgi0000644000000000000000000000003213411003760017161 0ustar rootroot adlibtracker2-2.4.24/package/instr/harp2.sbi0000644000000000000000000000006413411003760017252 0ustar rootrootSBIharp2.sbi™€õöUSadlibtracker2-2.4.24/package/instr/epiano1a.sbi0000644000000000000000000000006413411003760017733 0ustar rootrootSBIepiano1a.sbiAc€óòXXadlibtracker2-2.4.24/package/instr/harpsi3.sbi0000644000000000000000000000006413411003760017607 0ustar rootrootSBIharpsi3.sbi5„€¨}3adlibtracker2-2.4.24/package/instr/fifths.fin0000644000000000000000000000006213411003760017516 0ustar rootrootFIFTHS.FIN Fifths echo õô¢adlibtracker2-2.4.24/package/instr/minebass.sgi0000644000000000000000000000003213411003760020037 0ustar rootrootadlibtracker2-2.4.24/package/instr/dune.sgi0000644000000000000000000000003213411003760017171 0ustar rootroot  adlibtracker2-2.4.24/package/instr/synth1.sbi0000644000000000000000000000006413411003760017464 0ustar rootrootSBIsynth1.sbiŠ@ññ³adlibtracker2-2.4.24/package/instr/tuba2.sbi0000644000000000000000000000006413411003760017253 0ustar rootrootSBItuba2.sbibsduadlibtracker2-2.4.24/package/instr/synmllet.sgi0000644000000000000000000000003213411003760020105 0ustar rootroot adlibtracker2-2.4.24/package/instr/trible.sgi0000644000000000000000000000003213411003760017517 0ustar rootrootadlibtracker2-2.4.24/package/instr/nicebass.sgi0000644000000000000000000000003213411003760020025 0ustar rootrootadlibtracker2-2.4.24/package/instr/spring.cif0000644000000000000000000000006413411003760017524 0ustar rootrootö ô„ spring.cifadlibtracker2-2.4.24/package/instr/shrtbass.cif0000644000000000000000000000006413411003760020053 0ustar rootrootäâ÷¤ööshrtbass.cifadlibtracker2-2.4.24/package/instr/piccolo.sbi0000644000000000000000000000006413411003760017666 0ustar rootrootSBIpiccolo.sbiääp`Ÿ adlibtracker2-2.4.24/package/instr/pian1b.sbi0000644000000000000000000000006413411003760017410 0ustar rootrootSBIpian1b.sbi&õõúúadlibtracker2-2.4.24/package/instr/melody.cif0000644000000000000000000000006413411003760017513 0ustar rootroota²óú‹melody.cifadlibtracker2-2.4.24/package/instr/synbass.sbi0000644000000000000000000000006413411003760017720 0ustar rootrootSBIsynbass.sbiA‘ƒe2t adlibtracker2-2.4.24/package/instr/bdrum2.sbi0000644000000000000000000000006413411003760017431 0ustar rootrootSBIbdrum2.sbi Èðïßadlibtracker2-2.4.24/package/instr/silly.sgi0000644000000000000000000000003213411003760017372 0ustar rootroot  adlibtracker2-2.4.24/package/instr/bncebass.sbi0000644000000000000000000000006413411003760020016 0ustar rootrootSBIbncebass.sbi !K{õradlibtracker2-2.4.24/package/instr/elguit1.sbi0000644000000000000000000000006413411003760017610 0ustar rootrootSBIelguit1.sbiñ! —ñadlibtracker2-2.4.24/package/instr/horror1.sgi0000644000000000000000000000003213411003760017632 0ustar rootroot adlibtracker2-2.4.24/package/instr/ebass-l.sgi0000644000000000000000000000003213411003760017564 0ustar rootroot  adlibtracker2-2.4.24/package/instr/frhorn1.sbi0000644000000000000000000000006413411003760017615 0ustar rootrootSBIfrhorn1.sbi!!Ÿ€SªZ adlibtracker2-2.4.24/package/instr/ligtbell.cif0000644000000000000000000000006413411003760020020 0ustar rootroot…€NùÚ ligtbell.cifadlibtracker2-2.4.24/package/instr/drum2.sgi0000644000000000000000000000003213411003760017267 0ustar rootrootadlibtracker2-2.4.24/package/instr/$mlfbank.bnk0000644000000000000000000017603413411003760017724 0ustar rootrootADLIB-ñH9AAHSAALTOABRSS1ACCDN001ACCORDNßACGPIANOACGUIT1ACGUIT1AACGUIT2¯ACOUBASSKACOUBS1LACOUBS2"ACOUPNO1#ACOUPNO2$ACOUPNO3íACOUSTAACOUSTIàACPIANOADLIB*AGOGO@AGUITARALIEN1 ALIEN1AÿALTOSAX ALTOVIO2 ALTOVIOL APPLAUSE ART1 ART2ART3ART4ART5’ATMOSPHRB1B10B11B12B13B2B3B4B5B6B7B8B9'BAGPIPEBAGPIPE1BAGPIPE2 BAMBA#BANJO!BANJO1"BANKMNGBARISAXåBARORGAN#BASBNC01$BASELC01%BASELC02&BASFLP01'BASFLUT2(BASFLUT3)BASFLUT4*BASFNY01+BASJAZ01,BASJAZ02-BASLON01.BASNOR01/BASNOR020BASNOR031BASNOR042BASPOP013BASPOP024BASREED25BASS6BASS-POP7BASS0018BASS0029BASS003:BASS004;BASS005<BASS006=BASS1>BASS1A?BASS2@BASS3ABASS4BBASS5CBASSBEL2DBASSBELLkBASSDRM¾BASSDRM1¿BASSDRM2ÀBASSDRM3ÔBASSDRM6ÕBASSDRM7EBASSDRN1FBASSDRN2GBASSDRN3HBASSDRN4IBASSFLUT×BASSFUNJBASSGTRKBASSGTR2LBASSGUITMBASSHARPBASSOONNBASSOON1‚BASSOON2OBASSREEDPBASSSYN1QBASSTRLGRBASSVIOLSBASSVLN2TBASYKA01UBBELL2VBCKWRD1WBDRUMXBDRUM0YBDRUM1ZBDRUM1A[BDRUM2\BDRUM2A]BDRUM3^BDRUM4_BDRUM5`BDRUM8aBELLONGéBELLORGbBELLScBELLS1dBELLS2eBELLS3ABELLSINGßBELLYfBELSHORTÃBIGBOTTM·BIGHORNlBIRDTWTgBITEME1hBLIPP1iBLIPP1AjBLIPP2kBLIPP3lBLIPP3AmBLURB1nBLURB1AoBLURB2pBLURB3qBLURB4rBNCEBASSsBOING‘BONGtBOOMDRUMbBOTTLBLOBOTTLEuBOTTLE1vBOTTLE1A‹BOWGLASSwBRASS01xBRASS02yBRASS03zBRASS1{BRASS2|BRASS4}BRASS5µBRASSECT·BRASSOFTÔBRASSYžBRDTWEET1BREATHcBREATHPP“BRIGHTˆBRSS&LD~BRSS1A[BRSSECT1\BRSSECT2¶BRTGUITRBRUSH01€BRUSH02BRUSH03‚BRUSH04ƒBRUSH1„BRUSH2…BRUSHES†BRUSHES2‡BSSN-KˆBSYSGNL‰CACOPH1ŠCACOPH1AƒCALLIOPE‹CASTANETŒCBASSOONCBBSN-KŽCELESTA3CELESTA1CELESTA2CELLO‘CELLO#1’CELLO#2GCELLO1“CELLO2…CHARANG0CHICKEN”CHICKEN1•CHICKEN2„CHIFF–CHIFF1—CHIFF2˜CHIFF2A™CHIFF2BšCHIFF2C›CHIFF3œCHIFF3ACHIFF4žCHIFF5ŸCHIFF6 CHIFF6A¡CHIFF6B¢CHIFF6C£CHIFF7¤CHIFF7AÎCHIFFER¥CHIME¦CHINA1§CHINA1A¨CHIRP©CHIRPY1tCHOIRŠCHOIRPAD8CHORALE_CHORSPNOüCHORUS’CJC“CJCIIªCKNX1«CKNX2¬CKNX3­CKNX4®CKNX5¯CLAPPING°CLAR003±CLAR1²CLAR1A³CLAR2´CLARINETVCLARINT1WCLARINT2ƒCLARINT3„CLARINT4…CLARINT5µCLARION†CLARSUSTµCLAVECIN0CLAVI11CLAVI22CLAVI3äCLAVICHDaCLAVINET¶CLICKâCLOOP·CLRNOR01¸CLRNOR02¹CLRNOR03ºCLRNOR04»CLRNT-K¼CLVELC01½CLVELC02¾CLVELC03¿CLVNOR01ÀCOMPUT1öCONTRAîCONTRA1ÁCONTRA2ÂCONTRABHCONTRABSÃCOOLPHN1ÄCRAZY2ÅCRAZYSNDÆCROMORNE4CROWDÇCRUNCHY1ÈCRUNCHY2ÉCRUNCHY3‘CRYSTAL”CUNÊCYMB10LËCYMB10MÌCYMB10SÍCYMB10SSÎCYMBALÏCYMBAL0ÐCYMBAL1ÑCYMBAL10ÒCYMBAL1AÓCYMBAL2ÔCYMBAL3ÕCYMBAL4ÖCYMBAL5×CYMBAL6ØCYMBAL7ÙCYMBAL8ÚCYMBAL9ÛCYMBALAXÜCYMBL2ÝCYMCRASHÞCYMCRSH1ßCYMRIDE8DBLBASS‡DBLREEDˆDBLREED1àDBLREED2‰DBLREED3ŠDBLREED4‹DBLREED5dDEEPSNARáDEMO•DIR¹DIRTYmDISTGTR¾DISTGTR1¿DISTGTR2–DISTORS1—DM1˜DM2BDOCGUIT1CDOCGUIT2DDOCGUIT3EDOCGUTFZFDOCGUTL1GDOCGUTL2HDOCGUTL3sDOCORG1tDOCORG2uDOCORG3vDOCORG4?DOCSOLOØDOCSYN3ÙDOCSYNMÚDOCSYNM2âDOCTOR1ãDOCTOR1AäDOCTOR1BåDOCTOR2æDOCTOR2AçDOCTOR2BèDOCTOR2CéDOG1êDOG1AëDOG1CìDOG1DíDOLPHIN1îDOLPHIN2ïDOLPHIN3æDPNOSST±DRAGFLYðDRIPñDRMELC01òDRMELC02óDRMLOG01ôDRMMLT01õDRMPWR01öDRONE1÷DRONE1AøDRONE2ùDRONE3úDRONE4óDTGUITARdDULCIMERûECHIMESüECHOBASS<ECHOBELL•ECHOESÙECHOFAIRýECHOGUIT>ECHOPANþEG1ÿEG2EG3EG4EG5EG6IEGUITAR0JEGUITAR1KEGUITAR2LEGUITAR3MEGUITAR4NEGUITAR5OEGUITAR6PEGUITAR7QEGUITAR8REGUITAR9ELBANJO1ELBASS1ELBASS2ELBASS8wELCFLUT1xELCFLUT2ELCLAV1 ELCLAV2 ELCLAV3 ELDRUM1 ELDRUM2°ELECBASSMELECBS1NELECBS2 ELECFLELECFL2jELECGTRIELECGTR1JELECGTR2)ELECORG1*ELECORG2+ELECORG3,ELECORG4%ELECPNO1&ELECPNO2'ELECPNO3(ELECPNO4ELECVIBEðELGMUTEáELGPIANOSELGT1LSELGUITELGUIT1ELGUIT10ELGUIT11ELGUIT1AELGUIT1BELGUIT1CELGUIT2ELGUIT3ELGUIT4ELGUIT5ELGUIT6ELGUIT7ELGUIT9ïELGUITARELORGAN1ELORGAN2\ELPIANO ELPIANO1!ELPIANO2"ELPIANO3XENGHORN#ENGHRN-KENGLHORN$ENGLHRN1%ENGLHRN2&EPIANO1A'EPIANO1B(ETHEREAL)ETHNIC)EXCELSTR*EXP1+EXP2,EXP3™EXPLODE1-FANTAPAN6FANTASY.FANTPAN2/FHORN(FIDDLE‡FIFTHS0FIFTHTN1FISH#12FISH#1A3FLAPBAS4FLTELC015FLTELC026FLTNOR017FLTNOR028FLTNOR039FLTNOR04:FLTNOR05ÍFLUBBER;FLUTE<FLUTE001=FLUTE002>FLUTE009?FLUTE1@FLUTE1AAFLUTE2BFLUTE3yFLUTE3AzFLUTE4{FLUTE5|FLUTE6}FLUTE7~FLUTE8CFLUTE9FLUTELDFLUTESAXoFNGRBASSEFRED1FFRED1A²FRETLESSQFRETLS1RFRETLS2zFRHORNGFRHORN1HFRHORN2IFRHRN-KJFSTRP1KFSTRP1ALFSTRP2MFUNKORGNNFUNKYOFUNNYBAS;FUNNYVOXPFUZ13LQFUZ13MRFUZ13SSFUZGUI12TFUZGUIT1UFUZGUIT2VFUZZBAS2WFUZZBAS3XFUZZBASSÝFUZZYBFX1FX2FX3FX4?FX4_ATMSFX5FX6 FX7!FX8YFZZBAZZ1šGANSEI9GLASSES¸GLOCKbGLOCKNSP”GOBLINSZGONG[GRANDPNO[GRATE1\GRATE2]GTRELC01^GTRELC02_GTRELC03`GTRELC04aGTRELC05bGTRELC06cGTRELC07dGTRELC08eGTRELC09fGTRELC10gGTRELC11hGTRELC12iGTRELC13jGTRELC14GTRFRETkGTRFUZ01lGTRFUZ02nGTRHARMmGTRHVY01nGTRHVY02oGTRHVY03pGTRHVY04qGTRJAZ02rGTRJAZZ0sGTRNOR01tGTRNOR02uGTRNOR03vGTRNOR04wGTRNOR05xGTRNOR06yGTRPIZ01zGTRPIZZ1{GTRSTL01|GTRSTL02}GTRSTL03~GTRSTL04GTRSUS01€GTVOLGUIT-SUS‚GUITARƒGUITAR1„GUITAR2…GUITAR3†GUITAR4‡GUITAR5ˆGUITAR6TGUITAR7UGUITARACVGUITDIS6GUITHARM‰GUITHIGHWGUITHVXGUITNOSEŠGUN1¡GUNSHOTHALOPADeHAMMOND‹HAND1ŒHANDBELLêHARMNICAHARMON1gHARMONCA7HARMOPANŽHARPHARP1HARP2‘HARP3’HARPE1ãHARPSCHD`HARPSI“HARPSI1”HARPSI1A•HARPSI1B–HARPSI2—HARPSI3˜HARPSI4™HARPSI5šHARTBEATèHEADYÚHEARTSTR›HELICOœHELICO1HELICO2žHELICO3ŸHELICPTR HELILOWÌHENHOUSE¡HHWAVE#1¢HHWAVE#2£HIHAT1¤HIHAT11¥HIHAT2¦HIHAT3§HIHAT4ÂHIHAT6ÃHIHAT7¨HONKTNK©HONKTNK2âHONKTONK]HONKYTNKªHORN1«HORN2¬HOTCYMB1­HRMCA-K®HRNENG01¯HRNENG02°HRNFR01±HRNFR02²HRNNOR01³HRNNOR02´HRPBAS01µHRPNOR01¶HRPNOR02·HRPNOR03¸HRPNOR04¹HRPNOR05ºHUMAN1»HUMAN2¼HUMAN3½HUMAN4¾HUMAN5¿HUMAN6òHVYMETALÀHVYMETL1ÁHVYMETL2ÂHVYMETL3ÃHVYMETL4ÄHVYMETL5YHVYMETL6ICERAINÅINSECTSÆINSTRMÇJAVAIC2ÈJAVAIC3ÉJAVAIC4ÊJAVAICA2ËJAVAICA3ÌJAVAICA4ÍJAVAICANiJAWHARPÎJAZGIT10ZJAZGUIT1ÏJAZGUIT2ÐJAZZBAS2ÑJAZZBASSîJAZZGTRÒJAZZGUITÓJAZZORGÔJET1ÕJET11AÖJET11B×JEWSHARPØJORGANnJUNGLTUN&KALIMBAÙKETTLE1ÚKEYBRD1ÛKEYBRD2ÜKEYBRD3ÝKEYBRD8ÞKEYBRD9ßKJM%KOTOàKOTO1áKUORSAU2âKUORSAUSãLASERäLASER1åLASER2 LEAD1 LEAD2 LEAD3 LEAD4LEAD5LEAD6LEAD7LEAD8æLEADGTRçLNGCYMBLèLNGSNAREéLOGDRUM1êLONGBASSëLOOSPRNGìLOVE30íLOVE31îLOVE32ïLOWðLOW001ñLOWSYN1òLOWSYN2óLOWSYN3ôLOWSYN4õLOWSYN5öLOWSYN6÷LOWSYN7øLOWSYN8ùLOWSYN9úLUOLAûMARIMB1A»MARIMBAüMARIMBA1ýMARIMBA2þMATTINSÿMDRNPHON.MELDRUM›MELODTOM¼MELOFLUTMEOWMEOW1MEOW1AMEOW2MEOW2AMEOW2BMERIMETAL1ŒMETALLICÆMETALSYNàMETLINGMGUN1 MGUN2 MGUN3 MIXTRE MLTRDRUM MNSYN1'MNSYN16'MNSYN2'MNSYN4'MNSYN8'ëMOHORNmMOOGSYN›MOOGSYN2œMOOGSYN3MOOGSYN4MOOGSYNTMOONMOTOR1MSUS01MSUS02yMTRUMPET¹MUSICBOXkMUTEDGTRMYINSMYSOUND1ÖNAVARROžNEW=NEWAGE¸NITESONGfNOISENOISE1NOISE1ANOISE2NOISE3NOISESYNNOTBIGìNYLONäNYLOONeOBERHEIMOBOEOBOE-K OBOE1!OBOE2=OBOE2001"OBOEV€OCARINA#OINKEE1$OINKEE23OINKEY%OLDPIA1&OLDSNAR:OOHSÖORCHjORCHEHITýORCHHIT'ORG10(ORG9ÄORGAN-B)ORGAN1*ORGAN101+ORGAN102,ORGAN103-ORGAN13.ORGAN2/ORGAN2A0ORGAN31ORGAN3A2ORGAN3B3ORGAN44ORGAN4A5ORGAN56ORGAN67ORGAN7oORGAN88ORGANASpORGANFDqORGANFD19ORGANKrORGANVL:ORGELC01;ORGNOR01<ORGNOR02=ORGNOR03>ORGNOR04?ORGNOR05@ORGNOR06AORGNOR07BORGNPERCCORGPEC01DORGPEDALñOVERDRIVlOVRDRGTRPAD1PAD2PAD3PAD4PAD5PAD6PAD7PAD8~PANFLUTE;PANPIPESÀPARLORGNfPERCORGNÜPHLASOREPHONE1FPHONE2GPHONE3ŸPHONE3A PHONE3B¡PHONE5HPHSHF1IPIAN1AJPIAN1BKPIAN1CLPIANOMPIANO1NPIANO10OPIANO11PPIANO1AQPIANO2RPIANO3SPIANO4ìPIANO64TPIANOBELUPIANOFVPIANOSUSWPICCOLOSPICCOLO1TPICCOLO2ÞPICKB±PICKBASSXPIG1YPINBEL01ZPINELC01[PINELC02\PINELC03]PINELC04^PINELC05_PINNOR01`PINNOR02aPINNOR03bPINNOR04cPINNOR05dPINNOR06ePINNOR07fPINNOR08gPINNOR09hPINNOR10iPINOLD01-PIPEORG1.PIPEORG2/PIPEORG3èPIPEORGNPIPESjPIPES1PIPES2÷PIZZsPIZZCATOFPIZZICTOkPLANE1lPLANE2mPLANE3nPLBASS1oPLIPH1‰POLYSNTHpPOPBASS1qPOPBASS2rPOPBASS3sPOPCORN1tPOWRDRUMæPRCORGANãPRCWOODuQBERT1vQBERT1AwQBERT1BxQBERT1CyQBERT1DzQBERT2{QWERTY1|QWERTY2áRAINY€RC1RECORDERéREEDORGN}REVCY#2~REVCYMBREVHHAT1€REVSNAR1REVVER1‚REVVER2^RHODESƒRIBIT„RIMSHOT…RKSNARE1çROCKORGN²RUDEBRSSçRUUBER¢S_SPI000£S_SPI001¤S_SPI002¥S_SPI003¦S_SPI004§S_SPI005¨S_SPI006©S_SPI007ªS_SPI008«S_SPI009¬S_SPI010­S_SPI011®S_SPI012¯S_SPI013°S_SPI014±S_SPI015²S_SPI016³S_SPI017´S_SPI018µS_SPI019¶S_SPI020·S_SPI021¸S_SPI022¹S_SPI023ºS_SPI024»S_SPI025¼S_SPI026½S_SPI027¾S_SPI028¿S_SPI029ÀS_SPI030ÁS_SPI031ÂS_SPI032ÃS_SPI033ÄS_SPI034ÅS_SPI035ÆS_SPI036ÇS_SPI037ÈS_SPI038ÉS_SPI039ÊS_SPI040ËS_SPI041ÌS_SPI042ÍS_SPI043ÎS_SPI044ÏS_SPI045ÐS_SPI046ÑS_SPI047ÒS_SPI048ÓS_SPI049ÔS_SPI050ÕS_SPI051ÖS_SPI052×S_SPI053ØS_SPI054ÙS_SPI055ÚS_SPI056ÛS_SPI057ÜS_SPI058ÝS_SPI059ÞS_SPI060ßS_SPI061àS_SPI062áS_SPI063âS_SPI064ãS_SPI065äS_SPI066åS_SPI067æS_SPI068çS_SPI069èS_SPI070éS_SPI071êS_SPI072ëS_SPI073ìS_SPI074íS_SPI075îS_SPI076ïS_SPI077ðS_SPI078ñS_SPI079òS_SPI080óS_SPI081ôS_SPI082õS_SPI083öS_SPI084÷S_SPI085øS_SPI086ùS_SPI087úS_SPI088ûS_SPI089üS_SPI090ýS_SPI091þS_SPI092ÿS_SPI093S_SPI094S_SPI095S_SPI096S_SPI097S_SPI098S_SPI099S_SPI100S_SPI101S_SPI102 S_SPI103 S_SPI104 S_SPI105 S_SPI106 S_SPI107S_SPI108S_SPI109S_SPI110S_SPI111S_SPI112S_SPI113S_SPI114S_SPI115S_SPI116S_SPI117S_SPI118S_SPI119S_SPI120S_SPI121S_SPI122S_SPI123S_SPI124S_SPI125 S_SPI126!S_SPI127‚SAWTOOTH†SAX1‡SAX11ˆSAX2‰SAX3USAX4ŠSAXNOR01‹SAXNOR02ŒSAXNOR03SAXNOR04ŽSAXTEN01SAXTEN02SAXTEN03‘SAXTEN04’SAXUNDERÅSAXXY“SBSYNTH°SBTIMBRE@SCHLDAZE–SCIFI”SCRATCH•SCRATCH4–SDROLD01—SDRRCK01˜SDRSUS01™SDRSYN01šSDRSYN02›SDRUM22SEASHOREœSEAWAVE1SEAWAVE2žSFTBRSS1ŸSFTFL2 SFTSTRNGŒSGLREEDSGLREED1ŽSGLREED2SGLREED3SGLREED4SHAKA<SHAKAHUSHAKUHCH$SHAMISEN—SHANAI¡SHIMMER1aSHO¢SHOCK1£SHOCK2¤SHOCK3¥SHOCK4¢SHORT£SHORT1¤SHORT2¥SHORT3¦SHORT4§SHORT5¨SHORT6ÂSHORTSYN5SHOT¦SHOT1§SHOT2¨SHPPIZZ©SHRTVIBEªSHUHP«SINEWV1¬SIREN1­SIREN2A®SIREN2B"SITAR¯SITAR1°SITAR2»SIXTIES7SLAP2pSLAPBAS1qSLAPBAS2³SLAPBASSOSLAPBS1PSLAPBS2êSLOCELLO©SMOOTH±SNAKEFL²SNARE1³SNARE10´SNARE2µSNARE3ÉSNARE4ÊSNARE5ÍSNARE6ÎSNARE7ÒSNARE8ÓSNARE9¶SNDRUM1·SNRSUST¸SOCE1ÐSOFTPAD¹SOFTPIZZ´SOFTRUMPºSOFTSAX»SOLOVLNþSOPRANO¼SOUNDA½SOUNDBSOUNDTRKÁSOUTHWNDíSPACBASS¾SPACE1¿SPACE1AÀSPACE1BÁSPACE1CÉSPACEBARÊSPACEFXÂSPASM1ÃSPBELLS1åSPCTDIST}SPRNOSAXSQUAREBSQWAVEÄSTANDARDÅSTEELD+STEELDRMÆSTEELGÇSTEELGT1ÈSTEELGT2ÉSTEELGT6ÊSTEELGT7iSTEELGTRËSTRBAS01ÌSTRING1ÍSTRING2ÎSTRING3ÏSTRING4ÐSTRING5ÑSTRING6ÒSTRING7ÓSTRINGS1ÔSTRINGS2ÕSTRINGYÖSTRLON01×STRLON02ºSTRLONGØSTRNG-KÙSTRNLON2ÚSTRNLONGÛSTRNOR01ÜSTRNOR02ÝSTRNOR03ùSTRSECTCSTRSECT1DSTRSECT2ESTRSECT3ÞSUDSY1ßSUDSY1AàSUDSY1BáSUDSY1CâSUDSY2ãSUDSY2AäSUDSY3åSURFŽSWEEPæSWINTH1çSWINTH2èSWINTH3éSWINTH4ØSWPIPORGêSYN1ëSYN10ìSYN12LíSYN12MîSYN12SïSYN12SSðSYN13ªSYN15ñSYN2òSYN3«SYN3AóSYN3SôSYN4õSYN5öSYN6÷SYN6AøSYN7ùSYN9úSYNBAL1ûSYNBAL2ÇSYNBARüSYNBAS01ýSYNBAS02þSYNBAS03ÿSYNBAS04SYNBAS05SYNBAS06SYNBAS07SYNBAS08SYNBASS1SYNBASS2SYNBASS3SYNBASS4SYNBASS5 SYNBASS6 SYNBASS8¶SYNBRASS{SYNBRSS1|SYNBRSS24SYNBRSS35SYNBRSS4_SYNMALLT SYNMOG01 SYNNOR01 SYNNOR02SYNNOR03SYNNOR04SYNNOR05SYNNOR06SYNNOR07SYNNOR08SYNNOR09SYNNOR10ÑSYNORCH½SYNPUNCH/SYNSNARSYNSNR1SYNSNR2úSYNSTR1ûSYNSTR2SYNT1SYNTH1SYNTH2¬SYNTH3­SYNTH4œSYNTHDRMvSYNVOICEÒSYNWHIZZ®T-PUPPY1¯T-PUPPY2T0-TAIDRUMgTAIKOšTAIKODRMhTAIKORIMëTANGOhTANGOACCTCA1TCD1ŸTELEPHONTENORSAXTENSAXTENSAX2 TENSAX3!TENSAX4"TEST1#TESTACC$TESTINSÈTHICKPADðTIMPøTIMPANI%TINCAN1&TING˜TINKLBEL'TLKBASS1(TLKBASS2)TMA1*TMD1+TOM1,TOM10-TOM11.TOM2/TOM30TOM41TOMTOM1ÇTOMTOM10ÈTOMTOM11ËTOMTOM12ÌTOMTOM13ÏTOMTOM14ÐTOMTOM15ÑTOMTOM16ÁTOMTOM6ÄTOMTOM7ÅTOMTOM8ÆTOMTOM9ÛTORTURE2TRAIN13TRAIN24TRAINBELrTREMOLO5TRIANGLE6TROFF17TROFF28TROMB19TROMB2:TROMB3YTROMBON1ZTROMBON2wTROMBONE;TROMBV<TRON1=TRON1A>TRON1B?TRPCUP1@TRUMPETATRUMPET1BTRUMPET2CTRUMPET3DTRUMPET4ETRUMPET5FTRUMPET6xTUBAGTUBA1HTUBA2ITUBA3½TUBEBELLJUFO1KUFO2ºVIBES]VIBES1^VIBES2³VIBPHONELVIBRA1MVIBRA2NVIBRA3cVIBRAPHNOVIBRELLSõVIOLAôVIOLINPVIOLIN1×VIOLIN1AQVIOLIN2RVIOLIN3ïVIOLIN4SVIOLIN8TVIOLIN9UVLN-KVVLNALT01WVLNALT02XVLNNOR01YVLNNOR02ZVLNNOR03[VLNNOR04\VLNNOR05]VLNPIZ01^VLNPIZZ1uVOICE†VOXLEAD_VOXSYNTH´WAABRASS:WARMBELL>WARMPAD`WASHMEaWASHME2bWASHME2AcWAVEdWAVE2eWEATHERfWEIRD1gWEIRD1AhWEIRD1BiWEIRD2jWHISTLEÛWHISTLE1kWHISTLE2ÜWHISTLE3lWHIZZO1mWHIZZO1AnWHIZZO1BoWHIZZO1CpWHIZZO1DqWHIZZO2rWHIZZO2AsWHIZZO2BtWHIZZO2CuWHIZZO2DvWHIZZO3wWIERD3xWIERD4`WINDBELLÏWINDBITEyWLKNGBSS WOODzWOOD1™WOODBLCK,WOODBLOCÕWOODYËWOOF{WOOFY1|WOOFY1A}WOOFY1B~WRDBASSWUZZLE1€WUZZLE1AWUZZLE1B‚WUZZLE1CƒWUZZLE1D„WUZZLE1E…WUZZLE1F†WUZZLE1G‡WUZZLE1HˆWUZZLE1I‰WUZZLE1JŠWUZZLE1K‹WUZZLE1LŒWUZZLE1MWUZZLE1NŽWUZZLE1OWUZZLE2WUZZLE2A‘WUZZLE2B’WUZZLE2C“WUZZLE2D”WUZZLE3•WUZZLE3A–WUZZLE3B—WUZZLE3C˜WUZZLE3D™WUZZLE3EšWUZZLE3F›WUZZLE3GœWUZZLE3HWUZZLE3IžWUZZLE3JÓWUZZYÝXYLOŸXYLO1 XYLO2¡XYLO3¼XYLOPHON¢YKABASS1ÞYKABASS2£YS1¤ZOINKS1¥ZOINKS1A¦ZOINKS1B§ZOINKS2¨ZOINKS2A©ZORF1ªZORF1A«ZORF1B¬ZORF1C­ZORF1D®ZORF1Eñòóôõö÷øùúûüýþÿ  8   (          4y                         #  #        *                         -                                                                    ?        ?        '                    .                                         ?    ?      ?   ?   <    ? <   <)   <A<   ?   ?     ?  ?       ?                                     2   ?         #  #  #             -                           ?        "    #  # #                      -  ' , '   '  , '                                                                                    !    ))                       ?    <   '     <  <   <          ? #  #            -'))                                                                                !   !      2        !         5                                          #  &                " #    #  &                   ?        ?     ?                            !  8  '           ?      <    < 5   #                        !                                                                                              ??????                ????    ? ?                   ,                      3                                                                  -                               "         )  *  ; =     <   <  C J  9  I  D  *  *<  < @  4  0  5   H  !  C  !  ?(N   <>A'                                             %                      - ,                                           !                                       #  3  $      '  '                                          & , +          !       %  +                !                                                                                     '                                   ) )                                                                                                      5                                                                                   '                                                                                                             1   #    *  # 8                #            #                              #)                               ,                     '                                       % adlibtracker2-2.4.24/package/instr/kuorsaus.sbi0000644000000000000000000000006413411003760020112 0ustar rootrootSBIkuorsaus.sbipÖÄ€¤EBadlibtracker2-2.4.24/package/instr/sweep.sbi0000644000000000000000000000006413411003760017361 0ustar rootrootSBIsweep.sbi¡! a÷o÷=ÿÿadlibtracker2-2.4.24/package/instr/bassharp.sbi0000644000000000000000000000006413411003760020041 0ustar rootrootSBIbassharp.sbiÀmùòsadlibtracker2-2.4.24/package/instr/tom.sbi0000644000000000000000000000006413411003760017035 0ustar rootrootSBItom.sbiúÚ¿¿adlibtracker2-2.4.24/package/instr/englhrn2.sbi0000644000000000000000000000006413411003760017755 0ustar rootrootSBIenglhrn2.sbiàä#q€®ž adlibtracker2-2.4.24/package/instr/drum2.ins0000644000000000000000000000003313411003760017277 0ustar rootroot éêdrum2.insadlibtracker2-2.4.24/package/instr/csynth.sbi0000644000000000000000000000006413411003760017546 0ustar rootrootSBIcsynth.sbiŠHññ³adlibtracker2-2.4.24/package/instr/bim.cif0000644000000000000000000000006413411003760016771 0ustar rootroot!*õòˆ bim.cifadlibtracker2-2.4.24/package/instr/tromb1.sbi0000644000000000000000000000006413411003760017442 0ustar rootrootSBItromb1.sbiq¡€A’;adlibtracker2-2.4.24/package/instr/dapbass.cif0000644000000000000000000000006413411003760017637 0ustar rootrootââö¦öödapbass.cifadlibtracker2-2.4.24/package/instr/elpiano1.sbi0000644000000000000000000000006413411003760017746 0ustar rootrootSBIelpiano1.sbiOñÒP|adlibtracker2-2.4.24/package/instr/snare1.sbi0000644000000000000000000000006413411003760017427 0ustar rootrootSBIsnare1.sbi øÖµOadlibtracker2-2.4.24/package/instr/tensax2.sbi0000644000000000000000000000006413411003760017622 0ustar rootrootSBItensax2.sbi‘OqR[{adlibtracker2-2.4.24/package/instr/long-hi.sgi0000644000000000000000000000003213411003760017573 0ustar rootroot  adlibtracker2-2.4.24/package/instr/upswing.sgi0000644000000000000000000000003213411003760017732 0ustar rootrootadlibtracker2-2.4.24/package/instr/base3.cif0000644000000000000000000000006413411003760017217 0ustar rootroot2Dõøÿbase3.cifadlibtracker2-2.4.24/package/instr/shrtvibe.sbi0000644000000000000000000000006413411003760020064 0ustar rootrootSBIshrtvibe.sbiäÀÿó?adlibtracker2-2.4.24/package/instr/syncrsh.cif0000644000000000000000000000006413411003760017713 0ustar rootrootDFBLsyncrsh.cifadlibtracker2-2.4.24/package/instr/bass.ins0000644000000000000000000000001413411003760017175 0ustar rootroot` ót85 adlibtracker2-2.4.24/package/instr/dot3.sgi0000644000000000000000000000003213411003760017107 0ustar rootroot adlibtracker2-2.4.24/package/instr/basstrlg.sbi0000644000000000000000000000006413411003760020057 0ustar rootrootSBIbasstrlg.sbiÁàO±Stadlibtracker2-2.4.24/package/instr/syn4.sbi0000644000000000000000000000006413411003760017133 0ustar rootrootSBIsyn4.sbi!" €ée:l adlibtracker2-2.4.24/package/instr/icerain.sgi0000644000000000000000000000003213411003760017650 0ustar rootroot  adlibtracker2-2.4.24/package/instr/bass4.cif0000644000000000000000000000006413411003760017236 0ustar rootroot@ETñSSbass4.cifadlibtracker2-2.4.24/package/instr/tromb2.sbi0000644000000000000000000000006413411003760017443 0ustar rootrootSBItromb2.sbi!¡€SR; adlibtracker2-2.4.24/package/instr/piano.ins0000644000000000000000000000001413411003760017353 0ustar rootroot¡¢¥¥õôadlibtracker2-2.4.24/package/instr/funny.sgi0000644000000000000000000000003213411003760017375 0ustar rootrootadlibtracker2-2.4.24/package/instr/beverly.sgi0000644000000000000000000000003213411003760017706 0ustar rootrootadlibtracker2-2.4.24/package/instr/tuba3.sbi0000644000000000000000000000006413411003760017254 0ustar rootrootSBItuba3.sbiRsevadlibtracker2-2.4.24/package/instr/bdrum3.sbi0000644000000000000000000000006413411003760017432 0ustar rootrootSBIbdrum3.sbi è¥ïÿadlibtracker2-2.4.24/package/instr/lostinsp.sgi0000644000000000000000000000003213411003760020111 0ustar rootroot  adlibtracker2-2.4.24/package/instr/chirp.sbi0000644000000000000000000000006413411003760017343 0ustar rootrootSBIchirp.sbi .ð_ððadlibtracker2-2.4.24/package/instr/trumpet2.sbi0000644000000000000000000000006413411003760020020 0ustar rootrootSBItrumpet2.sbi1¡€#R; adlibtracker2-2.4.24/package/instr/easybass.cif0000644000000000000000000000006413411003760020034 0ustar rootrootMôó|Veasybass.cifadlibtracker2-2.4.24/package/instr/harp3.sbi0000644000000000000000000000006413411003760017253 0ustar rootrootSBIharp3.sbiW€õöVTadlibtracker2-2.4.24/package/instr/organ3b.sbi0000644000000000000000000000006413411003760017571 0ustar rootrootSBIorgan3b.sbi[’ðð adlibtracker2-2.4.24/package/instr/syn4.cif0000644000000000000000000000006413411003760017117 0ustar rootroot(T‘syn4.cifadlibtracker2-2.4.24/package/instr/organ3.sbi0000644000000000000000000000006413411003760017427 0ustar rootrootSBIorgan3.sbi[€ðð adlibtracker2-2.4.24/package/instr/eguitar5.sgi0000644000000000000000000000003213411003760017763 0ustar rootroot   adlibtracker2-2.4.24/package/instr/trombone.sbi0000644000000000000000000000006413411003760020063 0ustar rootrootSBItrombone.sbi!¡€SR; adlibtracker2-2.4.24/package/instr/fifth.fin0000644000000000000000000000006213411003760017333 0ustar rootrootFIFTH.FIN Fifths õô£adlibtracker2-2.4.24/package/instr/mhihat.fin0000644000000000000000000000006213411003760017505 0ustar rootrootMHIHAT.FIN MetalHihat ·¥ adlibtracker2-2.4.24/package/instr/tuba.cif0000644000000000000000000000006413411003760017155 0ustar rootroot¡!RS; tuba.cifadlibtracker2-2.4.24/package/instr/synbuz.sbi0000644000000000000000000000006413411003760017570 0ustar rootrootSBIsynbuz.sbióô9 adlibtracker2-2.4.24/package/instr/rlog.sbi0000644000000000000000000000006413411003760017201 0ustar rootrootSBIrlog.sbi2Døõÿadlibtracker2-2.4.24/package/instr/softtrom.cif0000644000000000000000000000006413411003760020077 0ustar rootroot(A‘ûsofttrom.cifadlibtracker2-2.4.24/package/instr/fantpan2.sbi0000644000000000000000000000006413411003760017747 0ustar rootrootSBIfantpan2.sbitÖ‡€¤EBadlibtracker2-2.4.24/package/instr/bass2.ins0000644000000000000000000000001413411003760017257 0ustar rootroot`pãïT adlibtracker2-2.4.24/package/instr/drumdown.sgi0000644000000000000000000000003213411003760020075 0ustar rootroot adlibtracker2-2.4.24/package/instr/snare.sbi0000644000000000000000000000006413411003760017346 0ustar rootrootSBIsnare.sbi. ÿöJadlibtracker2-2.4.24/package/instr/wave1.sbi0000644000000000000000000000006413411003760017261 0ustar rootrootSBIwave1.sbiyÀ@Radlibtracker2-2.4.24/package/instr/pzzicato.sgi0000644000000000000000000000003213411003760020101 0ustar rootroot adlibtracker2-2.4.24/package/instr/tomtom.sgi0000644000000000000000000000003213411003760017555 0ustar rootrootadlibtracker2-2.4.24/package/instr/bass5.cif0000644000000000000000000000006413411003760017237 0ustar rootroot££bass5.cifadlibtracker2-2.4.24/package/instr/moon.sbi0000644000000000000000000000006413411003760017206 0ustar rootrootSBImoon.sbi†€ò ½›adlibtracker2-2.4.24/package/instr/blast.sbi0000644000000000000000000000006413411003760017343 0ustar rootrootSBIblast.sbiÿÿadlibtracker2-2.4.24/package/instr/topcbl.sgi0000644000000000000000000000003213411003760017521 0ustar rootroot  adlibtracker2-2.4.24/package/instr/vlnpizz.sbi0000644000000000000000000000006413411003760017752 0ustar rootrootSBIvlnpizz.sbiòá@€õý¨­adlibtracker2-2.4.24/package/instr/dot.sgi0000644000000000000000000000003213411003760017024 0ustar rootroot adlibtracker2-2.4.24/package/instr/syn1.sbi0000644000000000000000000000006413411003760017130 0ustar rootrootSBIsyn1.sbi•—€*Bóadlibtracker2-2.4.24/package/instr/synbass2.sbi0000644000000000000000000000006413411003760020002 0ustar rootrootSBIsynbass2.sbiA†e2t adlibtracker2-2.4.24/package/instr/bcymbal.sbi0000644000000000000000000000006413411003760017647 0ustar rootrootSBIbcymbal.sbid@²—‚Ôadlibtracker2-2.4.24/package/instr/ghost.sgi0000644000000000000000000000003213411003760017362 0ustar rootroot adlibtracker2-2.4.24/package/instr/elguit3.sbi0000644000000000000000000000006413411003760017612 0ustar rootrootSBIelguit3.sbi€‚‚}} adlibtracker2-2.4.24/package/instr/wave.sbi0000644000000000000000000000006413411003760017200 0ustar rootrootSBIwave.sbi€ð¢adlibtracker2-2.4.24/package/instr/organ3a.sbi0000644000000000000000000000006413411003760017570 0ustar rootrootSBIorgan3a.sbi[ðð adlibtracker2-2.4.24/package/instr/shrttne2.sbi0000644000000000000000000000006413411003760020007 0ustar rootrootSBIshrttne2.sbiÛ©6adlibtracker2-2.4.24/package/instr/v42.sgi0000644000000000000000000000003213411003760016651 0ustar rootroot  adlibtracker2-2.4.24/package/instr/troll.sgi0000644000000000000000000000003213411003760017372 0ustar rootrootadlibtracker2-2.4.24/package/instr/bass2.sbi0000644000000000000000000000006413411003760017250 0ustar rootrootSBIbass2.sbiòõïx adlibtracker2-2.4.24/package/instr/elecvibe.sbi0000644000000000000000000000006413411003760020014 0ustar rootrootSBIelecvibe.sbiQ—€š›adlibtracker2-2.4.24/package/instr/pianobel.sbi0000644000000000000000000000006413411003760020027 0ustar rootrootSBIpianobel.sbiOñòStadlibtracker2-2.4.24/package/instr/jazzbas2.sbi0000644000000000000000000000006413411003760017764 0ustar rootrootSBIjazzbas2.sbi !@{ur adlibtracker2-2.4.24/package/instr/slapbs1.sbi0000644000000000000000000000006413411003760017603 0ustar rootrootSBIslapbs1.sbióñöùo÷=ÿÿadlibtracker2-2.4.24/package/instr/string4.cif0000644000000000000000000000006413411003760017614 0ustar rootrootÅà—!óstring4.cifadlibtracker2-2.4.24/package/instr/tone.cif0000644000000000000000000000006413411003760017167 0ustar rootrootOÒñtStone.cifadlibtracker2-2.4.24/package/instr/terz.sgi0000644000000000000000000000003213411003760017222 0ustar rootrootadlibtracker2-2.4.24/package/instr/string6.cif0000644000000000000000000000006413411003760017616 0ustar rootroot(A‘ústring6.cifadlibtracker2-2.4.24/package/instr/bagpipe2.sbi0000644000000000000000000000006413411003760017727 0ustar rootrootSBIbagpipe2.sbi0cÿe  adlibtracker2-2.4.24/package/instr/frhorn2.sbi0000644000000000000000000000006413411003760017616 0ustar rootrootSBIfrhorn2.sbi !Ž¥6=adlibtracker2-2.4.24/package/instr/elclav1.sbi0000644000000000000000000000006413411003760017565 0ustar rootrootSBIelclav1.sbiŠ€ðô{{adlibtracker2-2.4.24/package/instr/softsax.sbi0000644000000000000000000000006413411003760017725 0ustar rootrootSBIsoftsax.sbiPRqRf‹adlibtracker2-2.4.24/package/instr/string2.cif0000644000000000000000000000006413411003760017612 0ustar rootrootæÂDf÷%string2.cifadlibtracker2-2.4.24/package/instr/eguitar3.sgi0000644000000000000000000000003213411003760017761 0ustar rootrootadlibtracker2-2.4.24/package/instr/ultra2.sgi0000644000000000000000000000003213411003760017447 0ustar rootroot  adlibtracker2-2.4.24/package/instr/syn3.sbi0000644000000000000000000000006413411003760017132 0ustar rootrootSBIsyn3.sbiŠ@ññ³adlibtracker2-2.4.24/package/instr/eguittar.cif0000644000000000000000000000006413411003760020046 0ustar rootroot @EññSSeguittar.cifadlibtracker2-2.4.24/package/instr/synsnr1.sbi0000644000000000000000000000006413411003760017653 0ustar rootrootSBIsynsnr1.sbiðøð¶adlibtracker2-2.4.24/package/instr/klarinet.cif0000644000000000000000000000006413411003760020033 0ustar rootrootò"@aAklarinet.cifadlibtracker2-2.4.24/package/instr/syn9.sbi0000644000000000000000000000006413411003760017140 0ustar rootrootSBIsyn9.sbi‡€ððadlibtracker2-2.4.24/package/instr/horror2.sgi0000644000000000000000000000003213411003760017633 0ustar rootroot adlibtracker2-2.4.24/package/instr/sax.ins0000644000000000000000000000001413411003760017040 0ustar rootroot¡"ÿððadlibtracker2-2.4.24/package/instr/panic.sgi0000644000000000000000000000003213411003760017330 0ustar rootroot adlibtracker2-2.4.24/package/instr/triangle.sbi0000644000000000000000000000006413411003760020043 0ustar rootrootSBItriangle.sbi&àÿð1adlibtracker2-2.4.24/package/instr/orgnperc.sbi0000644000000000000000000000006413411003760020055 0ustar rootrootSBIorgnperc.sbi øÖµOadlibtracker2-2.4.24/package/instr/synbass4.sbi0000644000000000000000000000006413411003760020004 0ustar rootrootSBIsynbass4.sbiA‘ƒe2t adlibtracker2-2.4.24/package/instr/knock.cif0000644000000000000000000000006413411003760017327 0ustar rootrootÚú¿¿knock.cifadlibtracker2-2.4.24/package/instr/synbal1.sbi0000644000000000000000000000006413411003760017607 0ustar rootrootSBIsynbal1.sbi&àÿð1adlibtracker2-2.4.24/package/instr/bellong.sbi0000644000000000000000000000006413411003760017660 0ustar rootrootSBIbellong.sbi¤>ÛÀÿóbadlibtracker2-2.4.24/package/instr/snare2.sbi0000644000000000000000000000006413411003760017430 0ustar rootrootSBIsnare2.sbi@@ Ìöadlibtracker2-2.4.24/package/instr/noise1.sbi0000644000000000000000000000006413411003760017434 0ustar rootrootSBInoise1.sbi@ÑòSadlibtracker2-2.4.24/package/instr/bell.ins0000644000000000000000000000001413411003760017163 0ustar rootrootaâõõòô adlibtracker2-2.4.24/package/instr/clavecin.sbi0000644000000000000000000000006413411003760020022 0ustar rootrootSBIclavecin.sbi òò± adlibtracker2-2.4.24/package/instr/brass.sgi0000644000000000000000000000003213411003760017350 0ustar rootrootadlibtracker2-2.4.24/package/instr/sunrise.sgi0000644000000000000000000000003213411003760017726 0ustar rootrootadlibtracker2-2.4.24/package/instr/basesyn.cif0000644000000000000000000000006413411003760017666 0ustar rootroot$@Õµ…Tbasesyn.cifadlibtracker2-2.4.24/package/instr/trpcup1.sbi0000644000000000000000000000006413411003760017634 0ustar rootrootSBItrpcup1.sbiàã,q€®žadlibtracker2-2.4.24/package/instr/reverb2.sbi0000644000000000000000000000006413411003760017605 0ustar rootrootSBIreverb2.sbi ¯?adlibtracker2-2.4.24/package/instr/briss6.sgi0000644000000000000000000000003213411003760017446 0ustar rootroot adlibtracker2-2.4.24/package/instr/snrsust.sbi0000644000000000000000000000006413411003760017757 0ustar rootrootSBIsnrsust.sbiÄðÄð4adlibtracker2-2.4.24/package/instr/syntom.cif0000644000000000000000000000006413411003760017553 0ustar rootrootäâ÷öösyntom.cifadlibtracker2-2.4.24/package/instr/galaxy3.sgi0000644000000000000000000000003213411003760017606 0ustar rootroot  adlibtracker2-2.4.24/package/instr/beep.cif0000644000000000000000000000006413411003760017135 0ustar rootroot3ÿbeep.cifadlibtracker2-2.4.24/iss_tim.pas0000644000000000000000000002106013411003760015160 0ustar rootroot { þ 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/adt2sys.pas0000644000000000000000000007356713411003760015125 0ustar rootroot// 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 AdT2sys; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const virtual_screen__first_row: Longint = 0; virtual_cur_shape: Word = 0; virtual_cur_pos: Word = 0; slide_ticks: Longint = 0; reset_slide_ticks: Boolean = FALSE; {$IFDEF GO32V2} gfx_ticks: Longint = 0; reset_gfx_ticks: Boolean = FALSE; scroll_ticks: Real = 0; mouse_active: Boolean = FALSE; {$ENDIF} {$IFNDEF GO32V2} _WAVREC_blink_flag: Boolean = FALSE; _WAVREC_blink_ticks: Longint = 0; {$ENDIF} _NRECM_blink_flag: Boolean = FALSE; _NRECM_blink_ticks: Longint = 0; _IRQ_freq_shift_reset_flag: Boolean = FALSE; _IRQFREQ_update_event: Boolean = FALSE; _IRQFREQ_blink_flag: Boolean = FALSE; _IRQFREQ_blink_ticks: Longint = 0; blink_flag: Boolean = FALSE; blink_ticks: Longint = 0; cursor_sync: Boolean = FALSE; _show_bpm_realtime_proc: procedure = NIL; {$IFDEF GO32V2} _draw_screen_without_vsync: Boolean = FALSE; _draw_screen_without_delay: Boolean = FALSE; {$ELSE} _draw_screen_without_delay: Boolean = FALSE; _update_sdl_screen: Boolean = FALSE; _name_scrl_shift_ctr: Shortint = 1; _name_scrl_shift: Byte = 0; _name_scrl_pending_frames: Longint = 0; {$ENDIF} _cursor_blink_factor: Longint = 13; _cursor_blink_pending_frames: Longint = 0; _realtime_gfx_no_update: Boolean = FALSE; {$IFDEF GO32V2} _screen_refresh_pending_frames: Longint = 0; _custom_svga_cfg: array[1..31] of Record flag: Boolean; value: Longint; end = ((flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1),(flag: FALSE; value: -1),(flag: FALSE; value: -1), (flag: FALSE; value: -1)); {$ENDIF} const _debug_: Boolean = FALSE; _last_debug_str_: String = ''; _debug_str_: String = ''; const _force_program_quit: Boolean = FALSE; _traceprc_last_order: Byte = 0; _traceprc_last_pattern: Byte = 0; _traceprc_last_line: Byte = 0; _pattedit_lastpos: Byte = 0; procedure sys_init; procedure sys_done; procedure draw_screen; {$IFNDEF GO32V2} const _FrameBuffer: Pointer = NIL; procedure vid_Init; procedure vid_Deinit; procedure vid_SetVideoMode(do_delay: Boolean); procedure vid_SetRGBPalette(var palette); procedure vid_FadeOut; {$ELSE} var _FrameBuffer_mirror: array[0..PRED(1024*768)] of Byte; {$ENDIF} function iCASE_filename(str: String): String; function Lower_filename(str: String): String; function Upper_filename(str: String): String; procedure ResetF_RW(var f: File); procedure ResetF(var f: File); procedure RewriteF(var f: File); procedure BlockReadF(var f: File; var data; size: Longint; var bytes_read: Longint); procedure BlockWriteF(var f: File; var data; size: Longint; var bytes_written: Longint); procedure SeekF(var f: File; fpos: Longint); procedure EraseF(var f: File); procedure CloseF(var f: File); implementation uses {$IFDEF GO32V2} DOS,GO32,AdT2vesa, {$ELSE} DOS,SDL,SDL_Video,SDL_Timer,SDL__rwops, AdT2opl3, {$ENDIF} AdT2unit,AdT2text,AdT2keyb,AdT2data, TxtScrIO,StringIO,ParserIO; {$IFNDEF GO32V2} var screen: PSDL_Surface; rgb_color_alt: array[0..15] of tRGB; {$ENDIF} procedure sys_init; begin {$IFNDEF GO32V2} vid_Init; // SDL video AdT2opl3.snd_init; // SDL sound + opl3 emulation {$ENDIF} end; procedure sys_done; begin {$IFNDEF GO32V2} vid_Deinit; {$ENDIF} end; {$IFDEF GO32V2} procedure draw_VESA_screen_800x600_1; const H_RES = 800; V_RES = 600; H_CHR = 90; V_CHR = 30; var byte_pos,bit_mask: Byte; cur_pos_lo,cur_pos_hi: Byte; cur_shape: Word; pos_x,pos_y: Byte; base_ofs,skip_ofs: Dword; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm push ebx push esi push edi mov ax,word ptr [virtual_cur_pos] mov cur_pos_lo,al mov cur_pos_hi,ah mov ax,word ptr [virtual_cur_shape] mov cur_shape,ax mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] lea edi,[_FrameBuffer_mirror] mov base_ofs,edi add edi,(H_RES-H_CHR*8)/2+(V_RES-V_CHR*16)/2*H_RES mov ebx,dword ptr [screen_ptr] mov eax,virtual_screen__first_row mov skip_ofs,eax movzx eax,MAX_ROWS mov loop_idx1,eax mov pos_y,1 @@2: mov byte_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,H_CHR mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,byte_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 cmp skip_ofs,0 jz @@6 dec skip_ofs jmp @@9 @@6: mov eax,edi sub eax,base_ofs cmp eax,H_RES*V_RES-(H_RES-H_CHR*8)/2-(V_RES-V_CHR*16)/2*H_RES jnbe @@12 cmp byte ptr [cursor_sync],1 jnz @@7 movzx eax,pos_x cmp al,cur_pos_lo jnz @@7 mov ax,cur_shape cmp byte_pos,ah jb @@7 cmp byte_pos,al ja @@7 movzx eax,pos_y cmp al,cur_pos_hi jnz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,H_CHR*2 cmp skip_ofs,0 jz @@10 sub skip_ofs,H_RES-H_CHR*8 jmp @@11 @@10: add edi,H_RES-H_CHR*8 @@11: inc byte_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,H_CHR*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 @@12: end; end; procedure draw_VESA_screen_800x600_2; const H_RES = 800; V_RES = 600; H_CHR = 90; V_CHR = 36; var byte_pos,bit_mask: Byte; cur_pos_lo,cur_pos_hi: Byte; cur_shape: Word; pos_x,pos_y: Byte; base_ofs,skip_ofs: Dword; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov ax,word ptr [virtual_cur_pos] mov cur_pos_lo,al mov cur_pos_hi,ah mov ax,word ptr [virtual_cur_shape] mov cur_shape,ax mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] lea edi,[_FrameBuffer_mirror] mov base_ofs,edi add edi,(H_RES-H_CHR*8)/2+(V_RES-V_CHR*16)/2*H_RES mov ebx,dword ptr [screen_ptr] mov eax,virtual_screen__first_row mov skip_ofs,eax movzx eax,MAX_ROWS mov loop_idx1,eax mov pos_y,1 @@2: mov byte_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,H_CHR mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,byte_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 cmp skip_ofs,0 jz @@6 dec skip_ofs jmp @@9 @@6: mov eax,edi sub eax,base_ofs cmp eax,H_RES*V_RES-(H_RES-H_CHR*8)/2-(V_RES-V_CHR*16)/2*H_RES jnbe @@12 cmp byte ptr [cursor_sync],1 jnz @@7 movzx eax,pos_x cmp al,cur_pos_lo jnz @@7 mov ax,cur_shape cmp byte_pos,ah jb @@7 cmp byte_pos,al ja @@7 movzx eax,pos_y cmp al,cur_pos_hi jnz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,H_CHR*2 cmp skip_ofs,0 jz @@10 sub skip_ofs,H_RES-H_CHR*8 jmp @@11 @@10: add edi,H_RES-H_CHR*8 @@11: inc byte_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,H_CHR*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 @@12: end; end; procedure draw_VESA_screen_1024x768; const H_RES = 1024; V_RES = 768; H_CHR = 120; V_CHR = 46; var byte_pos,bit_mask: Byte; cur_pos_lo,cur_pos_hi: Byte; cur_shape: Word; pos_x,pos_y: Byte; base_ofs: Dword; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov ax,word ptr [virtual_cur_pos] mov cur_pos_lo,al mov cur_pos_hi,ah mov ax,word ptr [virtual_cur_shape] mov cur_shape,ax mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] lea edi,[_FrameBuffer_mirror] mov base_ofs,edi add edi,(H_RES-H_CHR*8)/2+(V_RES-V_CHR*16)/2*H_RES mov ebx,dword ptr [screen_ptr] movzx eax,MAX_ROWS mov loop_idx1,eax mov pos_y,1 @@2: mov byte_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,H_CHR mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,byte_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 mov eax,edi sub eax,base_ofs cmp eax,H_RES*V_RES-(H_RES-H_CHR*8)/2-(V_RES-V_CHR*16)/2*H_RES jnbe @@9 cmp byte ptr [cursor_sync],1 jnz @@6 movzx eax,pos_x cmp al,cur_pos_lo jnz @@6 mov ax,cur_shape cmp byte_pos,ah jb @@6 cmp byte_pos,al ja @@6 movzx eax,pos_y cmp al,cur_pos_hi jnz @@6 mov al,[ebx+1] and al,01111b stosb jmp @@8 @@6: movzx eax,bit_mask test dl,al jz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@8 @@7: mov al,[ebx+1] shr al,4 stosb @@8: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,H_CHR*2 add edi,H_RES-H_CHR*8 inc byte_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,H_CHR*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 @@9: end; end; procedure dump_VESA_buffer(buffer_size: Longint); var dumped_data_size,bank_data_size: Longint; current_bank: Byte; begin If NOT _draw_screen_without_vsync then WaitRetrace; dumped_data_size := 0; current_bank := 0; While (dumped_data_size < buffer_size) do begin If (dumped_data_size+65536 <= buffer_size) then bank_data_size := 65536 else bank_data_size := buffer_size-dumped_data_size; VESA_SwitchBank(current_bank); dosmemput($0a000,0,_FrameBuffer_mirror[dumped_data_size],bank_data_size); Inc(dumped_data_size,bank_data_size); Inc(current_bank); end; end; procedure shift_text_screen; var xsize: Byte; xshift: Byte; begin xsize := SCREEN_RES_X DIV scr_font_width; xshift := (xsize-MAX_COLUMNS) DIV 2; FillChar(ptr_temp_screen2^,SCREEN_MEM_SIZE,0); asm mov esi,dword ptr [screen_ptr] mov edi,dword ptr [ptr_temp_screen2] cld movzx ecx,MAX_ROWS movzx ebx,xshift shl ebx,1 add edi,ebx @@1: xchg ecx,edx movzx ecx,xsize rep movsw xchg ecx,edx loop @@1 end; end; procedure draw_screen; begin If _draw_screen_without_delay then _draw_screen_without_delay := FALSE else If do_synchronize and NOT (_screen_refresh_pending_frames > fps_down_factor) then EXIT else _screen_refresh_pending_frames := 0; If Compare(screen_ptr,ptr_screen_mirror,(SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2) then EXIT else begin ScreenMemCopy(screen_ptr,ptr_screen_mirror); If NOT is_VESA_emulated_mode then begin If NOT _draw_screen_without_vsync then WaitRetrace; If NOT (program_screen_mode in [4,5]) then dosmemput(v_seg,v_ofs,screen_ptr^,MAX_COLUMNS*MAX_ROWS*2) else begin shift_text_screen; dosmemput(v_seg,v_ofs,ptr_temp_screen2^,(SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2); end; end; end; _draw_screen_without_vsync := FALSE; If is_VESA_emulated_mode then Case get_VESA_emulated_mode_idx of 0: begin draw_VESA_screen_800x600_1; dump_VESA_buffer(800*600); end; 1: begin draw_VESA_screen_800x600_2; dump_VESA_buffer(800*600); end; 2: begin draw_VESA_screen_1024x768; dump_VESA_buffer(1024*768); end; end; end; {$ELSE} {$IFNDEF CPU64} procedure draw_SDL_screen_720x480; var byte_pos,bit_mask: Byte; pos_x,pos_y: Byte; skip: Dword; framebuffer_end: Dword; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] mov edi,dword ptr [_FrameBuffer] mov framebuffer_end,edi add framebuffer_end,720*480 mov ebx,dword ptr [screen_ptr] mov eax,virtual_screen__first_row mov skip,eax mov loop_idx1,40 mov pos_y,1 @@2: mov byte_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,90 mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,byte_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 cmp skip,0 jz @@6 dec skip jmp @@9 @@6: cmp cursor_sync,1 jnz @@7 movzx eax,byte ptr [pos_x] cmp al,byte ptr [virtual_cur_pos] jnz @@7 mov ax,word ptr [virtual_cur_shape] cmp byte_pos,ah jb @@7 cmp byte_pos,al ja @@7 movzx eax,pos_y cmp al,byte ptr [virtual_cur_pos+1] jnz @@7 mov al,[ebx+1] and al,01111b cmp edi,framebuffer_end ja @@9 stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b cmp edi,framebuffer_end ja @@9 stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 cmp edi,framebuffer_end ja @@9 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,90*2 inc byte_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,90*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 end; end; procedure draw_SDL_screen_960x800; var byte_pos,bit_mask: Byte; pos_x,pos_y: Byte; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] mov edi,dword ptr [_FrameBuffer] mov ebx,dword ptr [screen_ptr] mov loop_idx1,50 mov pos_y,1 @@2: mov byte_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,120 mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,byte_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 @@6: cmp cursor_sync,1 jnz @@7 movzx eax,byte ptr [pos_x] cmp al,byte ptr [virtual_cur_pos] jnz @@7 mov ax,word ptr [virtual_cur_shape] cmp byte_pos,ah jb @@7 cmp byte_pos,al ja @@7 movzx eax,pos_y cmp al,byte ptr [virtual_cur_pos+1] jnz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,120*2 inc byte_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,120*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 end; end; procedure draw_SDL_screen_1440x960; var byte_pos,bit_mask: Byte; pos_x,pos_y: Byte; loop_idx1,loop_idx2,loop_idx3, loop_idx4: Dword; begin asm mov eax,_cursor_blink_factor cmp _cursor_blink_pending_frames,eax jnae @@1 mov _cursor_blink_pending_frames,0 xor byte ptr [cursor_sync],1 @@1: lea esi,[font8x16] mov edi,dword ptr [_FrameBuffer] mov ebx,dword ptr [screen_ptr] mov loop_idx1,60 mov pos_y,1 @@2: mov byte_pos,0 mov loop_idx2,16 @@3: mov loop_idx3,180 mov pos_x,1 @@4: movzx eax,byte ptr [ebx] mov edx,16 mul edx movzx edx,byte_pos add eax,edx mov dl,[esi+eax] mov bit_mask,dl mov loop_idx4,8 @@5: mov edx,1 mov ecx,loop_idx4 shl dx,cl shr dx,1 @@6: cmp cursor_sync,1 jnz @@7 movzx eax,byte ptr [pos_x] cmp al,byte ptr [virtual_cur_pos] jnz @@7 mov ax,word ptr [virtual_cur_shape] cmp byte_pos,ah jb @@7 cmp byte_pos,al ja @@7 movzx eax,pos_y cmp al,byte ptr [virtual_cur_pos+1] jnz @@7 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@7: movzx eax,bit_mask test dl,al jz @@8 mov al,[ebx+1] and al,01111b stosb jmp @@9 @@8: mov al,[ebx+1] shr al,4 stosb @@9: dec loop_idx4 cmp loop_idx4,0 ja @@5 add ebx,2 inc pos_x dec loop_idx3 cmp loop_idx3,0 ja @@4 sub ebx,180*2 inc byte_pos dec loop_idx2 cmp loop_idx2,0 ja @@3 inc pos_y add ebx,180*2 dec loop_idx1 cmp loop_idx1,0 ja @@2 end; end; {$ELSE} type pBYTE_ARRAY = ^tBYTE_ARRAY; tBYTE_ARRAY = array[0..PRED(SizeOf(DWORD))] of Byte; procedure draw_SDL_screen(columns,rows: Byte; scr_res: Dword); var bit_pos,bit_mask,byte_pos: Byte; pos_x,pos_y,chr,attr: Byte; s_ofs,v_ofs,skip: Dword; begin If (_cursor_blink_pending_frames >= _cursor_blink_factor) then begin _cursor_blink_pending_frames := 0; cursor_sync := NOT cursor_sync; end; s_ofs := 0; v_ofs := 0; skip := virtual_screen__first_row; For pos_y := 1 to rows do begin For byte_pos := 0 to 15 do begin For pos_x := 1 to columns do begin chr := pBYTE_ARRAY(screen_ptr)^[s_ofs]; attr := pBYTE_ARRAY(screen_ptr)^[s_ofs+1]; bit_mask := pBYTE_ARRAY(Addr(font8x16))^[chr*16+byte_pos]; For bit_pos := 8 downto 1 do begin If (skip <> 0) then Dec(skip) else If (v_ofs < scr_res) then begin If cursor_sync and (pos_x = LO(virtual_cur_pos)) and (pos_y = HI(virtual_cur_pos)) and (byte_pos >= HI(virtual_cur_shape)) and (byte_pos <= LO(virtual_cur_shape)) then pBYTE_ARRAY(_FrameBuffer)^[v_ofs] := attr AND $0f else If (bit_mask OR (1 SHL bit_pos) SHR 1 = bit_mask) then pBYTE_ARRAY(_FrameBuffer)^[v_ofs] := attr AND $0f else pBYTE_ARRAY(_FrameBuffer)^[v_ofs] := attr SHR 4; Inc(v_ofs); end; end; Inc(s_ofs,2); end; Dec(s_ofs,columns*2); end; Inc(s_ofs,columns*2); end; end; {$ENDIF} procedure draw_screen_proc; begin _update_sdl_screen := FALSE; If Compare(screen_ptr,ptr_screen_mirror,(SCREEN_RES_X DIV scr_font_width)*MAX_ROWS*2) then EXIT else ScreenMemCopy(screen_ptr,ptr_screen_mirror); _cursor_blink_factor := ROUND(13/100*sdl_frame_rate); _update_sdl_screen := TRUE; {$IFNDEF CPU64} Case program_screen_mode of 0: draw_SDL_screen_720x480; 1: draw_SDL_screen_960x800; 2: draw_SDL_screen_1440x960; end; {$ELSE} Case program_screen_mode of 0: draw_SDL_screen(90,40,720*480); 1: draw_SDL_screen(120,50,960*800); 2: draw_SDL_screen(180,60,1440*960); end; {$ENDIF} end; procedure vid_Init; begin SDL_Init(SDL_INIT_VIDEO or SDL_INIT_TIMER or SDL_INIT_AUDIO); end; procedure vid_Deinit; begin SDL_FreeSurface(screen); SDL_Quit; end; procedure vid_SetRGBPalette(var palette); begin SDL_SetPalette(screen,SDL_PHYSPAL,SDL_ColorArray(palette),0,16); end; procedure draw_screen; const frame_start: Longint = 0; frame_end: Longint = 0; actual_frame_end: Longint = 0; begin realtime_gfx_poll_proc; draw_screen_proc; If _update_sdl_screen then SDL_Flip(screen); If _draw_screen_without_delay then _draw_screen_without_delay := FALSE else begin // keep framerate actual_frame_end := SDL_GetTicks; frame_end := frame_start+(1000 DIV sdl_frame_rate); // always sleep at least 2 msec If (actual_frame_end+2 > frame_end) then frame_end := actual_frame_end+2; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; end; end; procedure vid_SetVideoMode(do_delay: Boolean); var icon: pSDL_Surface; rwop: pSDL_RWops; win_title: String; begin If do_delay then SDL_Delay(1000); screen := SDL_SetVideoMode(SCREEN_RES_x,SCREEN_RES_y,8,SDL_SWSURFACE); If (screen = NIL) then begin WriteLn('SDL: Couldn''t initialize video mode'); HALT(1); end; vid_SetRGBPalette(Addr(rgb_color)^); Move(rgb_color,rgb_color_alt,SizeOf(rgb_color)); _FrameBuffer := screen^.pixels; rwop := SDL_RWFromMem(adt2_icon_bitmap,SizeOf(adt2_icon_bitmap)); icon := SDL_LoadBMP_RW(rwop,TRUE); SDL_WM_SetIcon(icon,NIL); win_title := '/|DLiB TR/|CK3R ][ SDL'+#0; SDL_WM_SetCaption(Addr(win_title[1]),NIL); end; procedure vid_FadeOut; var idx: Byte; function min0(val: Longint): Longint; begin If (val <= 0) then min0 := 0 else min0 := val; end; begin For idx := 1 to 15 do begin rgb_color_alt[idx].r := min0(rgb_color_alt[idx].r-1); rgb_color_alt[idx].g := min0(rgb_color_alt[idx].g-1); rgb_color_alt[idx].b := min0(rgb_color_alt[idx].b-1); end; SDL_SetPalette(screen,SDL_PHYSPAL,SDL_ColorArray(Addr(rgb_color_alt)^),0,16); end; {$ENDIF} function iCASE_filename(str: String): String; begin {$IFDEF UNIX} iCASE_filename := str; {$ELSE} iCASE_filename := iCASE(str); {$ENDIF} end; function Lower_filename(str: String): String; begin {$IFDEF UNIX} Lower_filename := str; {$ELSE} Lower_filename := Lower(str); {$ENDIF} end; function Upper_filename(str: String): String; begin {$IFDEF UNIX} Upper_filename := str; {$ELSE} Upper_filename := Upper(str); {$ENDIF} end; procedure ResetF_RW(var f: File); var fattr: Word; begin _debug_str_:= 'ADT2SYS.PAS:ResetF_RW'; GetFAttr(f,fattr); If (fattr AND ReadOnly = ReadOnly) then SetFAttr(f,fattr AND NOT ReadOnly); If (DosError <> 0) then ; FileMode := 2; {$i-} Reset(f,1); {$i+} end; procedure ResetF(var f: File); var fattr: Word; begin _debug_str_:= 'ADT2SYS.PAS:ResetF'; GetFAttr(f,fattr); If (fattr AND ReadOnly = ReadOnly) then FileMode := 0; {$i-} Reset(f,1); {$i+} end; procedure RewriteF(var f: File); var fattr: Word; begin _debug_str_:= 'ADT2SYS.PAS:RewriteF'; GetFAttr(f,fattr); If (fattr AND ReadOnly = ReadOnly) then SetFAttr(f,fattr AND NOT ReadOnly); {$i-} Rewrite(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 BlockWriteF(var f: File; var data; size: Longint; var bytes_written: Longint); begin _debug_str_:= 'ADT2SYS.PAS:BlockWriteF'; {$i-} BlockWrite(f,data,size,bytes_written); {$i+} If (IOresult <> 0) then bytes_written := 0; end; procedure SeekF(var f: File; fpos: Longint); begin _debug_str_:= 'ADT2SYS.PAS:SeekF'; {$i-} Seek(f,fpos); {$i+} end; procedure EraseF(var f: File); begin _debug_str_:= 'ADT2SYS.PAS:EraseF'; {$i-} Erase(f); {$i+} If (IOresult <> 0) then ; 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/realtime.inc0000644000000000000000000010254613411003760015312 0ustar rootroot// 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 . { function _decay_bar_str(value: Byte): String; procedure show_bar(chan,level,xpos,from_pos,to_pos,attr: Byte); procedure decay_bars_refresh; function _vol_bar_str(value: Byte): String; procedure status_refresh; procedure trace_update_proc; } function _decay_bar_str(value: Byte): String; var result: String; begin result := ''; Repeat If (value > 15) then begin result := result+#219; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := result+CHR(224+value) until (value <= 15); _decay_bar_str := FlipStr(result); end; procedure show_bar(chan,level,xpos,from_pos,to_pos,attr: Byte); var temp: Byte; begin For temp := from_pos to to_pos do show_vcstr(xpos+temp-1+PRED(chan)*15,MAX_PATTERN_ROWS+14, ExpStrL('~'+_decay_bar_str(Round(105/63*level))+'~',9,#224), analyzer_bckg+analyzer, analyzer_bckg+attr SHR 4); end; procedure decay_bars_refresh; var chan,temp: Byte; speedup_factor,speedown_factor: Real; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'REALTIME.INC:decay_bars_refresh'; {$ENDIF} show_bar(1,overall_volume,05,1,2, analyzer_ovrllvol+analyzer_ovrllvol SHL 4); show_bar(1,global_volume,MAX_COLUMNS-7,1,2, analyzer_volumelvl+analyzer_volumelvl SHL 4); {$IFDEF GO32V2} speedup_factor := 4.0*SUCC(fps_down_factor); speedown_factor :=4.0*SUCC(fps_down_factor); {$ELSE} speedup_factor := 2.5*(100/sdl_frame_rate); speedown_factor := 2.5*(100/sdl_frame_rate); {$ENDIF} chan := chan_pos; For temp := 1 to MAX_TRACKS do begin If (decay_bar[chan].dir1 = 1) then decay_bar[chan].lvl1 := decay_bar[chan].lvl1+ decay_bar[chan].dir1*(decay_bar_rise*speedup_factor) else decay_bar[chan].lvl1 := decay_bar[chan].lvl1+ decay_bar[chan].dir1*(decay_bar_fall*speedown_factor); If (decay_bar[chan].dir2 = 1) then decay_bar[chan].lvl2 := decay_bar[chan].lvl2+ decay_bar[chan].dir2*(decay_bar_rise*speedup_factor) else decay_bar[chan].lvl2 := decay_bar[chan].lvl2+ decay_bar[chan].dir2*(decay_bar_fall*speedown_factor); If (decay_bar[chan].lvl1 < 0) then decay_bar[chan].lvl1 := 0; If (decay_bar[chan].lvl1 > 63) then decay_bar[chan].lvl1 := 63; If (decay_bar[chan].lvl1 >= carrier_vol[chan]) then decay_bar[chan].dir1 := -1; If (decay_bar[chan].lvl2 < 0) then decay_bar[chan].lvl2 := 0; If (decay_bar[chan].lvl2 > 63) then decay_bar[chan].lvl2 := 63; If (decay_bar[chan].lvl2 >= modulator_vol[chan]) then decay_bar[chan].dir2 := -1; If (volum_bar[chan].dir = 1) then volum_bar[chan].lvl := volum_bar[chan].lvl+ volum_bar[chan].dir*(decay_bar_rise*speedup_factor) else volum_bar[chan].lvl := volum_bar[chan].lvl+ volum_bar[chan].dir*(decay_bar_fall*speedown_factor); If (volum_bar[chan].lvl < 0) then volum_bar[chan].lvl := 0; If (volum_bar[chan].lvl > 63) then volum_bar[chan].lvl := 63; 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 (ins_parameter(voice_table[chan],10) AND 1 = 1) or (percussion_mode and (chan in [17..20])) then show_bar(temp,Round(decay_bar[chan].lvl2),08,1,6, analyzer+analyzer_modulator SHL 4) else show_bar(temp, 63-(scale_volume(63-Round(decay_bar[chan].lvl2), 63-Round(decay_bar[chan].lvl1))), 08,1,6, analyzer+analyzer_modulator SHL 4); If NOT (percussion_mode and (chan in [17..20])) then show_bar(temp,Round(decay_bar[chan].lvl1),08,8,14, analyzer+analyzer_carrier SHL 4) else show_bar(temp,0,08,8,14, analyzer+analyzer_carrier SHL 4); Inc(chan); end; end; function _vol_bar_str(value: Byte): String; var result: String; begin result := ''; Repeat If (value > 3) then begin result := result+#168; Dec(value,3); end; If (value <= 3) and (value <> 0) then result := result+CHR(164+value) until (value <= 3); _vol_bar_str := result; end; procedure status_refresh; var temps: String; temp,temp2,chan: Byte; {$IFNDEF GO32V2} wav_indicator_attr: array[Boolean] of Byte; {$ENDIF} playtime_attr1,playtime_attr2, playtime_attr3: array[Boolean] of Byte; bpm: Real; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'REALTIME.INC:status_refresh:1/4'; {$ENDIF} If really_no_status_refresh then EXIT; show_str(21,06,status_layout[play_status][8]+status_layout[play_status][9], status_background+status_play_state); {$IFDEF GO32V2} _debug_str_ := 'REALTIME.INC:status_refresh:2/4'; {$ENDIF} If no_status_refresh then begin chan := chan_pos; For temp2 := 1 to MAX_TRACKS do begin If channel_flag[chan] then show_str(08+(temp2-1)*15,MAX_PATTERN_ROWS+11, ExpStrR('',14,#205), pattern_bckg+pattern_border); Inc(chan); end; EXIT; end; {$IFDEF GO32V2} _debug_str_ := 'REALTIME.INC:status_refresh:3/4'; {$ENDIF} temps := status_layout[play_status]; show_str(14,06,ExpStrR(temps,10,' '), status_background+status_play_state); If NOT (area_x1+area_y1 = 0) and (area_x1 <= 20) and (area_y1 <= 06) then show_str(02,01,' '+ExpStrR(temps,10,' '), main_background+main_border) else show_str(02,01,ExpStrR('',12,#196), main_background+main_border); If single_play then EXIT; {$IFDEF GO32V2} _debug_str_ := 'REALTIME.INC:status_refresh:4/4'; {$ENDIF} If play_single_patt then show_str(20,03,byte2hex(current_pattern)+' ', pattern_bckg+status_dynamic_txt) else begin temp := songdata.pattern_order[current_order]; If NOT (temp <= $7f) then temp := 0; If NOT replay_forbidden and repeat_pattern and NOT calibrating then show_str(20,03,byte2hex(temp)+' '#19, pattern_bckg+status_dynamic_txt) else If NOT calibrating then show_str(20,03,byte2hex(temp)+' ', status_background+status_dynamic_txt) else show_str(20,03,byte2hex(temp), status_background+status_dynamic_txt); end; If NOT play_single_patt then show_str(17,03,byte2hex(current_order), status_background+status_dynamic_txt) else show_str(17,03,'--', status_background+status_dynamic_txt); show_str(17,04,byte2hex(current_line), status_background+status_dynamic_txt); If _IRQFREQ_update_event and NOT (Addr(_show_bpm_realtime_proc) <> NIL) then begin bpm := calc_realtime_bpm_speed(tempo,speed,mark_line); show_str(03,05,'SPEED iN BPM', status_background+status_static_txt); show_str(17,05,ExpStrR(Bpm2str(bpm),7,' '), status_background+status_dynamic_txt) end else If NOT _IRQFREQ_update_event then begin show_str(03,05,'SPEED/TEMPO /', status_background+status_static_txt); show_str(17,05,byte2hex(speed), status_background+status_dynamic_txt); If (tempo < 100) then If (tempo = 18) and timer_fix then show_str(20,05,byte2dec(tempo)+#5+#174, status_background+status_dynamic_txt) else show_str(20,05,byte2dec(tempo)+#174+' ', status_background+status_dynamic_txt) else show_str(20,05,byte2dec(tempo)+#174, status_background+status_dynamic_txt); end; If (play_status <> isStopped) then temps := ' ~'+byte2dec(max(song_timer DIV 60,99))+':'+ byte2dec(max(song_timer MOD 60,99))+'.'+ CHR(48+max(song_timer_tenths DIV 10,9))+'~ ' else temps := ' 00~:~00~.~0 '; playtime_attr1[FALSE] := status_background+status_text_dis; playtime_attr1[TRUE] := (status_border SHL 4) AND $0f0; playtime_attr2[FALSE] := status_background+status_border; playtime_attr2[TRUE] := status_background+status_border; playtime_attr3[FALSE] := main_background+main_border; playtime_attr3[TRUE] := (main_border SHL 4) AND $0f0; If _IRQFREQ_update_event then begin If (IRQ_freq_shift+playback_speed_shift > 0) then temps := '+'+Num2str(IRQ_freq_shift+playback_speed_shift,10)+#174 else If (IRQ_freq_shift+playback_speed_shift < 0) then temps := '-'+Num2str(Abs(IRQ_freq_shift+playback_speed_shift),10)+#174 else temps := Num2str(IRQ_freq+IRQ_freq_shift+playback_speed_shift,10)+#174; temps := '~ ~ '+CenterStR(temps,5)+' ~ ~'; end; show_cstr(13,07,temps, playtime_attr1[_IRQFREQ_blink_flag AND _IRQFREQ_update_event], playtime_attr2[_IRQFREQ_blink_flag AND _IRQFREQ_update_event]); If NOT (area_x1+area_y1 = 0) and (area_x1 <= 20) and (area_y1 <= 06) then show_cstr(16,01,temps, playtime_attr3[_IRQFREQ_blink_flag AND _IRQFREQ_update_event], main_background+main_border) else show_str(16,01,ExpStrR('',11,#196), main_background+main_border); If NOT _IRQFREQ_blink_flag AND _IRQFREQ_update_event then _IRQFREQ_update_event := FALSE; {$IFDEF GO32V2} temp := Pos('.',songdata_title); show_str(03,06,'['+ExpStrR(iCASE(Copy(songdata_title,1,PRED(temp))),8,' ')+']', status_background+status_dynamic_txt); show_str(03,07,'['+ExpStrR(iCASE(Copy(songdata_title,SUCC(temp),3)),3,' ')+']', status_background+status_border); If NOT module_archived then show_str(08,07,'['+#29+']', main_background+main_behavior) else show_str(08,07,#205#205#205, status_background+status_border); {$ELSE} temps := BaseNameOnly(FilterStr2(songdata_title,_valid_characters_fname,'_')); While (8+_name_scrl_shift > Length(temps)) and (_name_scrl_shift > 0) do Dec(_name_scrl_shift); show_str(03,06,'['+ExpStrR(iCASE(Copy(temps,1+_name_scrl_shift,8)),8,' ')+']', status_background+status_dynamic_txt); show_str(03,07,'['+ExpStrR(iCASE(Copy(ExtOnly(songdata_title),1,3)),3,' ')+']', status_background+status_border); If (_name_scrl_pending_frames <> 0) then Dec(_name_scrl_pending_frames) else begin _name_scrl_pending_frames := 20; If (_name_scrl_shift_ctr > 0) then If (8+_name_scrl_shift < Length(temps)) then Inc(_name_scrl_shift,_name_scrl_shift_ctr) else begin _name_scrl_shift_ctr := -1; _name_scrl_pending_frames := _name_scrl_pending_frames*10; end else If (_name_scrl_shift > 0) then Inc(_name_scrl_shift,_name_scrl_shift_ctr) else begin _name_scrl_shift_ctr := 1; _name_scrl_pending_frames := _name_scrl_pending_frames*50; end; end; wav_indicator_attr[FALSE] := main_background+main_behavior; If (play_status = isPlaying) and NOT opl3_channel_recording_mode then wav_indicator_attr[TRUE] := (main_behavior SHL 4) AND $0f0 else wav_indicator_attr[TRUE] := main_background+main_behavior; If NOT (area_x1+area_y1 = 0) and (area_x1 <= 20) and (area_y1 <= 06) then If (sdl_opl3_emulator <> 0) then show_str(13,01,'WAV',wav_indicator_attr[TRUE]) else show_str(13,01,#196#196#196,main_background+main_border) else If (sdl_opl3_emulator = 1) then show_str(08,07,'[WAV]',wav_indicator_attr[_WAVREC_blink_flag]) else If NOT module_archived then show_cstr(08,07,'~['+#29+']~'#205#205, status_background+status_border, main_background+main_behavior) else show_str(08,07,#205#205#205#205#205, status_background+status_border); {$ENDIF} If (command_typing = 1) then If NOT cycle_pattern then show_str(MAX_COLUMNS-17,MAX_PATTERN_ROWS+12,'A',main_background+main_behavior) else show_str(MAX_COLUMNS-17,MAX_PATTERN_ROWS+12,'F',main_background+main_behavior) else If (command_typing = 2) and NOT cycle_pattern then show_str(MAX_COLUMNS-17,MAX_PATTERN_ROWS+12,'S',main_background+main_behavior) else show_str(MAX_COLUMNS-17,MAX_PATTERN_ROWS+12,#196,main_background+main_border); If (songdata.flag_4op <> 0) then show_cstr(MAX_COLUMNS-43,MAX_PATTERN_ROWS+12,'~[~'+#4#3+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line) else show_cstr(MAX_COLUMNS-43,MAX_PATTERN_ROWS+12,'~[~'+#2+#3+'~]~', main_background+main_hi_stat_line, main_background+main_stat_line); For temp := 1 to 8 do If (temp <> current_octave) then show_str(30+temp,MAX_PATTERN_ROWS+12,CHR(48+temp), main_background+main_stat_line) else show_str(30+temp,MAX_PATTERN_ROWS+12,CHR(48+temp), main_background+main_hi_stat_line); chan := chan_pos; For temp2 := 1 to max(MAX_TRACKS,songdata.nm_tracks) do begin If NOT pan_lock[chan] or ((play_status = isStopped) and NOT debugging) then temp := pattern_bckg+pattern_pan_indic else temp := pattern_bckg+pattern_gpan_indic; If NOT ((play_status = isStopped) and NOT debugging and NOT panlock) and channel_flag[chan] then begin If percussion_mode and (chan in [16..20]) then Case chan of 16: temps := '~BD~ '; 17: temps := '~SD~ '; 18: temps := '~TT~ '; 19: temps := '~TC~ '; 20: temps := '~HH~ '; end else Case chan of 1, 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 3, 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 5, 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 10, 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 12, 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; 14, 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then If NOT vol4op_lock[chan] then temps := '~'#4#3'~ ' else temps := '~'#4#3'+~' else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; else Case volslide_type[chan] of 0: temps := ' '; 1: temps := 'C'+#10+' '; 2: temps := 'M'+#10+' '; 3: temps := '&'+#10+' '; end; end; If volume_lock[chan] then temps := temps+'V+'; If peak_lock[chan] then temps := temps+'P+'; If panlock and (play_status = isStopped) and NOT debugging then Case songdata.lock_flags[chan] AND 3 of 0: show_str(12+(temp2-1)*15,09,#21#22' ',temp); 1: show_str(12+(temp2-1)*15,09,#21' ',temp); 2: show_str(12+(temp2-1)*15,09,' '#22' ',temp); end else Case panning_table[chan] of 0: show_str(12+(temp2-1)*15,09,#21#22' ',temp); 1: show_str(12+(temp2-1)*15,09,#21' ',temp); 2: show_str(12+(temp2-1)*15,09,' '#22' ',temp); end; If NOT (chan in [16..20]) then show_cstr(12+(temp2-1)*15+3,09,ExpStrR(temps,7,' '), pattern_bckg+pattern_lock_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15+3,09,ExpStrR(temps,7,' '), pattern_bckg+pattern_lock_indic, pattern_bckg+pattern_perc_indic); end else If NOT percussion_mode and (chan in [16..20]) then show_str(12+(temp2-1)*15,09,#250#250' '+ExpStrL('',7,' '), pattern_bckg+pattern_pan_indic) else Case chan of 1, 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 3, 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 5, 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 10, 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 12, 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 14, 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 16: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('BD',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 17: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('SD',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 18: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('TT',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 19: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('TC',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 20: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('HH',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); else show_str(12+(temp2-1)*15,09,#250#250' '+ExpStrL('',7,' '), pattern_bckg+pattern_pan_indic); end; If NOT channel_flag[chan] then begin show_str(08+(temp2-1)*15,MAX_PATTERN_ROWS+11,#205#205#205, pattern_bckg+pattern_border); show_str(11+(temp2-1)*15,MAX_PATTERN_ROWS+11,' () OFF ', pattern_bckg+pattern_chan_indic); If (temp2 < max(MAX_TRACKS,songdata.nm_tracks)) then show_str(19+(temp2-1)*15,MAX_PATTERN_ROWS+11,#205#205#205#207, pattern_bckg+pattern_border) else show_str(19+(temp2-1)*15,MAX_PATTERN_ROWS+11,#205#205#205#202, pattern_bckg+pattern_border); If NOT percussion_mode and (chan in [16..20]) then show_str(12+(temp2-1)*15,09,#250#250' '+ExpStrL('',7,' '), pattern_bckg+pattern_pan_indic) else Case chan of 1, 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 3, 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 5, 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 10, 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 12, 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 14, 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR(''#4#3'',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic) else show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_4op_indic); 16: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('BD',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 17: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('SD',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 18: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('TT',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 19: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('TC',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); 20: show_cstr(12+(temp2-1)*15,09,#250#250' ~'+ExpStrR('HH',7,' ')+'~', pattern_bckg+pattern_pan_indic, pattern_bckg+pattern_perc_indic); else show_str(12+(temp2-1)*15,09,#250#250' '+ExpStrL('',7,' '), pattern_bckg+pattern_pan_indic); end; end else begin temp := 0; {$IFDEF GO32V2} If NOT ((scr_scroll_y > 10) or NOT is_scrollable_screen_mode) then {$ELSE} If NOT ((screen_scroll_offset > 10) or NOT is_default_screen_mode) then {$ENDIF} If NOT is_4op_chan(chan) or (is_4op_chan(chan) and (((chan in _4op_tracks_lo) and (temp2 = 1)) or ((chan in _4op_tracks_hi) and (temp2 = max(MAX_TRACKS,songdata.nm_tracks))))) then begin temp := Round(42/63*volum_bar[chan].lvl); If (temp2 < max(MAX_TRACKS,songdata.nm_tracks)) then show_str(08+(temp2-1)*15,11+MAX_PATTERN_ROWS, ExpStrR(_vol_bar_str(temp),14,#205)+#207, pattern_bckg+pattern_border) else show_str(08+(temp2-1)*15,11+MAX_PATTERN_ROWS, ExpStrR(_vol_bar_str(temp),14,#205)+#202, pattern_bckg+pattern_border); end else If chan in _4op_tracks_hi then begin temp := Round(84/63*volum_bar[chan].lvl); temps := _vol_bar_str(temp); If (Length(temps) > 14) then begin temps[15] := #169; temps := ExpStrR(temps,29,#205); end else begin temps := ExpStrR(temps,29,#205); temps[15] := #207; end; If (temp2 < PRED(max(MAX_TRACKS,songdata.nm_tracks))) then temps := temps+#207 else temps := temps+#202; show_str(08+(temp2-1)*15,11+MAX_PATTERN_ROWS, temps, pattern_bckg+pattern_border); end else else show_str(08+(temp2-1)*15,11+MAX_PATTERN_ROWS,Copy(patt_win[5],07+(temp2-1)*15,15), pattern_bckg+pattern_border); end; Inc(chan); end; end; procedure trace_update_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'IPATTERN.INC:trace_update_proc'; {$ENDIF} space_pressed := scankey(SC_SPACE); If (play_status = isPlaying) then If (_traceprc_last_order <> current_order) or (_traceprc_last_pattern <> current_pattern) or (_traceprc_last_line <> current_line) then begin _traceprc_last_order := current_order; _traceprc_last_pattern := songdata.pattern_order[current_order]; _traceprc_last_line := current_line; If tracing then begin If NOT play_single_patt then pattern_patt := songdata.pattern_order[current_order]; pattern_page := current_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; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; end; adlibtracker2-2.4.24/makefile0000644000000000000000000000263713411003760014515 0ustar rootroot.PHONY: clean release release_ all: adtrack2 release: release_ rm -rf release/adtrack-*/ echo -e "\n\n\nyour files are ready at release/\n" release_: all rm -rf release mkdir release mkdir release/src cp -r *.pas *.inc Makefile TODO *.bat sdl.dll sdl utils package release/src/ cp -r package release/bin cp adtrack2 release/bin/ rm -f release/bin/techinfo.* cd release; \ echo "which minor version is this? NOTE that i assume 2.4.xx and that you're on debian wheezy x86!"; \ read ver; \ mv src adtrack-2.4.$${ver}-linux-src; \ mv bin adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86; \ tar cvzf adtrack-2.4.$${ver}-linux-src.tar.gz adtrack-2.4.$${ver}-linux-src; \ tar cvzf adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86.tar.gz adtrack-2.4.$${ver}-linux-bin-debian-wheezy-x86; clean: rm -f *.o *.s *.res *.ppu *.map *.fpd *.sym *.cfg adtrack2 rm -f sdl/*.o sdl/*.ppu mrproper: clean rm -rf bin/ mkdir bin/ rm -rf release/ adtrack2: adt2data.pas adt2ext2.pas adt2ext3.pas adt2ext4.pas adt2ext5.pas adt2extn.pas adt2keyb.pas adt2opl3.pas adt2pack.pas adt2sys.pas adt2text.pas adt2unit.pas adt2vesa.pas adtrack2.pas depackio.pas dialogio.pas iloaders.inc iloadins.inc instedit.inc ipattern.inc ipattord.inc iss_tim.pas menulib1.pas menulib2.pas opl3emu.pas parserio.pas realtime.inc stringio.pas txtscrio.pas typcons1.inc typcons2.inc fpc -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Fusdl adtrack2.pas -oadtrack2 adlibtracker2-2.4.24/depackio.pas0000644000000000000000000014650713411003760015306 0ustar rootroot// 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 DepackIO; {$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; implementation 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: pByte; var ibuf_idx,ibuf_end,obuf_idx,obuf_src: pByte; ctrl_bits,ctrl_mask, command,count,offs: Word; {$IFNDEF CPU64} 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; {$ELSE} procedure RDC_decode; begin ctrl_mask := 0; ibuf_idx := input_ptr; obuf_idx := output_ptr; ibuf_end := input_ptr+input_size; While (ibuf_idx < ibuf_end) do begin ctrl_mask := ctrl_mask SHR 1; If (ctrl_mask = 0) then begin ctrl_bits := pWord(ibuf_idx)^; Inc(ibuf_idx,2); ctrl_mask := $8000; end; If (ctrl_bits AND ctrl_mask = 0) then begin obuf_idx^ := ibuf_idx^; Inc(ibuf_idx); Inc(obuf_idx); CONTINUE; end; command := (ibuf_idx^ SHR 4) AND 15; count := ibuf_idx^ AND 15; Inc(ibuf_idx); Case command Of // short RLE 0: begin Inc(count,3); FillChar(obuf_idx^,count,ibuf_idx^); Inc(ibuf_idx); Inc(obuf_idx,count); end; // long RLE 1: begin Inc(count,ibuf_idx^ SHL 4); Inc(ibuf_idx); Inc(count,19); FillChar(obuf_idx^,count,ibuf_idx^); Inc(ibuf_idx); Inc(obuf_idx, count); end; // long pattern 2: begin offs := count+3; Inc(offs,ibuf_idx^ SHL 4); Inc(ibuf_idx); count := ibuf_idx^; Inc(ibuf_idx); Inc(count,16); obuf_src := obuf_idx-offs; Move(obuf_src^,obuf_idx^,count); Inc(obuf_idx,count); end; // short pattern else begin offs := count+3; Inc(offs,ibuf_idx^ SHL 4); Inc(ibuf_idx); obuf_src := obuf_idx-offs; Move(obuf_src^,obuf_idx^,command); Inc(obuf_idx,command); end; end; end; output_size := obuf_idx-output_ptr; end; {$ENDIF} 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_BITS = 12; F_BITS = 4; THRESHOLD = 2; N = 1 SHL N_BITS; F = (1 SHL F_BITS)+THRESHOLD; {$IFNDEF CPU64} 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,THRESHOLD 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; {$ELSE} procedure LZSS_decode; label j1,j2,j3,j4,j5; var al,cl,ch,cf: Byte; dx: Word; ebx,edi: Dword; procedure GetChar; begin If (ibufCount < ibufSize) then begin al := input_ptr[ibufCount]; Inc(ibufCount); cf := 0; end else cf := 1; end; procedure PutChar; begin output_ptr[output_size] := al; Inc(output_size); end; begin ibufCount := 0; // mov ibufCount,0 ibufSize := input_size; // mov ax,input_size // mov ibufSize,ax output_size := 0; // mov output_size,0 ebx := 0; // xor ebx,ebx dx := 0; // xor edx,edx edi := N-F; // mov edi,N-F j1: dx := dx SHR 1; //@@1: shr dx,1 If (dx SHR 8 <> 0) then // or dh,dh GOTO j2; // jnz @@2 GetChar; // call GetChar If (cf = 1) then GOTO j5; // jc @@5 dx := $ff00 OR al; // mov dh,0ffh // mov dl,al j2: If (dx AND 1 = 0) then //@@2: test dx,1 GOTO j3; // jz @@3 GetChar; // call GetChar If (cf = 1) then GOTO j5; // jc @@5 // push esi work_ptr[edi] := al; // mov esi,work_ptr // add esi,edi // mov byte ptr [esi],al // pop esi edi := (edi+1) AND (N-1); // inc edi // and edi,N-1 PutChar; // caj PutChar GOTO j1; // jmp @@1 j3: GetChar; //@@3: caj GetChar If (cf = 1) then GOTO j5; // jc @@5 ch := al; // mov ch,al GetChar; // call GetChar If (cf = 1) then GOTO j5; // jc @@5 // mov bh,al // mov cl,4 ebx := (al SHL 4) AND $ff00; // shr bh,cl ebx := ebx OR ch; // mov bl,ch // mov cl,al // and cl,0fh cl := (al AND $0f)+THRESHOLD; // add cl,THRESHOLD Inc(cl); // inc cl j4: ebx := ebx AND (N-1); //@@4: and ebx,N-1 // push esi al := work_ptr[ebx]; // mov esi,work_ptr // mov al,byte ptr [esi+ebx] // add esi,edi work_ptr[edi] := al; // mov byte ptr [esi],al // pop esi Inc(edi); // inc edi edi := edi AND (N-1); // and edi,N-1 PutChar; // call PutChar Inc(ebx); // inc ebx Dec(cl); // dec cl If (cl <> 0) then GOTO j4; // jnz @@4 GOTO j1; // jmp @@1 j5: //@@5: end; {$ENDIF} 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, le82a,le82b: Word; const le7a: array[0..4] of Word = ($1ff,$3ff,$7ff,$0fff,$1fff); {$IFNDEF CPU64} 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,le7a[ebx] end; procedure LZW_decode; 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 @@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 eax,edi sub eax,output_ptr mov output_size,ax end; end; {$ELSE} var stack: array[WORD] of Byte; ax,bx,cx,sp: Word; edi,td: Dword; procedure NextCode; label j2; begin bx := le82a; // mov bx,le82a ax := le82b; // mov ax,le82b td := (ax SHL 16)+bx; // add bx,le78 td := td + le78; // adc ax,0 le82a := td AND $ffff; // xchg bx,le82a le82b := td SHR 16; // xchg ax,le82b cx := bx AND 7; // mov cx,bx td := (ax SHL 16)+bx; // and cx,7 td := td SHR 1; // shr ax,1 // rcr bx,1 td := td SHR 1; // shr ax,1 // rcr bx,1 td := td SHR 1; // shr ax,1 bx := td; // rcr bx,1 td := input_ptr[bx]+ // mov esi,input_ptr (input_ptr[bx+1] shl 8)+ // mov ax,[ebx+esi] (input_ptr[bx+2] shl 16); // mov dl,[ebx+esi+2] If (cx = 0) then // or cx,cx GOTO j2; // jz @@2 While (cx <> 0) do begin //@@1: shr dl,1 td := td SHR 1; Dec(cx); // rcr ax,1 end; // loop @@1 j2: bx := le78; //@@2: mov bx,le78 Dec(bx,9); // sub bx,9 // shl bx,1 ax:=td AND le7a[bx]; // and ax,[ebx+le7a_0] end; procedure LZW_decode; label j1,j2,j3,j4,j5,j7,j8,j9; begin sp := PRED(SizeOf(stack)); le72 := 0; // mov le72,0 le78 := 9; // mov le78,9 le70 := $102; // mov le70,102h le74 := $200; // mov le74,200h edi := 0; // mov edi,output_ptr ax := 0; // xor eax,eax le6a := 0; // mov le6a,ax le6c := 0; // mov le6c,ax le6e := 0; // mov le6e,ax le76 := 0; // mov le76,al le77 := 0; // mov le77,al le82a := 0; // mov le82a,ax le82b := 0; // mov le82b,ax j1: NextCode; //@@1: call NextCode If (ax <> $101) then // cmp ax,101h GOTO j2; // jnz @@2 GOTO j9; // jmp @@9 j2: If (ax <> $100) then //@@2: cmp ax,100h GOTO j3; // jnz @@3 le78 := 9; // mov le78,9 le74 := $200; // mov le74,200h le70 := $102; // mov le70,102h NextCode; // caj NextCode le6a := ax; // mov le6a,ax le6c := ax; // mov le6c,ax le77 := ax; // mov le77,al le76 := ax; // mov le76,al // mov al,le77 output_ptr[edi] := ax; // mov byte ptr [edi],al Inc(edi); // inc edi GOTO j1; // jmp @@1 j3: le6a := ax; //@@3: mov le6a,ax le6e := ax; // mov le6e,ax If (ax < le70) then // cmp ax,le70 GOTO j4; // jb @@4 ax := le6c; // mov ax,le6c le6a := ax; // mov le6a,ax ax := (ax AND $ff00)+le76; // mov al,le76 Dec(sp); stack[sp] := ax; // push eax Inc(le72); // inc le72 j4: If (le6a <= $ff) then //@@4: cmp le6a,0ffh GOTO j5; // jbe @@5 // mov esi,work_ptr // mov bx,le6a bx := le6a*3; // shl bx,1 ax := (ax AND $ff00)+work_ptr[bx+2]; // add bx,le6a Dec(sp); // mov al,[ebx+esi+2] stack[sp] := ax; // push eax Inc(le72); // inc le72 ax := work_ptr[bx]+(work_ptr[bx+1] SHL 8); // mov ax,[ebx+esi] le6a := ax; // mov le6a,ax GOTO j4; // jmp @@4 j5: ax := le6a; //@@5: mov ax,le6a le76 := ax; // mov le76,al le77 := ax; // mov le77,al Dec(sp); stack[sp] := ax; // push eax Inc(le72); // inc le72 // xor ecx,ecx cx := le72; // mov cx,le72 If (cx = 0) then GOTO j7; // jecxz @@7 While (cx <> 0) do // begin // ax := stack[sp]; Inc(sp); //@@6: pop eax output_ptr[edi] := ax; // mov byte ptr [edi],al Inc(edi); Dec(cx); // inc edi end; // loop @@6 j7: le72 := 0; //@@7: mov le72,0 // push esi // mov bx,le70 // shl bx,1 bx:=le70*3; // add bx,le70 // mov esi,work_ptr // mov al,le77 work_ptr[bx+2] := le77; // mov [ebx+esi+2],al work_ptr[bx+1] := le6c SHR 8; // mov ax,le6c work_ptr[bx+0] := le6c; // mov [ebx+esi],ax Inc(le70); // inc le70 // pop esi ax := le6e; // mov ax,le6e le6c := ax; // mov le6c,ax bx := le70; // mov bx,le70 If (bx < le74) then // cmp bx,le74 GOTO j8; // jl @@8 If (le78 = 14) then // cmp le78,14 GOTO j8; // jz @@8 Inc(le78); // inc le78 le74 := le74 SHL 1; // shl le74,1 j8: GOTO j1; //@@8: jmp @@1 j9: output_size := edi; //@@9: mov output_size,ax end; {$ENDIF} 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; ibitCount,ibitBuffer,obufCount: Word; {$IFNDEF CPU64} var index: 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; {$ELSE} procedure InitTree; var index: Word; begin For index := 2 to TWICEMAX do begin dad[index] := index DIV 2; frq[index] := 1; end; For index := 1 to MAXCHAR do begin leftC[index] := 2*index; rghtC[index] := 2*index+1; end; end; procedure UpdateFreq(a,b: Word); begin Repeat frq[dad[a]] := frq[a]+frq[b]; a := dad[a]; If (a <> ROOT) then If (leftC[dad[a]] = a) then b := rghtC[dad[a]] else b := leftC[dad[a]]; until (a = ROOT); If (frq[ROOT] = MAXFREQ) then For a := 1 to TWICEMAX do frq[a] := frq[a] SHR 1; end; procedure UpdateModel(code: Word); var a,b,c, code1,code2: Word; begin a := code+SUCCMAX; Inc(frq[a]); If (dad[a] <> ROOT) then begin code1 := dad[a]; If (leftC[code1] = a) then UpdateFreq(a,rghtC[code1]) else UpdateFreq(a,leftC[code1]); Repeat code2 := dad[code1]; If (leftC[code2] = code1) then b := rghtC[code2] else b := leftC[code2]; If (frq[a] > frq[b]) then begin If (leftC[code2] = code1) then rghtC[code2] := a else leftC[code2] := a; If (leftC[code1] = a) then begin leftC[code1] := b; c := rghtC[code1]; end else begin rghtC[code1] := b; c := leftC[code1]; end; dad[b] := code1; dad[a] := code2; UpdateFreq(b,c); a := b; end; a := dad[a]; code1 := dad[a]; until (code1 = ROOT); end; end; function InputCode(bits: Word): Word; var index,code: Word; begin code := 0; For index := 1 to bits do begin If (ibitCount = 0) then begin If (ibufCount = MAXBUF) then ibufCount := 0; ibitBuffer := pWord(input_ptr)[ibufCount]; Inc(ibufCount); ibitCount := 15; end else Dec(ibitCount); If (ibitBuffer > $7fff) then code := code OR bitValue[index]; ibitBuffer := ibitBuffer SHL 1; end; InputCode := code; end; function Uncompress: Word; var a: Word; begin a := 1; Repeat If (ibitCount = 0) then begin If (ibufCount = MAXBUF) then ibufCount := 0; ibitBuffer := pWord(input_ptr)[ibufCount]; Inc(ibufCount); ibitCount := 15; end else Dec(ibitCount); If (ibitBuffer > $7fff) then a := rghtC[a] else a := leftC[a]; ibitBuffer := ibitBuffer SHL 1; until (a > MAXCHAR); Dec(a,SUCCMAX); UpdateModel(a); Uncompress := a; end; procedure SIXPACK_decode; var i,j,k,t,c, count,dist,len,index: Word; begin count := 0; InitTree; c := Uncompress; While (c <> TERMINATE) do begin If (c < 256) then begin output_ptr[obufCount] := c; Inc(obufCount); If (obufCount = MAXBUF) then begin output_size := MAXBUF; obufCount := 0; end; work_ptr[count] := c; Inc(count); If (count = MAXSIZE) then count := 0; end else begin t := c-FIRSTCODE; index := t DIV CODESPERRANGE; len := t+MINCOPY-index*CODESPERRANGE; dist := InputCode(CopyBits[index])+len+CopyMin[index]; j := count; k := count-dist; If (count < dist) then Inc(k,MAXSIZE); For i := 0 to PRED(len) do begin output_ptr[obufCount] := work_ptr[k]; Inc(obufCount); If (obufCount = MAXBUF) then begin output_size := MAXBUF; obufCount := 0; end; work_ptr[j] := work_ptr[k]; Inc(j); Inc(k); If (j = MAXSIZE) then j := 0; If (k = MAXSIZE) then k := 0; end; Inc(count,len); If (count >= MAXSIZE) then Dec(count,MAXSIZE); end; c := Uncompress; end; output_size := obufCount; end; {$ENDIF} function SIXPACK_decompress(var source,dest; size: Word): Word; begin input_ptr := @source; output_ptr := @dest; work_ptr := @work_mem; input_size := size; ibitCount := 0; ibitBuffer := 0; obufCount := 0; ibufCount := 0; SIXPACK_decode; SIXPACK_decompress := output_size; end; {$IFNDEF CPU64} 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; {$ELSE} function APACK_decompress(var source,dest): Dword; var temp,res,swp,eax,ecx: Dword; tsi,esi,edi: pByte; ncf,cf,dl: Byte; label j1,j2,j3,j4,j5,j6,j7,j8,j9,j10,j11,j12,j13, j14,j15,j16,j17,j18,j19,j20,j21,j22,j23,j24,j25; begin esi := @source; // mov esi,[source] edi := @dest; // mov edi,[dest] temp := 0; res := 0; // cld dl := $80; // mov dl,80h j1: edi^ := esi^; Inc(esi); Inc(edi); Inc(res); //@@1: movsb j2: cf := dl SHR 7; dl := dl SHL 1; //@@2: add dl,dl If (dl <> 0) then GOTO j3; // jnz @@3 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl := (dl SHL 1)+cf; cf := ncf; // adc dl,dl j3: If (cf = 0) then GOTO j1; //@@3: jnc @@1 ecx := 0; // xor ecx,ecx cf := dl SHR 7; dl := dl SHL 1; // add dl,dl If (dl <> 0) then GOTO j4; // jnz @@4 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl := (dl SHL 1)+cf; cf := ncf; // adc dl,dl j4: If (cf =0 ) then GOTO j8; //@@4: jnc @@8 eax := 0; // xor eax,eax cf := dl SHR 7; dl := dl SHL 1; // add dl,dl If (dl <> 0) then GOTO j5; // jnz @@5 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl := (dl SHL 1)+cf; cf := ncf; // adc dl,dl j5: If (cf = 0) then GOTO j15; //@@5: jnc @@15 Inc(ecx); // inc ecx eax := $10; // mov al,10h j6: cf := dl SHR 7; dl := (dl SHL 1); //@@6: add dl,dl If (dl <> 0) then GOTO j7; // jnz @@7 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl:= (dl SHL 1)+cf; cf := ncf; // adc dl,dl j7: ncf := (eax SHR 7) AND 1; eax := (eax AND $ffffff00)+BYTE((eax SHL 1)+cf); cf := ncf; //@@7: adc al,al If (cf = 0) then GOTO j6; // jnc @@6 If (eax <> 0) then GOTO j24; // jnz @@24 edi^ := eax; Inc(edi); Inc(res); // stosb GOTO j2; // jmp @@2 j8: Inc(ecx); //@@8: inc ecx j9: cf := dl SHR 7; dl := dl SHL 1; //@@9: add dl,dl If (dl <> 0) then GOTO j10; // jnz @@10 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl := (dl SHL 1)+cf; cf := ncf; // adc dl,dl j10: ecx := ecx+ecx+cf; //@@10: adc ecx,ecx cf := dl SHR 7; dl := dl SHL 1; // add dl,dl If (dl <> 0) then GOTO j11; // jnz @@11 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl := (dl SHL 1)+cf; cf := ncf; // adc dl,dl j11: If (cf = 1) then GOTO j9; //@@11: jc @@9 Dec(ecx); // dec ecx Dec(ecx); If (ecx <> 0) then GOTO j16; // loop @@16 ecx := 0; // xor ecx,ecx Inc(ecx); // inc ecx j12: cf := dl SHR 7; dl := dl SHL 1; //@@12: add dl,dl If (dl <> 0) then GOTO j13; // jnz @@13 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl := (dl SHL 1)+cf; cf := ncf; // adc dl,dl j13: ecx := ecx+ecx+cf; //@@13: adc ecx,ecx cf := dl SHR 7; dl := dl SHL 1; // add dl,dl If (dl <> 0) then GOTO j14; // jnz @@14 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl := (dl SHL 1)+cf; cf := ncf; // adc dl,dl j14: If (cf = 1) then GOTO j12; //@@14: jc @@12 GOTO j23; // jmp @@23 j15: eax := esi^; Inc(esi); //@@15: lodsb cf := eax AND 1; eax := eax SHR 1; // shr eax,1 If (eax = 0) then GOTO j25; // jz @@25 ecx := ecx+ecx+cf; // adc ecx,ecx GOTO j20; // jmp @@20 j16: swp := eax; eax := ecx; ecx := swp; //@@16: xchg eax,ecx Dec(eax); // dec eax eax := (eax SHL 8)+esi^; // shl eax,8 Inc(esi); // lodsb ecx := 0; // xor ecx,ecx Inc(ecx); // inc ecx j17: cf := dl SHR 7; dl := dl SHL 1; //@@17: add dl,dl If (dl <> 0) then GOTO j18; // jnz @@18 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl := (dl SHL 1)+cf; cf := ncf; // adc dl,dl j18: ecx := ecx+ecx+cf; //@@18: adc ecx,ecx cf := dl SHR 7; dl := dl SHL 1; // add dl,dl If (dl <> 0) then GOTO j19; // jnz @@19 dl := esi^; // mov dl,[esi] Inc(esi); // inc esi ncf := dl SHR 7; dl := (dl SHL 1)+cf; cf := ncf; // adc dl,dl j19: If (cf = 1) then GOTO j17; //@@19: jc @@17 If (eax >= 32000) then // cmp eax,32000 GOTO j20; // jae @@20 If (eax >= 1280) then // cmp ah,5 GOTO j21; // jae @@21 If (eax > 127) then // cmp eax,7fh GOTO j22; // ja @@22 j20: Inc(ecx); //@@20: inc ecx j21: Inc(ecx); //@@21: inc ecx j22: swp := temp; temp := eax; eax := swp; //@@22: xchg eax,temp j23: eax := temp; //@@23: mov eax,temp j24: //@@24: push esi tsi := edi; // mov esi,edi Dec(tsi,eax); // sub esi,eax While (ecx <> 0) do // begin // edi^ := tsi^; // rep movsb Inc(tsi); Inc(edi); Inc(res); // Dec(ecx); // end; // pop esi GOTO j2; // jmp @@2 j25: //@@25: sub edi,[dest] // mov result,edi APACK_decompress := res; end; {$ENDIF} end. adlibtracker2-2.4.24/sdl/0000755000000000000000000000000013411511347013574 5ustar rootrootadlibtracker2-2.4.24/sdl/build.sh0000644000000000000000000000005413411003760015221 0ustar rootroot#!/bin/sh for i in *.pp; do ppc386 $i; doneadlibtracker2-2.4.24/sdl/sdl_keyboard.pp0000644000000000000000000003201213411003760016570 0ustar rootrootunit SDL_keyboard; { Automatically converted by H2PAS.EXE from SDL_keyboard.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PBoolArray = ^BoolArray ; BoolArray = Array[0..322] of Boolean; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Include file for SDL keyboard event handling } { ***corresponding to SDL_keysym.h***} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { What we really want is a mapping of every raw key on the keyboard. To support international keyboards, we use the range 0xA1 - 0xFF as international virtual keycodes. We'll follow in the footsteps of X11... } type SDLKey = Longint; Const {The names of the keys} { The keyboard syms have been cleverly chosen to map to ASCII } SDLK_UNKNOWN = 0; SDLK_FIRST = 0; SDLK_BACKSPACE = 8; SDLK_TAB = 9; SDLK_CLEAR = 12; SDLK_RETURN = 13; SDLK_PAUSE = 19; SDLK_ESCAPE = 27; SDLK_SPACE = 32; SDLK_EXCLAIM = 33; SDLK_QUOTEDBL = 34; SDLK_HASH = 35; SDLK_DOLLAR = 36; SDLK_AMPERSAND = 38; SDLK_QUOTE = 39; SDLK_LEFTPAREN = 40; SDLK_RIGHTPAREN = 41; SDLK_ASTERISK = 42; SDLK_PLUS = 43; SDLK_COMMA = 44; SDLK_MINUS = 45; SDLK_PERIOD = 46; SDLK_SLASH = 47; SDLK_0 = 48; SDLK_1 = 49; SDLK_2 = 50; SDLK_3 = 51; SDLK_4 = 52; SDLK_5 = 53; SDLK_6 = 54; SDLK_7 = 55; SDLK_8 = 56; SDLK_9 = 57; SDLK_COLON = 58; SDLK_SEMICOLON = 59; SDLK_LESS = 60; SDLK_EQUALS = 61; SDLK_GREATER = 62; SDLK_QUESTION = 63; SDLK_AT = 64; { Skip uppercase letters } SDLK_LEFTBRACKET = 91; SDLK_BACKSLASH = 92; SDLK_RIGHTBRACKET = 93; SDLK_CARET = 94; SDLK_UNDERSCORE = 95; SDLK_BACKQUOTE = 96; SDLK_a = 97; SDLK_b = 98; SDLK_c = 99; SDLK_d = 100; SDLK_e = 101; SDLK_f = 102; SDLK_g = 103; SDLK_h = 104; SDLK_i = 105; SDLK_j = 106; SDLK_k = 107; SDLK_l = 108; SDLK_m = 109; SDLK_n = 110; SDLK_o = 111; SDLK_p = 112; SDLK_q = 113; SDLK_r = 114; SDLK_s = 115; SDLK_t = 116; SDLK_u = 117; SDLK_v = 118; SDLK_w = 119; SDLK_x = 120; SDLK_y = 121; SDLK_z = 122; SDLK_DELETE = 127; { End of ASCII mapped keysyms } { International keyboard syms } SDLK_WORLD_0 = 160; { 0xA0 } SDLK_WORLD_1 = 161; SDLK_WORLD_2 = 162; SDLK_WORLD_3 = 163; SDLK_WORLD_4 = 164; SDLK_WORLD_5 = 165; SDLK_WORLD_6 = 166; SDLK_WORLD_7 = 167; SDLK_WORLD_8 = 168; SDLK_WORLD_9 = 169; SDLK_WORLD_10 = 170; SDLK_WORLD_11 = 171; SDLK_WORLD_12 = 172; SDLK_WORLD_13 = 173; SDLK_WORLD_14 = 174; SDLK_WORLD_15 = 175; SDLK_WORLD_16 = 176; SDLK_WORLD_17 = 177; SDLK_WORLD_18 = 178; SDLK_WORLD_19 = 179; SDLK_WORLD_20 = 180; SDLK_WORLD_21 = 181; SDLK_WORLD_22 = 182; SDLK_WORLD_23 = 183; SDLK_WORLD_24 = 184; SDLK_WORLD_25 = 185; SDLK_WORLD_26 = 186; SDLK_WORLD_27 = 187; SDLK_WORLD_28 = 188; SDLK_WORLD_29 = 189; SDLK_WORLD_30 = 190; SDLK_WORLD_31 = 191; SDLK_WORLD_32 = 192; SDLK_WORLD_33 = 193; SDLK_WORLD_34 = 194; SDLK_WORLD_35 = 195; SDLK_WORLD_36 = 196; SDLK_WORLD_37 = 197; SDLK_WORLD_38 = 198; SDLK_WORLD_39 = 199; SDLK_WORLD_40 = 200; SDLK_WORLD_41 = 201; SDLK_WORLD_42 = 202; SDLK_WORLD_43 = 203; SDLK_WORLD_44 = 204; SDLK_WORLD_45 = 205; SDLK_WORLD_46 = 206; SDLK_WORLD_47 = 207; SDLK_WORLD_48 = 208; SDLK_WORLD_49 = 209; SDLK_WORLD_50 = 210; SDLK_WORLD_51 = 211; SDLK_WORLD_52 = 212; SDLK_WORLD_53 = 213; SDLK_WORLD_54 = 214; SDLK_WORLD_55 = 215; SDLK_WORLD_56 = 216; SDLK_WORLD_57 = 217; SDLK_WORLD_58 = 218; SDLK_WORLD_59 = 219; SDLK_WORLD_60 = 220; SDLK_WORLD_61 = 221; SDLK_WORLD_62 = 222; SDLK_WORLD_63 = 223; SDLK_WORLD_64 = 224; SDLK_WORLD_65 = 225; SDLK_WORLD_66 = 226; SDLK_WORLD_67 = 227; SDLK_WORLD_68 = 228; SDLK_WORLD_69 = 229; SDLK_WORLD_70 = 230; SDLK_WORLD_71 = 231; SDLK_WORLD_72 = 232; SDLK_WORLD_73 = 233; SDLK_WORLD_74 = 234; SDLK_WORLD_75 = 235; SDLK_WORLD_76 = 236; SDLK_WORLD_77 = 237; SDLK_WORLD_78 = 238; SDLK_WORLD_79 = 239; SDLK_WORLD_80 = 240; SDLK_WORLD_81 = 241; SDLK_WORLD_82 = 242; SDLK_WORLD_83 = 243; SDLK_WORLD_84 = 244; SDLK_WORLD_85 = 245; SDLK_WORLD_86 = 246; SDLK_WORLD_87 = 247; SDLK_WORLD_88 = 248; SDLK_WORLD_89 = 249; SDLK_WORLD_90 = 250; SDLK_WORLD_91 = 251; SDLK_WORLD_92 = 252; SDLK_WORLD_93 = 253; SDLK_WORLD_94 = 254; SDLK_WORLD_95 = 255; { 0xFF } { Numeric keypad } SDLK_KP0 = 256; SDLK_KP1 = 257; SDLK_KP2 = 258; SDLK_KP3 = 259; SDLK_KP4 = 260; SDLK_KP5 = 261; SDLK_KP6 = 262; SDLK_KP7 = 263; SDLK_KP8 = 264; SDLK_KP9 = 265; SDLK_KP_PERIOD = 266; SDLK_KP_DIVIDE = 267; SDLK_KP_MULTIPLY = 268; SDLK_KP_MINUS = 269; SDLK_KP_PLUS = 270; SDLK_KP_ENTER = 271; SDLK_KP_EQUALS = 272; { Arrows + Home/End pad } SDLK_UP = 273; SDLK_DOWN = 274; SDLK_RIGHT = 275; SDLK_LEFT = 276; SDLK_INSERT = 277; SDLK_HOME = 278; SDLK_END = 279; SDLK_PAGEUP = 280; SDLK_PAGEDOWN = 281; { Function keys } SDLK_F1 = 282; SDLK_F2 = 283; SDLK_F3 = 284; SDLK_F4 = 285; SDLK_F5 = 286; SDLK_F6 = 287; SDLK_F7 = 288; SDLK_F8 = 289; SDLK_F9 = 290; SDLK_F10 = 291; SDLK_F11 = 292; SDLK_F12 = 293; SDLK_F13 = 294; SDLK_F14 = 295; SDLK_F15 = 296; { Key state modifier keys } SDLK_NUMLOCK = 300; SDLK_CAPSLOCK = 301; SDLK_SCROLLOCK = 302; SDLK_RSHIFT = 303; SDLK_LSHIFT = 304; SDLK_RCTRL = 305; SDLK_LCTRL = 306; SDLK_RALT = 307; SDLK_LALT = 308; SDLK_RMETA = 309; SDLK_LMETA = 310; SDLK_LSUPER = 311; { Left "Windows" key } SDLK_RSUPER = 312; { Right "Windows" key } SDLK_MODE = 313; { "Alt Gr" key } SDLK_COMPOSE = 314; { Multi-key compose key } { Miscellaneous function keys } SDLK_HELP = 315; SDLK_PRINT = 316; SDLK_SYSREQ = 317; SDLK_BREAK = 318; SDLK_MENU = 319; { Power Macintosh power key } SDLK_POWER = 320; { Some european keyboards } SDLK_EURO = 321; { Add any other keys here } SDLK_LAST = 322; type SDLMod = Longint; Const { Enumeration of valid key mods (possibly OR'd together) } KMOD_NONE = $0000; KMOD_LSHIFT = $0001; KMOD_RSHIFT = $0002; KMOD_LCTRL = $0040; KMOD_RCTRL = $0080; KMOD_LALT = $0100; KMOD_RALT = $0200; KMOD_LMETA = $0400; KMOD_RMETA = $0800; KMOD_NUM = $1000; KMOD_CAPS = $2000; KMOD_MODE = $4000; KMOD_RESERVED = $8000; KMOD_CTRL = KMOD_LCTRL or KMOD_RCTRL; KMOD_SHIFT = KMOD_LSHIFT or KMOD_RSHIFT; KMOD_ALT = KMOD_LALT or KMOD_RALT; KMOD_META = KMOD_LMETA or KMOD_RMETA; { ***end of SDL_keysym.h***} type { Keysym structure - The scancode is hardware dependent, and should not be used by general applications. If no hardware scancode is available, it will be 0. - The 'unicode' translated character is only available when character translation is enabled by the SDL_EnableUNICODE API. If non-zero, this is a UNICODE character corresponding to the keypress. If the high 9 bits of the character are 0, then this maps to the equivalent ASCII character: var ch:char; if (keysym.unicode and $FF80) = 0 then ch := keysym.unicode and 0x7F else An international character... } SDL_keysym = record scancode : Uint8; { hardware specific scancode } sym : SDLKey; { SDL virtual keysym } modifier : SDLMod; { current key modifiers } unicode : Uint16; { translated character } end; const { This is the mask which refers to all hotkey bindings } SDL_ALL_HOTKEYS = $FFFFFFFF; { Function prototypes } { Enable/Disable UNICODE translation of keyboard input. This translation has some overhead, so translation defaults off. If 'enable' is 1, translation is enabled. If 'enable' is 0, translation is disabled. If 'enable' is -1, the translation state is not changed. It returns the previous state of keyboard translation. } function SDL_EnableUNICODE(enable:longint):longint;cdecl; { Get a snapshot of the current state of the keyboard. Returns an array of keystates, indexed by the SDLK_ syms. Used: keystate: PBoolArray; keystate := SDL_GetKeyState(nil); if keystate[SDLK_RETURN] then ... is pressed } function SDL_GetKeyState(var numkeys:longint):PBoolArray;cdecl; { Get the current key modifier state } function SDL_GetModState:SDLMod;cdecl; { Set the current key modifier state This does not change the keyboard state, only the key modifier flags. } procedure SDL_SetModState(modstate:SDLMod);cdecl; { Get the name of an SDL virtual keysym } function SDL_GetKeyName(key:SDLKey):Pchar;cdecl; function SDL_EnableKeyRepeat(keydelay, keytinterval: longint): longint; cdecl; implementation function SDL_EnableUNICODE(enable:longint):longint;cdecl;external 'SDL'; function SDL_GetKeyState(var numkeys:longint):PBoolArray;cdecl;external 'SDL'; function SDL_GetModState:SDLMod;cdecl;external 'SDL'; procedure SDL_SetModState(modstate:SDLMod);cdecl;external 'SDL'; function SDL_GetKeyName(key:SDLKey):Pchar;cdecl;external 'SDL'; function SDL_EnableKeyRepeat(keydelay, keytinterval: longint): longint; cdecl; external 'SDL'; end. adlibtracker2-2.4.24/sdl/sdl_events.pp0000644000000000000000000003533513411003760016307 0ustar rootrootunit SDL_events; { Automatically converted by H2PAS.EXE from SDL_events.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types, SDL_syswm, SDL_keyboard; { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Include file for SDL event handling } const { Event enumerations } SDL_NOEVENT=0; { Unused (do not remove) } SDL_EVENTACTIVE=1; { Application loses/gains visibility } SDL_KEYDOWN=2; { Keys pressed } SDL_KEYUP=3; { Keys released } SDL_MOUSEMOTION=4; { Mouse moved } SDL_MOUSEBUTTONDOWN=5; { Mouse button pressed } SDL_MOUSEBUTTONUP=6; { Mouse button released } SDL_JOYAXISMOTION=7; { Joystick axis motion } SDL_JOYBALLMOTION=8; { Joystick trackball motion } SDL_JOYHATMOTION=9; { Joystick hat position change } SDL_JOYBUTTONDOWN=10; { Joystick button pressed } SDL_JOYBUTTONUP=11; { Joystick button released } SDL_EVENTQUIT=12; { User-requested quit } SDL_EVENTSYSWM=13; { System specific event } SDL_EVENT_RESERVEDA=14; { Reserved for future use } SDL_EVENT_RESERVEDB=15; { Reserved for future use } SDL_VIDEORESIZE=16; { User resized video mode } SDL_VIDEOEXPOSE=17; { Screen needs to be redrawn } SDL_EVENT_RESERVED2=18; { Reserved for future use } SDL_EVENT_RESERVED3=19; { Reserved for future use } SDL_EVENT_RESERVED4=20; { Reserved for future use } SDL_EVENT_RESERVED5=21; { Reserved for future use } SDL_EVENT_RESERVED6=22; { Reserved for future use } SDL_EVENT_RESERVED7=23; { Reserved for future use } { Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use } SDL_EVENTUSER = 24; { This last event is only for bounding internal arrays It is the number of bits in the event mask datatype -- Uint32 } SDL_NUMEVENTS = 32; { Predefined event masks } SDL_ACTIVEEVENTMASK = 1 shl (SDL_EVENTACTIVE); SDL_KEYDOWNMASK = 1 shl (SDL_KEYDOWN); SDL_KEYUPMASK = 1 shl (SDL_KEYUP); SDL_MOUSEMOTIONMASK = 1 shl (SDL_MOUSEMOTION); SDL_MOUSEBUTTONDOWNMASK = 1 shl (SDL_MOUSEBUTTONDOWN); SDL_MOUSEBUTTONUPMASK = 1 shl (SDL_MOUSEBUTTONUP); SDL_MOUSEEVENTMASK = SDL_MOUSEMOTIONMASK or SDL_MOUSEBUTTONDOWNMASK or SDL_MOUSEBUTTONUPMASK; SDL_JOYAXISMOTIONMASK = 1 shl (SDL_JOYAXISMOTION); SDL_JOYBALLMOTIONMASK = 1 shl (SDL_JOYBALLMOTION); SDL_JOYHATMOTIONMASK = 1 shl (SDL_JOYHATMOTION); SDL_JOYBUTTONDOWNMASK = 1 shl (SDL_JOYBUTTONDOWN); SDL_JOYBUTTONUPMASK = 1 shl (SDL_JOYBUTTONUP); SDL_JOYEVENTMASK = SDL_JOYAXISMOTIONMASK or SDL_JOYBALLMOTIONMASK or SDL_JOYHATMOTIONMASK or SDL_JOYBUTTONDOWNMASK or SDL_JOYBUTTONUPMASK; SDL_VIDEORESIZEMASK = 1 shl (SDL_VIDEORESIZE); SDL_VIDEOEXPOSEMASK = 1 shl (SDL_VIDEOEXPOSE); SDL_QUITMASK = 1 shl (SDL_EVENTQUIT); SDL_SYSWMEVENTMASK = 1 shl (SDL_EVENTSYSWM); SDL_ALLEVENTS = $FFFFFFFF; type { Application visibility event structure } SDL_ActiveEvent = record eventtype : Uint8; { SDL_ACTIVEEVENT } gain : Uint8; { Whether given state were gained or lost (1/0) } state : Uint8; { A mask of the focus states } end; { Keyboard event structure } SDL_KeyboardEvent = record eventtype : Uint8; { SDL_KEYDOWN or SDL_KEYUP } which : Uint8; { The keyboard edvice index } state : Uint8; { SDL_PRESSED or SDL_RELEASED } keysym : SDL_keysym; end; { Mouse motion event structure } SDL_MouseMotionEvent = record eventtype : Uint8; { SDL_MOUSEMOTION } which : Uint8; { The mouse device index } state : Uint8; { The current button state } x, y : Uint16; { The x/y coordinates of the mouse } xrel : Sint16; { The relative motion in X direction } yrel : Sint16; { The relative motion in Y direction } end; { Mouse button event structure } SDL_MouseButtonEvent = record eventtype : Uint8; { SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP } which : Uint8; { The mouse device index } button : Uint8; { The mouse button index } state : Uint8; { SDL_PRESSED or SDL_RELEASED } x, y : Uint16; { The X/Y coordinates of the mouse at press time } end; { Joystick axis motion event structure } SDL_JoyAxisEvent = record eventtype : Uint8; { SDL_JOYAXISMOTION } which : Uint8; { The joystick device index } axis : Uint8; { The joystick axis index } value : Uint16; { The axis value: (range: -32768 to 32768) } end; { Joystick trackball motion event structure } SDL_JoyBallEvent = record eventtype : Uint8; { SDL_JOYBALLMOTION } which : Uint8; { The joystick device index } ball : Uint8; { The joystick trackball index } xrel : Uint16; { The relative motion in X direction } yrel : Uint16; { The relative motion in Y direction } end; { Joystick hat position change event structure } SDL_JoyHatEvent = record eventtype : Uint8; { SDL_JOYHATMOTION } which : Uint8; { The joystick device index } hat : Uint8; { The joystick hat index } value : Uint16; { The hat position value 8 1 2 7 0 3 6 5 4 Note that zero means the POV is centered. } end; { Joystick button event structure } SDL_JoyButtonEvent = record eventtype : Uint8; { SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP } which : Uint8; { The joystick device index } button : Uint8; { The joystick button index } state : Uint8; { SDL_PRESSED or SDL_RELEASED } end; { The "window resized" event When you get this event you are responsible for setting a new video mode with the new width and height. } SDL_ResizeEvent = record eventtype : Uint8; { SDL_VIDEORESIZE} w : Longint; { New width } h : Longint; { New height } end; { The "screen redraw" event } SDL_ExposeEvent = record eventtype : Uint8; { SDL_VIDEOEXPOSE } end; { The "quit requested" event } SDL_QuitEvent = record eventtype : Uint8; { SDL_QUIT } end; { A user defined event type } SDL_UserEvent = record eventtype : Uint8; { SDL_USEREVENT through SDL_NUMEVENTS-1 } code: Longint; { User defined event code } data1: Pointer; { User defined data pointer } data2: Pointer; { User defined data pointer } end; { If you want to use this event, you should include SDL_syswm.h } PSDL_SysWMmsg = ^SDL_SysWMmsg; SDL_SysWMEvent = record eventtype : Uint8; msg : PSDL_SysWMmsg; end; { General event structure } PSDL_Event = ^SDL_Event; SDL_Event = record case longint of 0 : ( eventtype : Uint8 ); 1 : ( active : SDL_ActiveEvent ); 2 : ( key : SDL_KeyboardEvent ); 3 : ( motion : SDL_MouseMotionEvent ); 4 : ( button : SDL_MouseButtonEvent ); 5 : ( jaxis : SDL_JoyAxisEvent ); 6 : ( jball : SDL_JoyBallEvent ); 7 : ( jhat : SDL_JoyHatEvent ); 8 : ( jbutton : SDL_JoyButtonEvent ); 9 : ( resize : SDL_ResizeEvent ); 10: ( expose : SDL_ExposeEvent ); 11: ( quit : SDL_QuitEvent ); 12: ( user : SDL_UserEvent ); 13: ( syswm : SDL_SysWMEvent ); end; { Function prototypes } { Pumps the event loop, gathering events from the input devices. This function updates the event queue and internal input device state. This should only be run in the thread that sets the video mode. } procedure SDL_PumpEvents;cdecl; { Checks the event queue for messages and optionally returns them. If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to the back of the event queue. If 'action' is SDL_PEEKEVENT, up to 'numevents' events at the front of the event queue, matching 'mask', will be returned and will not be removed from the queue. If 'action' is SDL_GETEVENT, up to 'numevents' events at the front of the event queue, matching 'mask', will be returned and will be removed from the queue. This function returns the number of events actually stored, or -1 if there was an error. This function is thread-safe. } type SDL_eventaction = Longint; Const SDL_ADDEVENT = 0; SDL_PEEKEVENT = 1; SDL_GETEVENT = 2; function SDL_PeepEvents(var events:SDL_Event; numevents:longint; action:SDL_eventaction; mask:Uint32):longint;cdecl; { Polls for currently pending events, and returns 1 if there are any pending events, or 0 if there are none available. If 'event' is not nil, the next event is removed from the queue and stored in that area. } function SDL_PollEvent(event:pSDL_Event):longint;cdecl; { Waits indefinitely for the next available event, returning 1, or 0 if there was an error while waiting for events. If 'event' is not nil, the next event is removed from the queue and stored in that area. } function SDL_WaitEvent(event:pSDL_Event):longint;cdecl; { Add an event to the event queue. This function returns 0, or -1 if the event couldn't be added to the event queue. If the event queue is full, this function fails. } function SDL_PushEvent (var event: SDL_Event):longint;cdecl; { This function sets up a filter to process all events before they change internal state and are posted to the internal event queue. The filter is protypted as: } type SDL_EventFilter = function (event:pSDL_Event):longint;cdecl; { If the filter returns 1, then the event will be added to the internal queue. If it returns 0, then the event will be dropped from the queue, but the internal state will still be updated. This allows selective filtering of dynamically arriving events. WARNING: Be very careful of what you do in the event filter function, as it may run in a different thread! There is one caveat when dealing with the SDL_QUITEVENT event type. The event filter is only called when the window manager desires to close the application window. If the event filter returns 1, then the window will be closed, otherwise the window will remain open if possible. If the quit event is generated by an interrupt signal, it will bypass the internal queue and be delivered to the application at the next event poll. } procedure SDL_SetEventFilter(filter:SDL_EventFilter);cdecl; { Return the current event filter - can be used to "chain" filters. If there is no filter set, this function returns nil. } function SDL_GetEventFilter:SDL_EventFilter;cdecl; { This function allows you to set the state of processing certain events. If 'state' is set to SDL_IGNORE, that event will be automatically dropped from the event queue and will not event be filtered. If 'state' is set to SDL_ENABLE, that event will be processed normally. If 'state' is set to SDL_QUERY, SDL_EventState will return the current processing state of the specified event. } const SDL_QUERY = -(1); SDL_IGNORE = 0; SDL_DISABLE = 0; SDL_ENABLE = 1; function SDL_EventState(eventtype:Uint8; state:longint):Uint8;cdecl; implementation procedure SDL_PumpEvents;cdecl;external 'SDL'; function SDL_PeepEvents(var events:SDL_Event; numevents:longint; action:SDL_eventaction; mask:Uint32):longint;cdecl;external 'SDL'; function SDL_PollEvent(event:pSDL_Event):longint;cdecl;external 'SDL'; function SDL_WaitEvent(event:pSDL_Event):longint;cdecl;external 'SDL'; function SDL_PushEvent (var event: SDL_Event):longint;cdecl;external 'SDL'; procedure SDL_SetEventFilter(filter:SDL_EventFilter);cdecl;external 'SDL'; function SDL_GetEventFilter:SDL_EventFilter;cdecl;external 'SDL'; function SDL_EventState(eventtype:Uint8; state:longint):Uint8;cdecl;external 'SDL'; end. adlibtracker2-2.4.24/sdl/README0000644000000000000000000000212713411003760014451 0ustar rootrootSDL4Freepascal-1.2.0.0 These are Freepascal units for using the SDL (Simple Directmedia Layer) library. They were made with H2PAS from the SDL-1.0.0 headers and adapted a little, then upgraded by hand to SDL 1.2. The version number is a.b.c.d where a.b.c is the version of the SDL headers, and d is a release number for this library. I haven't almost tested them, please, if (when) you find any bugs, email me to dmoisset@grulic.org.ar If you write some simple demos (in Pascal) that would be useful as examples, please, send them so I can include them in the package. Everything I will put here must be GPL or LGPL. There are some simple demos here, that are useful as a "mini-tutorial" too. This should(could) compile with Delphi, or other Pascal compilers similar to FreePascal, or by FreePascal in other platforms. If you make it work in another compiler/platform, please tell me; portability would be a nice thing to this lib. I've compiled and run it and the demos on FreePascal for windows, but haven't done more testing than that. Daniel F Moisset - dmoisset@grulic.org.aradlibtracker2-2.4.24/sdl/stdio.pp0000644000000000000000000000312413411003760015252 0ustar rootrootunit stdio; { SDL4FreePascal-1.2.0.0 - Simple DirectMedia Layer bindings for FreePascal Copyright (C) 2000, 2001 Daniel F Moisset This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Daniel F Moisset dmoisset@grulic.org.ar } { This unit groups some of the types/constants usually inside , and required to compile the other SDL units. I know, I should do this more cleanly, but I couldn't find an standard place to find this constants/types from freepascal } interface type { Some functions in SDL_rwops need a FILE* ... I don't know how to get one from freepascal } PFile = Pointer ; {FILE *} const { I should take this constants from some standard place... where? } SEEK_SET=0; { Seek from beginning of file. } SEEK_CUR=1; { Seek from current position. } SEEK_END=2; { Seek from end of file. } implementation end.adlibtracker2-2.4.24/sdl/sdl.pp0000644000000000000000000000663613411003760014725 0ustar rootrootunit SDL; { Automatically converted by H2PAS.EXE from SDL.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types; { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Main include header for the SDL library } { As of version 0.5, SDL is loaded dynamically into the application } { These are the flags which may be passed to SDL_Init() -- you should specify the subsystems which you will be using in your application. } const SDL_INIT_TIMER = $00000001; SDL_INIT_AUDIO = $00000010; SDL_INIT_VIDEO = $00000020; SDL_INIT_CDROM = $00000100; SDL_INIT_JOYSTICK = $00000200; SDL_INIT_NOPARACHUTE = $00100000; { Don't catch fatal signals } SDL_INIT_EVENTTHREAD = $01000000; { Not supported on all OS's } SDL_INIT_EVERYTHING = $0000FFFF; { This function loads the SDL dynamically linked library and initializes the subsystems specified by 'flags' (and those satisfying dependencies) Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup signal handlers for some commonly ignored fatal signals (like SIGSEGV) } function SDL_Init(flags:Uint32):longint;cdecl; { This function initializes specific SDL subsystems } function SDL_InitSubSystem(flags:Uint32):longint;cdecl; { This function cleans up specific SDL subsystems } Procedure SDL_QuitSubSystem(flags:Uint32);cdecl; { This function returns mask of the specified subsystems which have been initialized. If 'flags' is 0, it returns a mask of all initialized subsystems. } Function SDL_WasInit(flags:Uint32):Uint32;cdecl; { This function cleans up the initialized subsystems and unloads the dynamically linked library. You should call it upon all exit conditions. } procedure SDL_Quit;cdecl; implementation {$IFDEF LINUX} {$LINKLIB pthread} {$ENDIF} function SDL_Init(flags:Uint32):longint;cdecl;external 'SDL'; function SDL_InitSubSystem(flags:Uint32):longint;cdecl;external 'SDL'; Procedure SDL_QuitSubSystem(flags:Uint32);cdecl;external 'SDL'; Function SDL_WasInit(flags:Uint32):Uint32;cdecl;external 'SDL'; procedure SDL_Quit;cdecl;external 'SDL'; end. adlibtracker2-2.4.24/sdl/sdl_syswm.pp0000644000000000000000000000472413411003760016163 0ustar rootrootunit SDL_syswm; { Automatically converted by H2PAS.EXE from SDL_syswm.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } interface { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Include file for SDL custom system window manager hooks } { Your application has access to a special type of event 'SDL_SYSWMEVENT', which contains window-manager specific information and arrives whenever an unhandled window event occurs. This event is ignored by default, but you can enable it with SDL_EventState() } type pSDL_SysWMinfo = ^SDL_SysWMinfo ; SDL_SysWMinfo = record { ***Not implemented*** } end; pSDL_SysWMmsg = ^SDL_SysWMmsg ; SDL_SysWMmsg = record { ***Not implemented*** } end; { Function prototypes } { This function gives you custom hooks into the window manager information. It fills the structure pointed to by 'info' with custom information and returns 1 if the function is implemented. If it's not implemented, or the version member of the 'info' structure is invalid, it returns 0. } function SDL_GetWMInfo(info:pSDL_SysWMinfo):longint;cdecl; implementation function SDL_GetWMInfo(info:pSDL_SysWMinfo):longint;cdecl;external 'SDL'; end. adlibtracker2-2.4.24/sdl/sdl_cdrom.pp0000644000000000000000000001712313411003760016102 0ustar rootrootunit SDL_cdrom; { Automatically converted by H2PAS.EXE from SDL_cdrom.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } interface uses SDL_types ; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PLongint = ^Longint; PByte = ^Byte; PWord = ^Word; PInteger = ^Integer; PCardinal = ^Cardinal; PReal = ^Real; PDouble = ^Double; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { This is the CD-audio control API for Simple DirectMedia Layer } { In order to use these functions, SDL_Init must have been called with the SDL_INIT_CDROM flag. This causes SDL to scan the system for CD-ROM drives, and load appropriate drivers. } { The maximum number of CD-ROM tracks on a disk } const SDL_MAX_TRACKS = 99; { The types of CD-ROM track possible } SDL_AUDIO_TRACK = $00; SDL_DATA_TRACK = $04; { The possible states which a CD-ROM drive can be in. } type CDstatus = Longint; Const CD_TRAYEMPTY = 0; CD_STOPPED = 1; CD_PLAYING = 2; CD_PAUSED = 3; CD_ERROR = -(1); { Given a status, returns true if there's a disk in the drive } function CD_INDRIVE(status : longint) : longBool; type SDL_CDtrack = record id : Uint8; { Track number } track_type : Uint8; { Data or audio track } unused: Uint16; length : Uint32; { Length, in frames, of this track } offset : Uint32; { Offset, in frames, from start of disk } end; { This structure is only current as of the last call to SDL_CDStatus } PSDL_CD = ^SDL_CD ; SDL_CD = record id : longint; { Private drive identifier } status : CDstatus; { Current drive status } numtracks : longint; { The rest of this structure is only valid if there's a CD in drive } cur_track : longint; { Number of tracks on disk } cur_frame : longint; { Current track position } { Current frame offset within current track } track : array[0..SDL_MAX_TRACKS] of SDL_CDtrack; end; { Conversion functions from frames to Minute/Second/Frames and vice versa } const CD_FPS = 75; procedure FRAMES_TO_MSF(v: Longint; var m,s,f: Longint) ; { CD-audio API functions: } { Returns the number of CD-ROM drives on the system, or -1 if SDL_Init has not been called with the SDL_INIT_CDROM flag. } function SDL_CDNumDrives:Longint;cdecl; { Returns a human-readable, system-dependent identifier for the CD-ROM. Example: "/dev/cdrom" "E:" "/dev/disk/ide/1/master" } function SDL_CDName(drive:longint):Pchar;cdecl; { Opens a CD-ROM drive for access. It returns a drive handle on success, or NULL if the drive was invalid or busy. This newly opened CD-ROM becomes the default CD used when other CD functions are passed a NULL CD-ROM handle. Drives are numbered starting with 0. Drive 0 is the system default CD-ROM. } function SDL_CDOpen(drive:longint):PSDL_CD;cdecl; { This function returns the current status of the given drive. If the drive has a CD in it, the table of contents of the CD and current play position of the CD will be stored in the SDL_CD structure. } function SDL_CDStatus(var cdrom:SDL_CD):CDstatus;cdecl; { Play the given CD starting at 'start_track' and 'start_frame' for 'ntracks' tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play until the end of the CD. This function will skip data tracks. This function should only be called after calling SDL_CDStatus to get track information about the CD. For example: (* Play entire CD: *) if CD_INDRIVE(SDL_CDStatus(cdrom)) then SDL_CDPlayTracks(cdrom, 0, 0, 0, 0); (* Play last track: *) if CD_INDRIVE(SDL_CDStatus(cdrom)) then SDL_CDPlayTracks(cdrom, cdrom^.numtracks-1, 0, 0, 0); (* Play first and second track and 10 seconds of third track: *0 if CD_INDRIVE(SDL_CDStatus(cdrom)) then SDL_CDPlayTracks(cdrom, 0, 0, 2, 10); This function returns 0, or -1 if there was an error. } function SDL_CDPlayTracks(cdrom:pSDL_CD; start_track:longint; start_frame:longint; ntracks:longint; nframes:longint):longint;cdecl; { Play the given CD starting at 'start' frame for 'length' frames. It returns 0, or -1 if there was an error. } function SDL_CDPlay(cdrom:pSDL_CD; start:longint; length:longint):longint;cdecl; { Pause play -- returns 0, or -1 on error } function SDL_CDPause(cdrom:pSDL_CD):longint;cdecl; { Resume play -- returns 0, or -1 on error } function SDL_CDResume(cdrom:pSDL_CD):longint;cdecl; { Stop play -- returns 0, or -1 on error } function SDL_CDStop(cdrom:pSDL_CD):longint;cdecl; { Eject CD-ROM -- returns 0, or -1 on error } function SDL_CDEject(cdrom:pSDL_CD):longint;cdecl; { Closes the handle for the CD-ROM drive } procedure SDL_CDClose(cdrom:pSDL_CD);cdecl; implementation { Implementation of macros } function CD_INDRIVE(status : longint) : longBool; begin CD_INDRIVE:=(longint(status)) > 0; end; procedure FRAMES_TO_MSF(v: Longint; var m,s,f: Longint) ; Begin f := v mod CD_FPS ; v := v div CD_FPS ; s := v mod 60 ; v := v div 60 ; m := v ; End ; { External functions } function SDL_CDNumDrives:LongInt;cdecl;external 'SDL'; function SDL_CDName(drive:longint):Pchar;cdecl;external 'SDL'; function SDL_CDOpen(drive:longint):PSDL_CD;cdecl;external 'SDL'; function SDL_CDStatus(var cdrom:SDL_CD):CDstatus;cdecl;external 'SDL'; function SDL_CDPlayTracks(cdrom:pSDL_CD; start_track:longint; start_frame:longint; ntracks:longint; nframes:longint):longint;cdecl;external 'SDL'; function SDL_CDPlay(cdrom:pSDL_CD; start:longint; length:longint):longint;cdecl;external 'SDL'; function SDL_CDPause(cdrom:pSDL_CD):longint;cdecl;external 'SDL'; function SDL_CDResume(cdrom:pSDL_CD):longint;cdecl;external 'SDL'; function SDL_CDStop(cdrom:pSDL_CD):longint;cdecl;external 'SDL'; function SDL_CDEject(cdrom:pSDL_CD):longint;cdecl;external 'SDL'; procedure SDL_CDClose(cdrom:pSDL_CD);cdecl;external 'SDL'; end. adlibtracker2-2.4.24/sdl/INSTALL0000644000000000000000000000046613411003760014626 0ustar rootrootInstallation notes To compile the library: $ tar xzf SDL4Freepascal-1.2.0.0.tar.gz $ cd SDL4Freepascal-1.2.0.0 $ ./build.sh and to install it (as root): # mkdir /usr/lib/fpc/yourversion/units/linux/SDL4Freepascal-1.2.0.0 # mv *.o *.ppu /usr/lib/fpc/yourversion/units/linux/SDL4Freepascal-1.2.0.0adlibtracker2-2.4.24/sdl/CHANGES0000644000000000000000000000015613411003760014564 0ustar rootroot1.2.0.0 - Updated to SDL 1.2 added some demos added SDL_cdrom 1.0.0.0 - Initial releaseadlibtracker2-2.4.24/sdl/sdl_video.pp0000644000000000000000000014724113411003760016111 0ustar rootrootunit SDL_video; { Automatically converted by H2PAS.EXE from SDL_video.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types, SDL__rwops ; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PByte = ^Byte; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Header file for access to the SDL raw framebuffer window } { Useful data types } const SDL_ALPHA_OPAQUE = 255; SDL_ALPHA_TRANSPARENT = 0; type PSDL_Rect = ^SDL_Rect; SDL_Rect = record x : Sint16; y : Sint16; w : Uint16; h : Uint16; end; PSDL_RectArray = ^SDL_RectArray; SDL_RectArray = array[0..0] of SDL_Rect ; PSDL_Color = ^SDL_COLOR ; SDL_Color = record r : Uint8; g : Uint8; b : Uint8; unused : Uint8; end; PSDL_ColorArray = ^SDL_ColorArray; SDL_ColorArray = Array[0..0] of SDL_Color ; SDL_Palette = record ncolors : longint; colors : PSDL_ColorArray; end; { Everything in the pixel format structure is read-only } PSDL_PixelFormat = ^SDL_PixelFormat; SDL_PixelFormat = record palette : ^SDL_Palette; BitsPerPixel : Uint8; BytesPerPixel : Uint8; Rloss : Uint8; Gloss : Uint8; Bloss : Uint8; Aloss : Uint8; Rshift : Uint8; Gshift : Uint8; Bshift : Uint8; Ashift : Uint8; Rmask : Uint32; Gmask : Uint32; Bmask : Uint32; Amask : Uint32; { RGB color key information } colorkey : Uint32; { Alpha value information (per-surface alpha) } alpha : Uint8; end; { This structure should be treated as read-only, except for 'pixels', which, if not nil, contains the raw pixel data for the surface. } PSDL_Surface = ^SDL_Surface; SDL_Surface = record flags : Uint32; { Read only } format : ^SDL_PixelFormat; { Read only } w : longint; { Read only } h : longint; { Read only } pitch : Uint16; { Read only } pixels : pointer; { Read-write } offset : longint; { Private } { Hardware-specific surface info } hwdata : Pointer; { ***"struct private_hwdata *"*** } clip_rect: SDL_Rect; { clipping information } unused1: Uint32; { for binary compatibility } locked: Uint32; { allow recursive locks } { info for fast blit mapping to other surfaces } map : Pointer; { Private } { ***"struct SDL_BlitMap *"*** } { format version, bumped at every evrsion to invalidate blit maps } format_version: Longint; { Reference count -- used when freeing surface } refcount : longint; { Read mostly } end; SDL_blit = function (src:PSDL_Surface; srcrect:pSDL_Rect; dst:PSDL_Surface; dstrect:pSDL_Rect):longint;cdecl; { These are the currently supported flags for the SDL_surface } const { Available for SDL_CreateRGBSurface or SDL_SetVideoMode } SDL_SWSURFACE = $00000000; { Surface is in system memory } SDL_HWSURFACE = $00000001; { Surface is in video memory } SDL_ASYNCBLIT = $00000004; { Use asynchronous blits if possible } { Available for SDL_SetVideoMode } { Allow any video depth/pixel-format } SDL_ANYFORMAT = $10000000; { Surface has exclusive palette } SDL_HWPALETTE = $20000000; { Set up double-buffered video mode } SDL_DOUBLEBUF = $40000000; { Surface is a full screen display } SDL_FULLSCREEN = $80000000; { Create an OpenGL rendering context} SDL_OPENGL = $00000002; { Create an OpenGL rendering context and use it for blitting } SDL_OPENGLBLIT = $0000000A; { This video mode may be resized } SDL_RESIZABLE = $00000010; { No window caption or edge frame } SDL_NOFRAME = $00000020; { Used internally (read-only) } { Blit uses hardware acceleration } SDL_HWACCEL = $00000100; { Blit uses a source color key } SDL_SRCCOLORKEY = $00001000; { Private flag } SDL_RLEACCELOK = $00002000; { Surface is RLE encoded } SDL_RLEACCEL = $00004000; { Blit uses source alpha blending } SDL_SRCALPHA = $00010000; { Surface uses preallocated memory } SDL_PREALLOC = $01000000; { Useful for determining the video hardware capabilities } type PSDL_VideoInfo = ^SDL_VideoInfo; SDL_VideoInfo = record flag0 : longint; video_mem : Uint32; { The total amount of video memory (in K) } vfmt : ^SDL_PixelFormat; { Value: The format of the video surface } end; { *** Accessors for the flags of SDL_VideoInfo *** } { Flag: Can you create hardware surfaces? } function hw_available(var a : SDL_VideoInfo) : Uint32; procedure set_hw_available(var a : SDL_VideoInfo; __hw_available : Uint32); { Flag: Can you talk to a window manager? } function wm_available(var a : SDL_VideoInfo) : Uint32; procedure set_wm_available(var a : SDL_VideoInfo; __wm_available : Uint32); function UnusedBits1(var a : SDL_VideoInfo) : Uint32; procedure set_UnusedBits1(var a : SDL_VideoInfo; __UnusedBits1 : Uint32); function UnusedBits2(var a : SDL_VideoInfo) : Uint32; procedure set_UnusedBits2(var a : SDL_VideoInfo; __UnusedBits2 : Uint32); { Flag: Accelerated blits HW --> HW } function blit_hw(var a : SDL_VideoInfo) : Uint32; procedure set_blit_hw(var a : SDL_VideoInfo; __blit_hw : Uint32); { Flag: Accelerated blits with Colorkey } function blit_hw_CC(var a : SDL_VideoInfo) : Uint32; procedure set_blit_hw_CC(var a : SDL_VideoInfo; __blit_hw_CC : Uint32); { Flag: Accelerated blits with Alpha } function blit_hw_A(var a : SDL_VideoInfo) : Uint32; procedure set_blit_hw_A(var a : SDL_VideoInfo; __blit_hw_A : Uint32); { Flag: Accelerated blits SW --> HW } function blit_sw(var a : SDL_VideoInfo) : Uint32; procedure set_blit_sw(var a : SDL_VideoInfo; __blit_sw : Uint32); { Flag: Accelerated blits with Colorkey } function blit_sw_CC(var a : SDL_VideoInfo) : Uint32; procedure set_blit_sw_CC(var a : SDL_VideoInfo; __blit_sw_CC : Uint32); { Flag: Accelerated blits with Alpha } function blit_sw_A(var a : SDL_VideoInfo) : Uint32; procedure set_blit_sw_A(var a : SDL_VideoInfo; __blit_sw_A : Uint32); { Flag: Accelerated color fill } function blit_fill(var a : SDL_VideoInfo) : Uint32; procedure set_blit_fill(var a : SDL_VideoInfo; __blit_fill : Uint32); function UnusedBits3(var a : SDL_VideoInfo) : Uint32; procedure set_UnusedBits3(var a : SDL_VideoInfo; __UnusedBits3 : Uint32); { Evaluates to true if the surface needs to be locked before access } Function SDL_MUSTLOCK (surface: PSDL_Surface): Boolean ; { The most common video overlay formats. For an explanation of these pixel formats, see: http://www.webartz.com/fourcc/indexyuv.htm For information on the relationship between color spaces, see: http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html } const SDL_YV12_OVERLAY=$32315659; { Planar mode: Y + V + U (3 planes) } SDL_IYUV_OVERLAY=$56555949; { Planar mode: Y + U + V (3 planes) } SDL_YUY2_OVERLAY=$32595559; { Packed mode: Y0+U0+Y1+V0 (1 plane) } SDL_UYVY_OVERLAY=$59565955; { Packed mode: U0+Y0+V0+Y1 (1 plane) } SDL_YVYU_OVERLAY=$55595659; { Packed mode: Y0+V0+Y1+U0 (1 plane) } { The YUV hardware video overlay } type TSDL_Plane = Array[0..0] of Uint8; PSDL_Plane = ^TSDL_Plane; TSDL_Overlay_PlaneArray = Array[0..0] of PSDL_Plane ; PSDL_Overlay_PlaneArray = ^TSDL_Overlay_PlaneArray ; pSDL_Overlay = ^SDL_Overlay; SDL_Overlay = record format: Uint32; { Read-only } w, h: Longint; { Read-only } planes: Longint; { Read-only } pitches: ^Uint16; { Read-only } pixels: PSDL_Overlay_PlaneArray; { Read-write } { Hardware-specific surface info } hwfuncs: Pointer; { struct private_yuvhwfuncs * } hwdata: Pointer; { struct private_yuvhwdata * } { Special flags } flag0: LongInt ; end ; { *** Accessors for the flags of SDL_Overlay *** } { Flag: This overlay hardware accelerated? } function hw_overlay (var o: SDL_Overlay): Uint32; procedure set_hw_overlay (var o: SDL_Overlay; value: Uint32); const SDL_GL_RED_SIZE = 0 ; SDL_GL_GREEN_SIZE = 1 ; SDL_GL_BLUE_SIZE = 2 ; SDL_GL_ALPHA_SIZE = 3 ; SDL_GL_BUFFER_SIZE = 4 ; SDL_GL_DOUBLEBUFFER = 5 ; SDL_GL_DEPTH_SIZE = 6 ; SDL_GL_STENCIL_SIZE = 7 ; SDL_GL_ACCUM_RED_SIZE = 8 ; SDL_GL_ACCUM_GREEN_SIZE = 9 ; SDL_GL_ACCUM_BLUE_SIZE = 10 ; SDL_GL_ACCUM_ALPHA_SIZE = 11 ; type { Public enumeration for setting the OpenGL window attributes. } SDL_GLattr = LongInt ; const { flags for SDL_SetPalette() } SDL_LOGPAL = $01; SDL_PHYSPAL = $02; { Function prototypes } { These functions are used internally, and should not be used unless you have a specific need to specify the video driver you want to use. You should normally use SDL_Init or SDL_InitSubSystem. SDL_VideoInit initializes the video subsystem -- sets up a connection to the window manager, etc, and determines the current video mode and pixel format, but does not initialize a window or graphics mode. Note that event handling is activated by this routine. If you use both sound and video in your application, you need to call SDL_Init before opening the sound device, otherwise under Win32 DirectX, you won't be able to set full-screen display modes. } { SDL_VideoInit } { SDL_VideoQuit } { This function fills the given character buffer with the name of the video driver, and returns a pointer to it if the video driver has been initialized. It returns nil if no driver has been initialized. } { SDL_VideoDriverName } { This function returns a pointer to the current display surface. If SDL is doing format conversion on the display surface, this function returns the publicly visible surface, not the real video surface. } function SDL_GetVideoSurface:PSDL_Surface;cdecl; { This function returns a read-only pointer to information about the video hardware. If this is called before SDL_SetVideoMode(), the 'vfmt' member of the returned structure will contain the pixel format of the "best" video mode. } function SDL_GetVideoInfo:PSDL_VideoInfo;cdecl; { Check to see if a particular video mode is supported. It returns 0 if the requested mode is not supported under any bit depth, or returns the bits-per-pixel of the closest available mode with the given width and height. If this bits-per-pixel is different from the one used when setting the video mode, SDL_SetVideoMode will succeed, but will emulate the requested bits-per-pixel with a shadow surface. The arguments to SDL_VideoModeOK are the same ones you would pass to SDL_SetVideoMode } function SDL_VideoModeOK(width:longint; height:longint; bpp:longint; flags:Uint32):longint;cdecl; { Return a pointer to an array of available screen dimensions for the given format and video flags, sorted largest to smallest. Returns NULL if there are no dimensions available for a particular format, or (SDL_Rect )-1 if any dimension is okay for the given format. If 'format' is NULL, the mode list will be for the format given by SDL_GetVideoInfo()->vfmt } function SDL_ListModes(format:pSDL_PixelFormat; flags:Uint32):PSDL_RectArray;cdecl; { Set up a video mode with the specified width, height and bits-per-pixel. If 'bpp' is 0, it is treated as the current display bits per pixel. If SDL_ANYFORMAT is set in 'flags', the SDL library will try to set the requested bits-per-pixel, but will return whatever video pixel format is available. The default is to emulate the requested pixel format if it is not natively available. If SDL_HWSURFACE is set in 'flags', the video surface will be placed in video memory, if possible, and you may have to call SDL_LockSurface in order to access the raw framebuffer. Otherwise, the video surface will be created in system memory. If SDL_ASYNCBLIT is set in 'flags', SDL will try to perform rectangle updates asynchronously, but you must always lock before accessing pixels. SDL will wait for updates to complete before returning from the lock. If SDL_HWPALETTE is set in 'flags', the SDL library will guarantee that the colors set by SDL_SetColors will be the colors you get. Otherwise, in 8-bit mode, SDL_SetColors may not be able to set all of the colors exactly the way they are requested, and you should look at the video surface structure to determine the actual palette. If SDL cannot guarantee that the colors you request can be set, i.e. if the colormap is shared, then the video surface may be created under emulation in system memory, overriding the SDL_HWSURFACE flag. If SDL_FULLSCREEN is set in 'flags', the SDL library will try to set a fullscreen video mode. The default is to create a windowed mode if the current graphics system has a window manager. If the SDL library is able to set a fullscreen video mode, this flag will be set in the surface that is returned. If SDL_DOUBLEBUF is set in 'flags', the SDL library will try to set up two surfaces in video memory and swap between them when you call SDL_Flip. This is usually slower than the normal single-buffering scheme, but prevents "tearing" artifacts caused by modifying video memory while the monitor is refreshing. It should only be used by applications that redraw the entire screen on every update. If SDL_RESIZABLE is set in 'flags', the SDL library will allow the window manager, if any, to resize the window at runtime. When this occurs, SDL will send a SDL_VIDEORESIZE event to your application, and you must respond to the event by re-calling SDL_SetVideoMode with the requested size (or another size that suits the application). If SDL_NOFRAME is set in 'flags', the SDL library will create a window without any title bar or frame decoration. Fullscreen video modes have this flag set automatically. This function returns the video framebuffer surface, or nil if it fails. If you rely on functionality provided by certain video flags, check the flags of the returned surface to make sure that functionality is available. SDL will fall back to reduced functionality if the exact flags you wanted are not available. } function SDL_SetVideoMode(width:longint; height:longint; bpp:longint; flags:Uint32):PSDL_Surface;cdecl; { Makes sure the given list of rectangles is updated on the given screen. If 'x', 'y', 'w' and 'h' are all 0, SDL_UpdateRect will update the entire screen. These functions should not be called while 'screen' is locked. } procedure SDL_UpdateRects(screen:pSDL_Surface; numrects:longint; var rects:SDL_RectArray);cdecl; procedure SDL_UpdateRect(screen:pSDL_Surface; x:Sint32; y:Sint32; w:Uint32; h:Uint32);cdecl; { On hardware that supports double-buffering, this function sets up a flip and returns. The hardware will wait for vertical retrace, and then swap video buffers before the next video surface blit or lock will return. On hardware that doesn not support double-buffering, this is equivalent to calling SDL_UpdateRect(screen, 0, 0, 0, 0); The SDL_DOUBLEBUF flag must have been passed to SDL_SetVideoMode when setting the video mode for this function to perform hardware flipping. This function returns 0 if successful, or -1 if there was an error. } function SDL_Flip(screen:pSDL_Surface):longint;cdecl; { Set the gamma correction for each of the color channels. The gamma values range (approximately) between 0.1 and 10.0 If this function isn't supported directly by the hardware, it will be emulated using gamma ramps, if available. Iff successful, this function returns False. } function SDL_SetGamma (red, green, blue: Single): LongBool;cdecl; { Set the gamma translation table for the red, green, and blue channels of the video hardware. Each table is an array of 256 16-bit quantities, representing a mapping between the input and output for that channel. The input is the index into the array, and the output is the 16-bit gamma value at that index, scaled to the output color precision. You may pass nil for any of the channels to leave it unchanged. If the call succeeds, it will return False. If the display driver or hardware does not support gamma translation, or otherwise fails, this function will return True. } type TGammaRamp = array[Byte] of Word; PGammaRamp = ^TGammaRamp; function SDL_SetGammaRamp (red, green, blue: PGammaRamp): LongBool;cdecl; { Sets a portion of the colormap for the given 8-bit surface. If 'surface' is not a palettized surface, this function does nothing, returning 0. If all of the colors were set as passed to SDL_SetColors, it will return 1. If not all the color entries were set exactly as given, it will return 0, and you should look at the surface palette to determine the actual color palette. When 'surface' is the surface associated with the current display, the display colormap will be updated with the requested colors. If SDL_HWPALETTE was set in SDL_SetVideoMode flags, SDL_SetColors will always return 1, and the palette is guaranteed to be set the way you desire, even if the window colormap has to be warped or run under emulation. } function SDL_SetColors(surface:pSDL_Surface; var colors:SDL_ColorArray; firstcolor:longint; ncolors:longint):longint;cdecl; { Sets a portion of the colormap for a given 8-bit surface. 'flags' is one or both of: SDL_LOGPAL -- set logical palette, which controls how blits are mapped to/from the surface, SDL_PHYSPAL -- set physical palette, which controls how pixels look on the screen Only screens have physical palettes. Separate change of physical/logical palettes is only possible if the screen has SDL_HWPALETTE set. The return value is True iff all colours could be set as requested. SDL_SetColors is equivalent to calling this function with flags = (SDL_LOGPAL|SDL_PHYSPAL). } function SDL_SetPalette(surface:pSDL_Surface; flags: Longint; var colors:SDL_ColorArray; firstcolor:longint; ncolors:longint):longBool;cdecl; { Maps an RGB triple to an opaque pixel value for a given pixel format } function SDL_MapRGB(format:pSDL_PixelFormat; r, g, b:Uint8):Uint32;cdecl; { Maps an RGBA quadruple to a pixel value for a given pixel format } function SDL_MapRGBA(format:pSDL_PixelFormat; r, g, b, a:Uint8):Uint32;cdecl; { Maps a pixel value into the RGB components for a given pixel format } procedure SDL_GetRGB(pixel:Uint32; fmt:pSDL_PixelFormat; var r,g,b:Uint8);cdecl; { Maps a pixel value into the RGBA components for a given pixel format } procedure SDL_GetRGBA(pixel:Uint32; fmt:pSDL_PixelFormat; var r,g,b,a:Uint8);cdecl; { Allocate and free an RGB surface (must be called after SDL_SetVideoMode) If the depth is 4 or 8 bits, an empty palette is allocated for the surface. If the depth is greater than 8 bits, the pixel format is set using the flags '[RGB]mask'. If the function runs out of memory, it will return nil. The 'flags' tell what kind of surface to create. SDL_SWSURFACE means that the surface should be created in system memory. SDL_HWSURFACE means that the surface should be created in video memory, with the same format as the display surface. This is useful for surfaces that will not change much, to take advantage of hardware acceleration when being blitted to the display surface. SDL_ASYNCBLIT means that SDL will try to perform asynchronous blits with this surface, but you must always lock it before accessing the pixels. SDL will wait for current blits to finish before returning from the lock. SDL_SRCCOLORKEY indicates that the surface will be used for colorkey blits. If the hardware supports acceleration of colorkey blits between two surfaces in video memory, SDL will try to place the surface in video memory. If this isn't possible or if there is no hardware acceleration available, the surface will be placed in system memory. SDL_SRCALPHA means that the surface will be used for alpha blits and if the hardware supports hardware acceleration of alpha blits between two surfaces in video memory, to place the surface in video memory if possible, otherwise it will be placed in system memory. If the surface is created in video memory, blits will be _much_ faster, but the surface format must be identical to the video surface format, and the only way to access the pixels member of the surface is to use the SDL_LockSurface and SDL_UnlockSurface calls. If the requested surface actually resides in video memory, SDL_HWSURFACE will be set in the flags member of the returned surface. If for some reason the surface could not be placed in video memory, it will not have the SDL_HWSURFACE flag set, but will be created in system memory instead } function SDL_CreateRGBSurface(flags:Uint32; width:longint; height:longint; depth:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface;cdecl; { This is an alias for SDL_CreateRGBSurface} function SDL_AllocSurface(flags:Uint32; width:longint; height:longint; depth:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface; function SDL_CreateRGBSurfaceFrom(pixels:pointer; width:longint; height:longint; depth:longint; pitch:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface;cdecl; procedure SDL_FreeSurface(surface:pSDL_Surface);cdecl; { SDL_LockSurface sets up a surface for directly accessing the pixels. Between calls to SDL_LockSurface/SDL_UnlockSurface, you can write to and read from 'surface->pixels', using the pixel format stored in 'surface->format'. Once you are done accessing the surface, you should use SDL_UnlockSurface to release it. Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates to 0, then you can read and write to the surface at any time, and the pixel format of the surface will not change. In particular, if the SDL_HWSURFACE flag is not given when calling SDL_SetVideoMode, you will not need to lock the display surface before accessing it. No operating system or library calls should be made between lock/unlock pairs, as critical system locks may be held during this time. SDL_LockSurface returns 0, or -1 if the surface couldn't be locked. } function SDL_LockSurface(surface:pSDL_Surface):longint;cdecl; procedure SDL_UnlockSurface(surface:pSDL_Surface);cdecl; { Load a surface from a seekable SDL data source (memory or file.) If 'freesrc' is True, the source will be closed after being read. Returns the new surface, or nil if there was an error. The new surface should be freed with SDL_FreeSurface. } function SDL_LoadBMP_RW(src:pSDL_RWops; freesrc:LongBool):PSDL_Surface;cdecl; { Convenience macro -- load a surface from a file } function SDL_LoadBMP(filename:PChar) : PSDL_Surface; { Save a surface to a seekable SDL data source (memory or file.) If 'freedst' is True, the source will be closed after being written. Returns 0 if successful or -1 if there was an error. } function SDL_SaveBMP_RW(surface:pSDL_Surface; dst:pSDL_RWops; freedst:LongBool):longint;cdecl; { Convenience macro -- save a surface to a file } function SDL_SaveBMP(surface: pSDL_Surface;filename:PChar) : longint; { Sets the color key (transparent pixel) in a blittable surface. If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), 'key' will be the transparent pixel in the source image of a blit. SDL_RLEACCEL requests RLE acceleration for the surface if present, and removes RLE acceleration if absent. If 'flag' is 0, this function clears any current color key. This function returns 0, or -1 if there was an error. } function SDL_SetColorKey(surface:pSDL_Surface; flag:Uint32; key:Uint32):longint;cdecl; { This function sets the alpha value for the entire surface, as opposed to using the alpha component of each pixel. This value measures the range of transparency of the surface, 0 being completely transparent to 255 being completely opaque. An 'alpha' value of 255 causes blits to be opaque, the source pixels copied to the destination (the default). Note that per-surface alpha can be combined with colorkey transparency. If 'flag' is 0, alpha blending is disabled for the surface. If 'flag' is SDL_SRCALPHA, alpha blending is enabled for the surface. OR:ing the flag with SDL_RLEACCEL requests RLE acceleration for the surface; if SDL_RLEACCEL is not specified, the RLE accel will be removed. } function SDL_SetAlpha(surface:pSDL_Surface; flag:Uint32; alpha:Uint8):longint;cdecl; { Sets the clipping rectangle for the destination surface in a blit. If the clip rectangle is nil, clipping will be disabled. If the clip rectangle doesn't intersect the surface, the function will return False and blits will be completely clipped. Otherwise the function returns True and blits to the surface will be clipped to the intersection of the surface area and the clipping rectangle. Note that blits are automatically clipped to the edges of the source and destination surfaces. } function SDL_SetClipRect(surface:pSDL_Surface; rect:pSDL_Rect): SDL_Bool;cdecl; { Gets the clipping rectangle for the destination surface in a blit. 'rect' will be filled with the correct values. } procedure SDL_GetClipRect(surface: pSDL_Surface; var rect: SDL_Rect);cdecl; { Creates a new surface of the specified format, and then copies and maps the given surface to it so the blit of the converted surface will be as fast as possible. If this function fails, it returns nil. The 'flags' parameter is passed to SDL_CreateRGBSurface and has those semantics. You can also pass SDL_RLEACCEL in the flags parameter and SDL will try to RLE accelerate colorkey and alpha blits in the resulting surface. This function is used internally by SDL_DisplayFormat. } function SDL_ConvertSurface(src:pSDL_Surface; fmt:pSDL_PixelFormat; flags:Uint32):PSDL_Surface;cdecl; { This performs a fast blit from the source surface to the destination surface. It assumes that the source and destination rectangles are the same size. If either 'srcrect' or 'dstrect' are nil, the entire surface (src or dst) is copied. The final blit rectangles are saved in 'srcrect' and 'dstrect' after all clipping is performed. If the blit is successful, it returns 0, otherwise it returns -1. The blit function should not be called on a locked surface. The blit semantics for surfaces with and without alpha and colorkey are defined as follows: RGBA->RGB: SDL_SRCALPHA set: alpha-blend (using alpha-channel). SDL_SRCCOLORKEY ignored. SDL_SRCALPHA not set: copy RGB. if SDL_SRCCOLORKEY set, only copy the pixels matching the RGB values of the source colour key, ignoring alpha in the comparison. RGB->RGBA: SDL_SRCALPHA set: alpha-blend (using the source per-surface alpha value); set destination alpha to opaque. SDL_SRCALPHA not set: copy RGB, set destination alpha to opaque. both: if SDL_SRCCOLORKEY set, only copy the pixels matching the source colour key. RGBA->RGBA: SDL_SRCALPHA set: alpha-blend (using the source alpha channel) the RGB values; leave destination alpha untouched. [Note: is this correct?] SDL_SRCCOLORKEY ignored. SDL_SRCALPHA not set: copy all of RGBA to the destination. if SDL_SRCCOLORKEY set, only copy the pixels matching the RGB values of the source colour key, ignoring alpha in the comparison. RGB->RGB: SDL_SRCALPHA set: alpha-blend (using the source per-surface alpha value). SDL_SRCALPHA not set: copy RGB. both: if SDL_SRCCOLORKEY set, only copy the pixels matching the source colour key. If either of the surfaces were in video memory, and the blit returns -2, the video memory was lost, so it should be reloaded with artwork and re-blitted: while SDL_BlitSurface(image, imgrect, screen, dstrect) = -2 do Begin while SDL_LockSurface(image) < 0 do Sleep(10); -- Write image pixels to image->pixels -- SDL_UnlockSurface(image); End; This happens under DirectX 5.0 when the system switches away from your fullscreen application. The lock will also fail until you have access to the video memory again. } { You should call SDL_BlitSurface unless you know exactly how SDL blitting works internally and how to use the other blit functions. } function SDL_BlitSurface(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint; { This is the public blit function, SDL_BlitSurface, and it performs rectangle validation and clipping before passing it to SDL_LowerBlit } function SDL_UpperBlit(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint;cdecl; { This is a semi-private blit function and it performs low-level surface blitting only. } function SDL_LowerBlit(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint;cdecl; { This function performs a fast fill of the given rectangle with 'color' The given rectangle is clipped to the destination surface clip area and the final fill rectangle is saved in the passed in pointer. If 'dstrect' is nil, the whole surface will be filled with 'color' The color should be a pixel of the format used by the surface, and can be generated by the SDL_MapRGB() function. This function returns 0 on success, or -1 on error. } function SDL_FillRect(dst:pSDL_Surface; dstrect:pSDL_Rect; color:Uint32):longint;cdecl; { This function takes a surface and copies it to a new surface of the pixel format and colors of the video framebuffer, suitable for fast blitting onto the display surface. It calls SDL_ConvertSurface If you want to take advantage of hardware colorkey or alpha blit acceleration, you should set the colorkey and alpha value before calling this function. If the conversion fails or runs out of memory, it returns nil } function SDL_DisplayFormat(surface:pSDL_Surface):PSDL_Surface;cdecl; { This function takes a surface and copies it to a new surface of the pixel format and colors of the video framebuffer (if possible), suitable for fast alpha blitting onto the display surface. The new surface will always have an alpha channel. If you want to take advantage of hardware colorkey or alpha blit acceleration, you should set the colorkey and alpha value before calling this function. If the conversion fails or runs out of memory, it returns nil } function SDL_DisplayFormatAlpha(surface:pSDL_Surface):pSDL_Surface;cdecl; { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } { * YUV video surface overlay functions * } { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } { This function creates a video output overlay Calling the returned surface an overlay is something of a misnomer because the contents of the display surface underneath the area where the overlay is shown is undefined - it may be overwritten with the converted YUV data. } function SDL_CreateYUVOverlay (width, height: Longint; format: Uint32; display: pSDL_Surface): pSDL_Overlay;cdecl; { Lock an overlay for direct access, and unlock it when you are done } function SDL_LockYUVOverlay(var overlay: SDL_Overlay):Longint;cdecl; procedure SDL_UnlockYUVOverlay(var overlay: SDL_Overlay);cdecl; { Blit a video overlay to the display surface. The contents of the video surface underneath the blit destination are not defined. The width and height of the destination rectangle may be different from that of the overlay, but currently only 2x scaling is supported. } function SDL_DisplayYUVOverlay(var overlay:SDL_Overlay; var dstrect: SDL_Rect):Longint;cdecl; { Free a video overlay } procedure SDL_FreeYUVOverlay(var overlay: SDL_Overlay);cdecl; { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } { * OpenGL support functions. * } { * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * } { Dynamically load a GL driver, if SDL is built with dynamic GL. SDL links normally with the OpenGL library on your system by default, but you can compile it to dynamically load the GL driver at runtime. If you do this, you need to retrieve all of the GL functions used in your program from the dynamic library using SDL_GL_GetProcAddress(). This is disabled in default builds of SDL. } function SDL_GL_LoadLibrary(path: PChar):Longint;cdecl; { Get the address of a GL function (for extension functions) } procedure SDL_GL_GetProcAddress(proc: PChar);cdecl; { Set an attribute of the OpenGL subsystem before intialization. } function SDL_GL_SetAttribute(attr: SDL_GLattr; value: Longint):Longint;cdecl; { Get an attribute of the OpenGL subsystem from the windowing interface, such as glX. This is of course different from getting the values from SDL's internal OpenGL subsystem, which only stores the values you request before initialization. Developers should track the values they pass into SDL_GL_SetAttribute themselves if they want to retrieve these values. } function SDL_GL_GetAttribute (attr: SDL_GLattr; var value: Longint):Longint;cdecl; { Swap the OpenGL buffers, if double-buffering is supported. } Procedure SDL_GL_SwapBuffers; cdecl; { Internal functions that should not be called unless you have read and understood the source code for these functions. } {extern DECLSPEC void SDL_GL_UpdateRects(int numrects, SDL_Rect* rects); extern DECLSPEC void SDL_GL_Lock(void); extern DECLSPEC void SDL_GL_Unlock(void);} { These functions allow interaction with the window manager, if any. } { Sets/Gets the title and icon text of the display window } procedure SDL_WM_SetCaption(title:pchar; icon:pchar);cdecl; procedure SDL_WM_GetCaption(title:ppchar; icon:ppchar);cdecl; { Sets the icon for the display window. This function must be called before the first call to SDL_SetVideoMode. It takes an icon surface, and a mask in MSB format. If 'mask' is nil, the entire icon surface will be used as the icon. } procedure SDL_WM_SetIcon(icon:pSDL_Surface; mask:pByte);cdecl; implementation { *** masks for implementing the bit fields accesors of SDL_VideoInfo *** } const bm_SDL_VideoInfo_hw_available = $1; bp_SDL_VideoInfo_hw_available = 0; bm_SDL_VideoInfo_wm_available = $2; bp_SDL_VideoInfo_wm_available = 1; bm_SDL_VideoInfo_UnusedBits1 = $FC; bp_SDL_VideoInfo_UnusedBits1 = 2; bm_SDL_VideoInfo_UnusedBits2 = $100; bp_SDL_VideoInfo_UnusedBits2 = 8; bm_SDL_VideoInfo_blit_hw = $200; bp_SDL_VideoInfo_blit_hw = 9; bm_SDL_VideoInfo_blit_hw_CC = $400; bp_SDL_VideoInfo_blit_hw_CC = 10; bm_SDL_VideoInfo_blit_hw_A = $800; bp_SDL_VideoInfo_blit_hw_A = 11; bm_SDL_VideoInfo_blit_sw = $1000; bp_SDL_VideoInfo_blit_sw = 12; bm_SDL_VideoInfo_blit_sw_CC = $2000; bp_SDL_VideoInfo_blit_sw_CC = 13; bm_SDL_VideoInfo_blit_sw_A = $4000; bp_SDL_VideoInfo_blit_sw_A = 14; bm_SDL_VideoInfo_blit_fill = $8000; bp_SDL_VideoInfo_blit_fill = 15; bm_SDL_VideoInfo_UnusedBits3 = $FFFF0000; bp_SDL_VideoInfo_UnusedBits3 = 16; { *** bit fields accesors of SDL_VideoInfo *** } function hw_available(var a : SDL_VideoInfo) : Uint32; begin hw_available:=(a.flag0 and bm_SDL_VideoInfo_hw_available) shr bp_SDL_VideoInfo_hw_available; end; procedure set_hw_available(var a : SDL_VideoInfo; __hw_available : Uint32); begin a.flag0:=a.flag0 or ((__hw_available shl bp_SDL_VideoInfo_hw_available) and bm_SDL_VideoInfo_hw_available); end; function wm_available(var a : SDL_VideoInfo) : Uint32; begin wm_available:=(a.flag0 and bm_SDL_VideoInfo_wm_available) shr bp_SDL_VideoInfo_wm_available; end; procedure set_wm_available(var a : SDL_VideoInfo; __wm_available : Uint32); begin a.flag0:=a.flag0 or ((__wm_available shl bp_SDL_VideoInfo_wm_available) and bm_SDL_VideoInfo_wm_available); end; function UnusedBits1(var a : SDL_VideoInfo) : Uint32; begin UnusedBits1:=(a.flag0 and bm_SDL_VideoInfo_UnusedBits1) shr bp_SDL_VideoInfo_UnusedBits1; end; procedure set_UnusedBits1(var a : SDL_VideoInfo; __UnusedBits1 : Uint32); begin a.flag0:=a.flag0 or ((__UnusedBits1 shl bp_SDL_VideoInfo_UnusedBits1) and bm_SDL_VideoInfo_UnusedBits1); end; function UnusedBits2(var a : SDL_VideoInfo) : Uint32; begin UnusedBits2:=(a.flag0 and bm_SDL_VideoInfo_UnusedBits2) shr bp_SDL_VideoInfo_UnusedBits2; end; procedure set_UnusedBits2(var a : SDL_VideoInfo; __UnusedBits2 : Uint32); begin a.flag0:=a.flag0 or ((__UnusedBits2 shl bp_SDL_VideoInfo_UnusedBits2) and bm_SDL_VideoInfo_UnusedBits2); end; function blit_hw(var a : SDL_VideoInfo) : Uint32; begin blit_hw:=(a.flag0 and bm_SDL_VideoInfo_blit_hw) shr bp_SDL_VideoInfo_blit_hw; end; procedure set_blit_hw(var a : SDL_VideoInfo; __blit_hw : Uint32); begin a.flag0:=a.flag0 or ((__blit_hw shl bp_SDL_VideoInfo_blit_hw) and bm_SDL_VideoInfo_blit_hw); end; function blit_hw_CC(var a : SDL_VideoInfo) : Uint32; begin blit_hw_CC:=(a.flag0 and bm_SDL_VideoInfo_blit_hw_CC) shr bp_SDL_VideoInfo_blit_hw_CC; end; procedure set_blit_hw_CC(var a : SDL_VideoInfo; __blit_hw_CC : Uint32); begin a.flag0:=a.flag0 or ((__blit_hw_CC shl bp_SDL_VideoInfo_blit_hw_CC) and bm_SDL_VideoInfo_blit_hw_CC); end; function blit_hw_A(var a : SDL_VideoInfo) : Uint32; begin blit_hw_A:=(a.flag0 and bm_SDL_VideoInfo_blit_hw_A) shr bp_SDL_VideoInfo_blit_hw_A; end; procedure set_blit_hw_A(var a : SDL_VideoInfo; __blit_hw_A : Uint32); begin a.flag0:=a.flag0 or ((__blit_hw_A shl bp_SDL_VideoInfo_blit_hw_A) and bm_SDL_VideoInfo_blit_hw_A); end; function blit_sw(var a : SDL_VideoInfo) : Uint32; begin blit_sw:=(a.flag0 and bm_SDL_VideoInfo_blit_sw) shr bp_SDL_VideoInfo_blit_sw; end; procedure set_blit_sw(var a : SDL_VideoInfo; __blit_sw : Uint32); begin a.flag0:=a.flag0 or ((__blit_sw shl bp_SDL_VideoInfo_blit_sw) and bm_SDL_VideoInfo_blit_sw); end; function blit_sw_CC(var a : SDL_VideoInfo) : Uint32; begin blit_sw_CC:=(a.flag0 and bm_SDL_VideoInfo_blit_sw_CC) shr bp_SDL_VideoInfo_blit_sw_CC; end; procedure set_blit_sw_CC(var a : SDL_VideoInfo; __blit_sw_CC : Uint32); begin a.flag0:=a.flag0 or ((__blit_sw_CC shl bp_SDL_VideoInfo_blit_sw_CC) and bm_SDL_VideoInfo_blit_sw_CC); end; function blit_sw_A(var a : SDL_VideoInfo) : Uint32; begin blit_sw_A:=(a.flag0 and bm_SDL_VideoInfo_blit_sw_A) shr bp_SDL_VideoInfo_blit_sw_A; end; procedure set_blit_sw_A(var a : SDL_VideoInfo; __blit_sw_A : Uint32); begin a.flag0:=a.flag0 or ((__blit_sw_A shl bp_SDL_VideoInfo_blit_sw_A) and bm_SDL_VideoInfo_blit_sw_A); end; function blit_fill(var a : SDL_VideoInfo) : Uint32; begin blit_fill:=(a.flag0 and bm_SDL_VideoInfo_blit_fill) shr bp_SDL_VideoInfo_blit_fill; end; procedure set_blit_fill(var a : SDL_VideoInfo; __blit_fill : Uint32); begin a.flag0:=a.flag0 or ((__blit_fill shl bp_SDL_VideoInfo_blit_fill) and bm_SDL_VideoInfo_blit_fill); end; function UnusedBits3(var a : SDL_VideoInfo) : Uint32; begin UnusedBits3:=(a.flag0 and bm_SDL_VideoInfo_UnusedBits3) shr bp_SDL_VideoInfo_UnusedBits3; end; procedure set_UnusedBits3(var a : SDL_VideoInfo; __UnusedBits3 : Uint32); begin a.flag0:=a.flag0 or ((__UnusedBits3 shl bp_SDL_VideoInfo_UnusedBits3) and bm_SDL_VideoInfo_UnusedBits3); end; { *** masks for implementing the bit fields accesors of SDL_Overlay *** } const bm_SDL_Overlay_hw_overlay = $1; bp_SDL_Overlay_hw_overlay = 0; { *** bit fields accesors of SDL_Overlay *** } function hw_overlay (var o: SDL_Overlay): Uint32; Begin hw_overlay := (o.flag0 and bm_SDL_Overlay_hw_overlay) shr bp_SDL_Overlay_hw_overlay ; End; procedure set_hw_overlay (var o: SDL_Overlay; value: Uint32); Begin o.flag0 := o.flag0 or ( (value shl bp_SDL_Overlay_hw_overlay) and bm_SDL_Overlay_hw_overlay) ; End; function SDL_GetVideoSurface:PSDL_Surface;cdecl;external 'SDL'; function SDL_GetVideoInfo:PSDL_VideoInfo;cdecl;external 'SDL'; function SDL_VideoModeOK(width:longint; height:longint; bpp:longint; flags:Uint32):longint;cdecl;external 'SDL'; function SDL_ListModes(format:pSDL_PixelFormat; flags:Uint32):PSDL_RectArray;cdecl;external 'SDL'; function SDL_SetVideoMode(width:longint; height:longint; bpp:longint; flags:Uint32):PSDL_Surface;cdecl;external 'SDL'; procedure SDL_UpdateRects(screen:pSDL_Surface; numrects:longint; var rects:SDL_RectArray);cdecl;external 'SDL'; procedure SDL_UpdateRect(screen:pSDL_Surface; x:Sint32; y:Sint32; w:Uint32; h:Uint32);cdecl;external 'SDL'; function SDL_Flip(screen:pSDL_Surface):longint;cdecl;external 'SDL'; function SDL_SetGamma (red, green, blue: Single): LongBool;cdecl;external 'SDL'; function SDL_SetGammaRamp (red, green, blue: PGammaRamp): LongBool;cdecl;external 'SDL'; function SDL_SetColors(surface:pSDL_Surface; var colors:SDL_ColorArray; firstcolor:longint; ncolors:longint):longint;cdecl;external 'SDL'; function SDL_SetPalette(surface:pSDL_Surface; flags: Longint; var colors:SDL_ColorArray; firstcolor:longint; ncolors:longint):longBool;cdecl;external 'SDL'; function SDL_MapRGB(format:pSDL_PixelFormat; r:Uint8; g:Uint8; b:Uint8):Uint32;cdecl;external 'SDL'; function SDL_MapRGBA(format:pSDL_PixelFormat; r, g, b, a:Uint8):Uint32;cdecl;external 'SDL'; procedure SDL_GetRGB(pixel:Uint32; fmt:pSDL_PixelFormat; var r,g,b:Uint8);cdecl;external 'SDL'; procedure SDL_GetRGBA(pixel:Uint32; fmt:pSDL_PixelFormat; var r,g,b,a:Uint8);cdecl;external 'SDL'; function SDL_CreateRGBSurface(flags:Uint32; width:longint; height:longint; depth:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface;cdecl;external 'SDL'; function SDL_CreateRGBSurfaceFrom(pixels:pointer; width:longint; height:longint; depth:longint; pitch:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface;cdecl;external 'SDL'; procedure SDL_FreeSurface(surface:pSDL_Surface);cdecl;external 'SDL'; function SDL_LockSurface(surface:pSDL_Surface):longint;cdecl;external 'SDL'; procedure SDL_UnlockSurface(surface:pSDL_Surface);cdecl;external 'SDL'; function SDL_LoadBMP_RW(src:pSDL_RWops; freesrc:LongBool):PSDL_Surface;cdecl;external 'SDL'; function SDL_SaveBMP_RW(surface:pSDL_Surface; dst:pSDL_RWops; freedst:LongBool):longint;cdecl;external 'SDL'; function SDL_SetColorKey(surface:pSDL_Surface; flag:Uint32; key:Uint32):longint;cdecl;external 'SDL'; function SDL_SetAlpha(surface:pSDL_Surface; flag:Uint32; alpha:Uint8):longint;cdecl;external 'SDL'; function SDL_SetClipRect(surface:pSDL_Surface; rect:pSDL_Rect): SDL_Bool;cdecl;external 'SDL'; procedure SDL_GetClipRect(surface: pSDL_Surface; var rect: SDL_Rect);cdecl;external 'SDL'; function SDL_ConvertSurface(src:pSDL_Surface; fmt:pSDL_PixelFormat; flags:Uint32):PSDL_Surface;cdecl;external 'SDL'; function SDL_UpperBlit(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint;cdecl;external 'SDL'; function SDL_LowerBlit(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint;cdecl;external 'SDL'; function SDL_FillRect(dst:pSDL_Surface; dstrect:pSDL_Rect; color:Uint32):longint;cdecl;external 'SDL'; function SDL_DisplayFormat(surface:pSDL_Surface):PSDL_Surface;cdecl;external 'SDL'; function SDL_DisplayFormatAlpha(surface:pSDL_Surface):pSDL_Surface;cdecl; external 'SDL'; function SDL_CreateYUVOverlay (width, height: Longint; format: Uint32; display: pSDL_Surface): pSDL_Overlay;cdecl;external 'SDL'; function SDL_LockYUVOverlay(var overlay: SDL_Overlay):Longint;cdecl;external 'SDL'; procedure SDL_UnlockYUVOverlay(var overlay: SDL_Overlay);cdecl;external 'SDL'; function SDL_DisplayYUVOverlay(var overlay:SDL_Overlay; var dstrect: SDL_Rect):Longint;cdecl;external 'SDL'; procedure SDL_FreeYUVOverlay(var overlay: SDL_Overlay);cdecl;external 'SDL'; function SDL_GL_LoadLibrary(path: PChar):Longint;cdecl;external 'SDL'; procedure SDL_GL_GetProcAddress(proc: PChar);cdecl;external 'SDL'; function SDL_GL_SetAttribute(attr: SDL_GLattr; value: Longint):Longint;cdecl;external 'SDL'; function SDL_GL_GetAttribute (attr: SDL_GLattr; var value: Longint):Longint;cdecl; external 'SDL'; Procedure SDL_GL_SwapBuffers; cdecl; external 'SDL'; procedure SDL_WM_SetCaption(title:pchar; icon:pchar);cdecl;external 'SDL'; procedure SDL_WM_GetCaption(title:ppchar; icon:ppchar);cdecl;external 'SDL'; procedure SDL_WM_SetIcon(icon:pSDL_Surface; mask:pByte);cdecl;external 'SDL'; { Macro } Function SDL_MUSTLOCK (surface: PSDL_Surface): Boolean ; Begin SDL_MUSTLOCK := (surface^.offset<>0) or ((surface^.flags and (SDL_HWSURFACE or SDL_ASYNCBLIT or SDL_RLEACCEL)) <>0) End ; {alias for SDL_CreateRGBSurface} function SDL_AllocSurface(flags:Uint32; width:longint; height:longint; depth:longint; Rmask:Uint32; Gmask:Uint32; Bmask:Uint32; Amask:Uint32):PSDL_Surface; Begin SDL_AllocSurface := SDL_CreateRGBSurface (flags, width, height, depth, Rmask, Gmask, Bmask, Amask); End; {convenience macros} function SDL_LoadBMP(filename:PChar) : PSDL_Surface; Begin SDL_LoadBMP := SDL_LoadBMP_RW (SDL_RWFromFile(filename, 'rb'), True) End; function SDL_SaveBMP(surface: pSDL_Surface;filename:PChar) : longint; begin SDL_SaveBMP := SDL_SaveBMP_RW(surface,SDL_RWFromFile(filename,'wb'), True); end; { alias for SDL_UpperBlit } function SDL_BlitSurface(src:pSDL_Surface; srcrect:pSDL_Rect; dst:pSDL_Surface; dstrect:pSDL_Rect):longint; Begin SDL_BlitSurface := SDL_UpperBlit(src, srcrect, dst, dstrect) End ; end. adlibtracker2-2.4.24/sdl/sdl__rwops.pp0000644000000000000000000001225713411003760016312 0ustar rootrootunit SDL__rwops; { Automatically converted by H2PAS.EXE from SDL_rwops.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types, stdio; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PByte = ^Byte; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { This file provides a general interface for SDL to read and write data sources. It can easily be extended to files, memory, etc. } { This is the read/write operation structure -- very basic } type pSDL_RWops = ^SDL_RWops; SDL_RWops = record { Seek to 'offset' relative to whence, one of stdio's whence values: SEEK_SET, SEEK_CUR, SEEK_END Returns the final offset in the data source. } seek : function (context:pSDL_RWops; offset:longint; whence:longint):longint;cdecl; { Read up to 'num' objects each of size 'objsize' from the data source to the area pointed at by 'ptr'. Returns the number of objects read, or -1 if the read failed. } read : function (context:pSDL_RWops; var data; size:longint; maxnum:longint):longint; { Write exactly 'num' objects each of size 'objsize' from the area pointed at by 'ptr' to data source. Returns 'num', or -1 if the write failed. } write : function (context:pSDL_RWops; var data; size:longint; num:longint):longint; { Close and free an allocated SDL_FSops structure } close : function (context:pSDL_RWops):longint; optype : Uint32; hidden : record case longint of 0 : ( stdio : record autoclose : longint; fp : PFile; {C file *} end ); 1 : ( mem : record base : PByte; here : PByte; stop : PByte; end ); 2 : ( unknown : record data1 : pointer; end ); end; end; { Functions to create SDL_RWops structures from various data sources } function SDL_RWFromFile(filename:pchar; mode:pchar):pSDL_RWops;cdecl; function SDL_RWFromFP(fp:Pointer; autoclose:longint):pSDL_RWops;cdecl; function SDL_RWFromMem(var mem; size:longint):pSDL_RWops;cdecl; function SDL_AllocRW:pSDL_RWops;cdecl; { Macros to easily read and write from an SDL_RWops structure } function SDL_RWseek(ctx: pSDL_RWops;offset,whence : longint) : longint; function SDL_RWtell(ctx : pSDL_RWops) : longint; function SDL_RWread(ctx : pSDL_RWops; var data;size,n : longint) : longint; function SDL_RWwrite(ctx : pSDL_RWops; var data;size,n : longint) : longint; function SDL_RWclose(ctx : pSDL_RWops) : longint; implementation function SDL_RWFromFile(filename:pchar; mode:pchar):pSDL_RWops;cdecl;external 'SDL'; function SDL_RWFromFP(fp:Pointer; autoclose:longint):pSDL_RWops;cdecl;external 'SDL'; function SDL_RWFromMem(var mem; size:longint):pSDL_RWops;cdecl;external 'SDL'; function SDL_AllocRW:pSDL_RWops;cdecl;external 'SDL'; function SDL_RWseek(ctx: pSDL_RWops;offset,whence : longint) : longint; begin SDL_RWseek:=ctx^.seek(ctx,offset,whence); end; function SDL_RWtell(ctx : pSDL_RWops) : longint; begin SDL_RWtell:=ctx^.seek(ctx,0,SEEK_CUR); end; function SDL_RWread(ctx : pSDL_RWops; var data;size,n : longint) : longint; begin SDL_RWread:=ctx^.read(ctx,data,size,n); end; function SDL_RWwrite(ctx : pSDL_RWops; var data;size,n : longint) : longint; begin SDL_RWwrite:=ctx^.write(ctx,data,size,n); end; function SDL_RWclose(ctx : pSDL_RWops) : longint; begin SDL_RWclose:=ctx^.close(ctx); end; end. adlibtracker2-2.4.24/sdl/AUTHOR0000644000000000000000000000005113411003760014510 0ustar rootrootDaniel F Moisset adlibtracker2-2.4.24/sdl/sdl_audio.pp0000644000000000000000000002771413411003760016106 0ustar rootrootunit SDL_audio; { Automatically converted by H2PAS.EXE from SDL_audio.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types,SDL__rwops; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PByte = ^Byte; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } type { Access to the raw audio mixing buffer for the SDL library } { The calculated values in this structure are calculated by SDL_OpenAudio } pSDL_AudioSpec = ^SDL_AudioSpec; SDL_AudioSpec = record freq : longint; { DSP frequency -- samples per second } format : Uint16; { Audio data format } channels : Uint8; { Number of channels: 1 mono, 2 stereo } silence : Uint8; { Audio buffer silence value (calculated) } samples : Uint16; { Audio buffer size in samples } size : Uint32; { Audio buffer size in bytes (calculated) } { This function is called when the audio device needs more data. 'stream' is a pointer to the audio data buffer 'len' is the length of that buffer in bytes. Once the callback returns, the buffer will no longer be valid. Stereo samples are stored in a LRLRLR ordering. } callback : procedure (var userdata; stream:pByte; len:longint);cdecl; userdata : pointer; end; const { Audio format flags (defaults to LSB byte order) } { Unsigned 8-bit samples } AUDIO_U8 = $0008; { Signed 8-bit samples } AUDIO_S8 = $8008; { Unsigned 16-bit samples } AUDIO_U16LSB = $0010; { Signed 16-bit samples } AUDIO_S16LSB = $8010; { As above, but big-endian byte order } AUDIO_U16MSB = $1010; { As above, but big-endian byte order } AUDIO_S16MSB = $9010; AUDIO_U16 = AUDIO_U16LSB; AUDIO_S16 = AUDIO_S16LSB; type { A structure to hold a set of audio conversion filters and buffers } pSDL_AudioCVT = ^SDL_AudioCVT; SDL_FilterFunction = procedure (cvt:pSDL_AudioCVT; format:Uint16);cdecl; SDL_AudioCVT = record needed : longint; { Set to 1 if conversion possible } src_format : Uint16; { Source audio format } dst_format : Uint16; { Target audio format } rate_incr : double; { Rate conversion increment } buf : ^Uint8; { Buffer to hold entire audio data } len : longint; { Length of original audio buffer } len_cvt : longint; { Length of converted audio buffer } len_mult : longint; { buffer must be len*len_mult big } len_ratio : double; { Given len, final size is len*len_ratio } filters : array[0..9] of SDL_FilterFunction; filter_index : longint;{ Current audio conversion function } end; { Function prototypes } { This function opens the audio device with the desired parameters, and returns 0 if successful, placing the actual hardware parameters in the structure pointed to by 'obtained'. If 'obtained' is nil, the audio data passed to the callback function will be guaranteed to be in the requested format, and will be automatically converted to the hardware audio format if necessary. This function returns -1 if it failed to open the audio device, or couldn't set up the audio thread. When filling in the desired audio spec structure, 'desired^.freq' should be the desired audio frequency in samples-per-second. 'desired^.format' should be the desired audio format. 'desired^.samples' is the desired size of the audio buffer, in samples. This number should be a power of two, and may be adjusted by the audio driver to a value more suitable for the hardware. Good values seem to range between 512 and 8096 inclusive, depending on the application and CPU speed. Smaller values yield faster response time, but can lead to underflow if the application is doing heavy processing and cannot fill the audio buffer in time. A stereo sample consists of both right and left channels in LR ordering. Note that the number of samples is directly related to time by the following formula: ms = (samples*1000)/freq 'desired^.size' is the size in bytes of the audio buffer, and is calculated by SDL_OpenAudio. 'desired^.silence' is the value used to set the buffer to silence, and is calculated by SDL_OpenAudio. 'desired^.callback' should be set to a function that will be called when the audio device is ready for more data. It is passed a pointer to the audio buffer, and the length in bytes of the audio buffer. This function usually runs in a separate thread, and so you should protect data structures that it accesses by calling SDL_LockAudio and SDL_UnlockAudio in your code. 'desired^.userdata' is passed as the first parameter to your callback function. The audio device starts out playing silence when it's opened, and should be enabled for playing by calling SDL_PauseAudio(0) when you are ready for your audio callback function to be called. Since the audio driver may modify the requested size of the audio buffer, you should allocate any local mixing buffers after you open the audio device. } function SDL_OpenAudio(desired, obtained:pSDL_AudioSpec):longint;cdecl; type SDL_audiostatus = Longint; Const SDL_AUDIO_STOPPED = 0 ; SDL_AUDIO_PLAYING = 1 ; SDL_AUDIO_PAUSED = 2 ; { Get the current audio state } Function SDL_GetAudioStatus: SDL_audiostatus; cdecl; { This function pauses and unpauses the audio callback processing. It should be called with a parameter of 0 after opening the audio device to start playing sound. This is so you can safely initialize data for your callback function after opening the audio device. Silence will be written to the audio device during the pause. } procedure SDL_PauseAudio(pause_on:longint);cdecl; { This function loads a WAVE from the data source, automatically freeing that source if 'freesrc' is True. For example, to load a WAVE file, you could do: SDL_LoadWAV_RW(SDL_RWFromFile('sample.wav', 'rb'), 1, ...); If this function succeeds, it returns the given SDL_AudioSpec, filled with the audio data format of the wave data, and sets 'audio_buf' to a getmem'd buffer containing the audio data, and sets 'audio_len' to the length of that audio buffer, in bytes. You need to free the audio buffer with SDL_FreeWAV when you are done with it. This function returns nil and sets the SDL error message if the wave file cannot be opened, uses an unknown data format, or is corrupt. Currently raw and MS-ADPCM WAVE files are supported. } function SDL_LoadWAV_RW(src:pSDL_RWops; freesrc:LongBool; spec:pSDL_AudioSpec; var audio_buf:pByte; var audio_len:Uint32):pSDL_AudioSpec;cdecl; { Compatibility convenience function -- loads a WAV from a file } function SDL_LoadWAV(filename:PChar; spec:pSDL_AudioSpec; var audio_buf:pByte; var audio_len : Uint32) : pSDL_AudioSpec; { This function frees data previously allocated with SDL_LoadWAV_RW } procedure SDL_FreeWAV(audio_buf:pByte);cdecl; { This function takes a source format and rate and a destination format and rate, and initializes the 'cvt' structure with information needed by SDL_ConvertAudio to convert a buffer of audio data from one format to the other. This function returns 0, or -1 if there was an error. } function SDL_BuildAudioCVT(cvt:pSDL_AudioCVT; src_format:Uint16; src_channels:Uint8; src_rate:longint; dst_format:Uint16; dst_channels:Uint8; dst_rate:longint):longint;cdecl; { Once you have initialized the 'cvt' structure using SDL_BuildAudioCVT, created an audio buffer cvt^.buf, and filled it with cvt^.len bytes of audio data in the source format, this function will convert it in-place to the desired format. The data conversion may expand the size of the audio data, so the buffer cvt^.buf should be allocated after the cvt structure is initialized by SDL_BuildAudioCVT, and should be cvt^.len*cvt^.len_mult bytes long. } function SDL_ConvertAudio(cvt:pSDL_AudioCVT):longint;cdecl; const SDL_MIX_MAXVOLUME = 128; { This takes two audio buffers of the playing audio format and mixes them, performing addition, volume adjustment, and overflow clipping. The volume ranges from 0 - 128, and should be set to SDL_MIX_MAXVOLUME for full audio volume. Note this does not change hardware volume. This is provided for convenience -- you can mix your own audio data. } procedure SDL_MixAudio(dst:pByte; src:pByte; len:Uint32; volume:longint);cdecl; { The lock manipulated by these functions protects the callback function. During a LockAudio/UnlockAudio pair, you can be guaranteed that the callback function is not running. Do not call these from the callback function or you will cause deadlock. } procedure SDL_LockAudio;cdecl; procedure SDL_UnlockAudio;cdecl; { This function shuts down audio processing and closes the audio device. } procedure SDL_CloseAudio;cdecl; implementation function SDL_OpenAudio(desired, obtained:pSDL_AudioSpec):longint;cdecl;external 'SDL'; Function SDL_GetAudioStatus: SDL_audiostatus;cdecl;external 'SDL'; procedure SDL_PauseAudio(pause_on:longint);cdecl;external 'SDL'; function SDL_LoadWAV_RW(src:pSDL_RWops; freesrc:LongBool; spec:pSDL_AudioSpec; var audio_buf:pByte; var audio_len:Uint32):pSDL_AudioSpec;cdecl;external 'SDL'; function SDL_LoadWAV(filename:PChar; spec:pSDL_AudioSpec; var audio_buf:pByte; var audio_len : Uint32) : pSDL_AudioSpec; begin SDL_LoadWAV:=SDL_LoadWAV_RW(SDL_RWFromFile(filename,'rb'),True,spec,audio_buf,audio_len); end; procedure SDL_FreeWAV(audio_buf:pByte);cdecl;external 'SDL'; function SDL_BuildAudioCVT(cvt:pSDL_AudioCVT; src_format:Uint16; src_channels:Uint8; src_rate:longint; dst_format:Uint16; dst_channels:Uint8; dst_rate:longint):longint;cdecl;external 'SDL'; function SDL_ConvertAudio(cvt:pSDL_AudioCVT):longint;cdecl;external 'SDL'; procedure SDL_MixAudio(dst:pByte; src:pByte; len:Uint32; volume:longint);cdecl;external 'SDL'; procedure SDL_LockAudio;cdecl;external 'SDL'; procedure SDL_UnlockAudio;cdecl;external 'SDL'; procedure SDL_CloseAudio;cdecl;external 'SDL'; end. adlibtracker2-2.4.24/sdl/sdl_copying.inc0000644000000000000000000000160613411003760016577 0ustar rootroot{ SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } adlibtracker2-2.4.24/sdl/sdl_mouse.pp0000644000000000000000000001324013411003760016122 0ustar rootrootunit SDL_mouse; { Automatically converted by H2PAS.EXE from SDL_mouse.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types, SDL_video ; { C default packing is dword } {$PACKRECORDS 4} { Pointers to basic pascal types, inserted by h2pas conversion program.} Type PByte = ^Byte; { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Include file for SDL mouse event handling } type { Implementation dependent } WMcursor = Pointer; pSDL_Cursor = ^SDL_Cursor ; SDL_Cursor = record area : SDL_Rect; { The area of the mouse cursor } hot_x : Sint16; hot_y : Sint16; { The "tip" of the cursor } data : ^Uint8; { B/W cursor data } mask : ^Uint8; { B/W cursor mask } save : array[0..1] of ^Uint8; { Place to save cursor area } wm_cursor : ^WMcursor; { Window-manager cursor } end; { Function prototypes } { Retrieve the current state of the mouse. The current button state is returned as a button bitmask, which can be tested using the SDL_BUTTON(X) function, and x and y are set to the current mouse cursor position. } function SDL_GetMouseState(var x:longint; var y:longint):Uint8;cdecl; { Retrieve the current state of the mouse. The current button state is returned as a button bitmask, which can be tested using the SDL_BUTTON(X) function, and x and y are set to the mouse deltas since the last call to SDL_GetRelativeMouseState. } function SDL_GetRelativeMouseState(var x:longint; var y:longint):Uint8;cdecl; { Set the position of the mouse cursor (generates a mouse motion event) } procedure SDL_WarpMouse(x:Uint16; y:Uint16);cdecl; { Create a cursor using the specified data and mask (in MSB format). The cursor width must be a multiple of 8 bits. The cursor is created in black and white according to the following: data mask resulting pixel on screen 0 1 White 1 1 Black 0 0 Transparent 1 0 Inverted color if possible, black if not. Cursors created with this function must be freed with SDL_FreeCursor. } function SDL_CreateCursor(data:pByte; mask:pByte; w:longint; h:longint; hot_x:longint; hot_y:longint):pSDL_Cursor;cdecl; { Set the currently active cursor to the specified one. If the cursor is currently visible, the change will be immediately represented on the display. } procedure SDL_SetCursor(cursor:pSDL_Cursor);cdecl; { Returns the currently active cursor. } function SDL_GetCursor:pSDL_Cursor;cdecl; { Deallocates a cursor created with SDL_CreateCursor. } procedure SDL_FreeCursor(cursor:pSDL_Cursor);cdecl; { Toggle whether or not the cursor is shown on the screen. The cursor start off displayed, but can be turned off. SDL_ShowCursor returns True iff the cursor was being displayed before the call. You can query the current state passing a 'toggle' value of -1 } function SDL_ShowCursor(toggle:Longint):LongBool;cdecl; { Used as a mask when testing buttons in buttonstate Button 1: Left mouse button Button 2: Middle mouse button Button 3: Right mouse button } function SDL_BUTTON(X : Uint8) : Uint8; const SDL_BUTTON_LEFT = 1; SDL_BUTTON_MIDDLE = 2; SDL_BUTTON_RIGHT = 3; SDL_BUTTON_LMASK = 1 shl SDL_BUTTON_LEFT; SDL_BUTTON_MMASK = 1 shl SDL_BUTTON_MIDDLE; SDL_BUTTON_RMASK = 1 shl SDL_BUTTON_RIGHT; implementation function SDL_GetMouseState(var x:longint; var y:longint):Uint8;cdecl;external 'SDL'; function SDL_GetRelativeMouseState(var x:longint; var y:longint):Uint8;cdecl;external 'SDL'; procedure SDL_WarpMouse(x:Uint16; y:Uint16);cdecl;external 'SDL'; function SDL_CreateCursor(data:pByte; mask:pByte; w:longint; h:longint; hot_x:longint; hot_y:longint):pSDL_Cursor;cdecl;external 'SDL'; procedure SDL_SetCursor(cursor:pSDL_Cursor);cdecl;external 'SDL'; function SDL_GetCursor:pSDL_Cursor;cdecl;external 'SDL'; procedure SDL_FreeCursor(cursor:pSDL_Cursor);cdecl;external 'SDL'; function SDL_ShowCursor(toggle:longint):longBool;cdecl;external 'SDL'; function SDL_BUTTON(X : Uint8 ) : Uint8; begin SDL_BUTTON:=SDL_PRESSED shl (X - 1); end; end. adlibtracker2-2.4.24/sdl/sdl_timer.pp0000644000000000000000000001224613411003760016117 0ustar rootrootunit SDL_timer; { Automatically converted by H2PAS.EXE from SDL_timer.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface uses SDL_types; { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { Header for the SDL time management routines } const { This is the OS scheduler timeslice, in milliseconds } SDL_TIMESLICE = 10; { This is the maximum resolution of the timer on all platforms } TIMER_RESOLUTION = 10; { Experimentally determined } { Get the number of milliseconds since the SDL library initialization. Note that this value wraps if the program runs for more than ~49 days. } function SDL_GetTicks:Uint32;cdecl; { Wait a specified number of milliseconds before returning } procedure SDL_Delay(ms:Uint32);cdecl; type { Function prototype for the timer callback function } SDL_TimerCallback = function (interval:Uint32):Longbool;cdecl; { Set a callback to run after the specified number of milliseconds has elapsed. The callback function is passed the current timer interval and returns the next timer interval. If the returned value is the same as the one passed in, the periodic alarm continues, otherwise a new alarm is scheduled. If the callback returns False, the periodic alarm is cancelled. To cancel a currently running timer, call SDL_SetTimer(0, nil); The timer callback function may run in a different thread than your main code, and so shouldn't call any functions from within itself. The maximum resolution of this timer is 10 ms, which means that if you request a 16 ms timer, your callback will run approximately 20 ms later on an unloaded system. If you wanted to set a flag signaling a frame update at 30 frames per second (every 33 ms), you might set a timer for 30 ms: SDL_SetTimer((33 div 10)*10, flag_update); If you use this function, you need to pass SDL_INIT_TIMER to SDL_Init. Under UNIX, you should not use raise or use SIGALRM and this function in the same program, as it is implemented using setitimer(). You also should not use this function in multi-threaded applications as signals to multi-threaded apps have undefined behavior in some implementations. } function SDL_SetTimer(interval:Uint32; callback:SDL_TimerCallback):longint;cdecl; { New timer API, supports multiple timers Written by Stephane Peter } { Function prototypye for the new timer callback function. The callback function is passed the current timer interval and returns the next timer interval. If the returned value is the same as the one passed in, the periodic alarm continues, otherwise a new alarm is scheduled. If the callback returns 0, the periodic alarm is cancelled. } type SDL_NewTimerCallback = function (interval: Uint32; param: Pointer):Uint32; cdecl; _SDL_TimerID = record end ; { No public Data} SDL_TimerID = ^_SDL_TimerID ; { Add a new timer to the pool of timers already running. Returns a timer ID, or Nil when an error occurs. } function SDL_AddTimer (interval: Uint32; callback: SDL_NewTimerCallback; param: Pointer): SDL_TimerID ; cdecl; { Remove one of the multiple timers knowing its ID. Returns a boolean value indicating success. } function SDL_RemoveTimer (t: SDL_TimerID): SDL_bool;cdecl; implementation function SDL_GetTicks:Uint32;cdecl;external 'SDL'; procedure SDL_Delay(ms:Uint32);cdecl;external 'SDL'; function SDL_SetTimer(interval:Uint32; callback:SDL_TimerCallback):longint;cdecl;external 'SDL'; function SDL_AddTimer (interval: Uint32; callback: SDL_NewTimerCallback; param: Pointer): SDL_TimerID ; cdecl;external 'SDL'; function SDL_RemoveTimer (t: SDL_TimerID): SDL_bool;cdecl;external 'SDL'; end. adlibtracker2-2.4.24/sdl/sdl_types.pp0000644000000000000000000000374613411003760016150 0ustar rootrootunit SDL_types; { Automatically converted by H2PAS.EXE from SDL_types.h Utility made by Florian Klaempfl 25th-28th september 96 Improvements made by Mark A. Malakanov 22nd-25th may 97 Further improvements by Michael Van Canneyt, April 1998 define handling and error recovery by Pierre Muller, June 1998 } { ***Edited by Daniel F Moisset, dmoisset@grulic.org.ar*** } interface { C default packing is dword } {$PACKRECORDS 4} { SDL - Simple DirectMedia Layer Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Sam Lantinga slouken@devolution.com } { General data types used by the SDL library } { /* The number of elements in a table */ #define SDL_TABLESIZE(table) (sizeof(table)/sizeof(table[0])) } { Basic data types } type Uint8 = byte; Sint8 = shortint; Uint16 = word; Sint16 = SmallInt; Uint32 = cardinal; Sint32 = Longint; Uint64 = record hi, lo: Uint32 ; end ; SDL_Bool = LongBool ; { General keyboard/mouse state definitions } const SDL_PRESSED = 1 ; SDL_RELEASED = 0; implementation end. adlibtracker2-2.4.24/sdl/COPYING0000644000000000000000000006222213411003760014626 0ustar rootroot GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! adlibtracker2-2.4.24/sdl/TODO0000644000000000000000000000243113411003760014257 0ustar rootroot* Implement sdl_SysWM* structures (in a 'portable' fashion) I should make a different structure for each platform and choose with {$ifdef}s... It's done that way in . Now they're empty structures, regardless of the platform. * Get a better name for sdl__rwops The reason for the double underscore is that there is a structure there called SDL_rwops, and I can't repeat that identifier in the unit name (and don't want to change the name of the record). If you find a better idea for a name of this unit, tell me. * Find a better solution for the stdio.pp issue Read the source. This unit is a hack. * Test it!!!! I've just barely tested some part of it. There's almost no code, just external definitions, so it won't be very bad, but you never know... At least it compiles :-) * Packages (source&binary RPM/DEBs) instead of this ugly tarball... * Remaining SDL modules active, byteorder, endian, error, main, mutex, quit, thread, version are not implemented yet. I'll do this soon (I may decide not to implement some of them)... * Make a real build/install/clean script The current one only builds, and compiles some units twice (Ok, I know, I should write a Makefile) adlibtracker2-2.4.24/adt2ext2.pas0000644000000000000000000014365213411003760015162 0ustar rootroot// 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 AdT2ext2; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const quick_mark_type: Byte = 0; discard_block: Boolean = FALSE; old_chan_pos: Byte = 1; old_hpos: Byte = 1; old_page: Byte = 0; old_block_chan_pos: Byte = 1; old_block_patt_hpos: Byte = 1; old_block_patt_page: Byte = 0; procedure process_global_keys; procedure PROGRAM_SCREEN_init; function INSTRUMENT_CONTROL_alt(instr: Byte; title: String): Byte; procedure INSTRUMENT_test(instr,instr2,chan: Byte; fkey: Word; process_macros: Boolean); procedure INSTRUMENT_CONTROL_page_refresh(page: Byte); procedure INSTRUMENT_CONTROL_edit; procedure PATTERN_ORDER_page_refresh(page: Byte); procedure PATTERN_ORDER_edit(var page,hpos,vpos: Byte); procedure PATTERN_tabs_refresh; procedure PATTERN_page_refresh(page: Byte); procedure STATUS_LINE_refresh; procedure PATTERN_position_preview(pattern,line,channel,mode: Byte); function PATTERN_trace: Word; procedure PATTERN_edit(var pattern,page,hpos: Byte); procedure process_config_file; function _1st_marked: Byte; function _2nd_marked: Byte; function marked_instruments: Byte; procedure reset_marked_instruments; function get_4op_to_test: Word; function check_4op_to_test: Word; function check_4op_instrument(ins: Byte): Word; function check_4op_flag(ins: Byte): Boolean; procedure reset_4op_flag(ins: Byte); procedure set_4op_flag(ins: Byte); procedure update_4op_flag_marks; implementation uses {$IFNDEF UNIX} CRT, {$ENDIF} {$IFDEF GO32V2} GO32, {$ELSE} SDL_Timer, {$ENDIF} StrUtils, AdT2opl3,AdT2unit,AdT2sys,AdT2extn,AdT2ext4,AdT2ext5,AdT2text,AdT2pack,AdT2keyb, TxtScrIO,StringIO,DialogIO,ParserIO; var old_pattern_patt,old_pattern_page, old_pattern_hpos, old_block_xstart,old_block_ystart: Byte; old_marking: Boolean; {$i instedit.inc} {$i ipattord.inc} {$i ipattern.inc} procedure FADE_OUT_RECORDING; {$IFNDEF GO32V2} const frame_start: Longint = 0; frame_end: Longint = 0; actual_frame_end: Longint = 0; var xstart,ystart: Byte; temp,temp2: Byte; label _jmp1,_end; begin If (play_status = isStopped) or (sdl_opl3_emulator = 0) then begin sdl_opl3_emulator := 0; opl3_channel_recording_mode := FALSE; EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' WAV RECORDER ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; show_progress(40); ShowStr(screen_ptr,xstart+2,ystart+1, 'FADiNG OUT WAV RECORDiNG...', dialog_background+dialog_text); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_num_steps := 1; progress_step := 1; progress_value:= 63; progress_old_value := BYTE_NULL; For temp := 63 downto 0 do begin If scankey(1) then GOTO _jmp1; fade_out_volume := temp; set_global_volume; show_progress(temp); For temp2 := 1 to 10 do begin If scankey(1) then GOTO _jmp1; keyboard_reset_buffer; actual_frame_end := SDL_GetTicks; frame_end := frame_start+fade_delay_tab[temp]; If (actual_frame_end+fade_delay_tab[temp] > frame_end) then begin frame_end := actual_frame_end; _draw_screen_without_delay := TRUE; draw_screen; end; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; end; _draw_screen_without_delay := TRUE; draw_screen; end; _jmp1: show_progress(0); ShowStr(screen_ptr,xstart+2,ystart+1, 'FADiNG iN SONG PLAYBACK... ', dialog_background+dialog_text); flush_WAV_data; sdl_opl3_emulator := 0; opl3_channel_recording_mode := FALSE; For temp := 0 to 63 do begin If scankey(1) then GOTO _end; fade_out_volume := temp; set_global_volume; show_progress(temp); If scankey(1) then GOTO _end; _draw_screen_without_delay := TRUE; draw_screen; keyboard_reset_buffer; actual_frame_end := SDL_GetTicks; frame_end := frame_start+5; If (actual_frame_end > frame_end) then frame_end := actual_frame_end; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; end; _end: flush_WAV_data; sdl_opl3_emulator := 0; opl3_channel_recording_mode := FALSE; fade_out_volume := 63; set_global_volume; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; {$ELSE} begin {$ENDIF} end; procedure FADE_IN_RECORDING; {$IFNDEF GO32V2} const frame_start: Longint = 0; frame_end: Longint = 0; actual_frame_end: Longint = 0; var xstart,ystart: Byte; temp,temp2: Byte; smooth_fadeOut: Boolean; label _end; begin If (sdl_opl3_emulator = 1) or (calc_following_order(0) = -1) then EXIT; If (play_status = isStopped) then smooth_fadeOut := FALSE else smooth_fadeOut := TRUE; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; dl_environment.context := ' ESC '#196#16' STOP '; centered_frame(xstart,ystart,43,3,' WAV RECORDER ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(screen_ptr,xstart+43-Length(dl_environment.context),ystart+3, dl_environment.context, dialog_background+dialog_border); dl_environment.context := ''; progress_xstart := xstart+2; progress_ystart := ystart+2; progress_num_steps := 1; progress_step := 1; progress_value:= 63; progress_old_value := BYTE_NULL; If smooth_fadeOut then begin show_progress(40); ShowStr(screen_ptr,xstart+2,ystart+1, 'FADiNG OUT SONG PLAYBACK...', dialog_background+dialog_text); For temp := 63 downto 0 do begin If scankey(1) then GOTO _end; fade_out_volume := temp; set_global_volume; show_progress(temp); _draw_screen_without_delay := TRUE; draw_screen; keyboard_reset_buffer; actual_frame_end := SDL_GetTicks; frame_end := frame_start+5; If (actual_frame_end > frame_end) then frame_end := actual_frame_end; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; If scankey(1) then GOTO _end; end; end else SDL_Delay(100); show_progress(0); ShowStr(screen_ptr,xstart+2,ystart+1, 'FADiNG iN WAV RECORDiNG... ', dialog_background+dialog_text); Case play_status of isStopped: begin If trace_by_default then tracing := TRUE; start_playing; end; isPaused: begin replay_forbidden := FALSE; play_status := isPlaying; end; end; fade_out_playback(FALSE); sdl_opl3_emulator := 1; For temp := 0 to 63 do begin If scankey(1) then GOTO _end; fade_out_volume := temp; set_global_volume; show_progress(temp); _draw_screen_without_delay := TRUE; draw_screen; For temp2 := 1 to 10 do begin If scankey(1) then GOTO _end; keyboard_reset_buffer; actual_frame_end := SDL_GetTicks; frame_end := frame_start+fade_delay_tab[temp]; If (actual_frame_end+fade_delay_tab[temp] > frame_end) then begin frame_end := actual_frame_end; _draw_screen_without_delay := TRUE; draw_screen; end; SDL_Delay(frame_end-actual_frame_end); frame_start := SDL_GetTicks; end; _draw_screen_without_delay := TRUE; draw_screen; end; _end: sdl_opl3_emulator := 1; fade_out_volume := 63; set_global_volume; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; {$ELSE} begin {$ENDIF} end; procedure process_global_keys; var temp,temp2: Byte; start_row,end_row: Byte; chunk: tCHUNK; begin If NOT ins_trailing_flag and ctrl_pressed then If scankey(SC_1) then current_octave := 1 else If scankey(SC_2) then current_octave := 2 else If scankey(SC_3) then current_octave := 3 else If scankey(SC_4) then current_octave := 4 else If scankey(SC_5) then current_octave := 5 else If scankey(SC_6) then current_octave := 6 else If scankey(SC_7) then current_octave := 7 else If scankey(SC_8) then current_octave := 8; If alt_pressed and NOT ctrl_pressed then If scankey(SC_PLUS) or (shift_pressed and scankey(SC_UP)) then begin If (overall_volume < 63) then begin Inc(overall_volume); set_global_volume; end; end else If scankey(SC_MINUS2) or (shift_pressed and scankey(SC_DOWN)) then begin If (overall_volume > 0) then begin Dec(overall_volume); set_global_volume; end; end; If ctrl_pressed and NOT alt_pressed and NOT scankey(SC_TAB) and (scankey(SC_UP) or scankey(SC_DOWN)) then begin If scankey(SC_UP) and scankey(SC_DOWN) then begin _IRQ_freq_shift_reset_flag := TRUE; If NOT shift_pressed then IRQ_freq_shift := songdata.bpm_data.tempo_finetune else IRQ_freq_shift := 0 end else If scankey(SC_UP) and NOT scankey(SC_DOWN) and (SUCC(IRQ_freq+IRQ_freq_shift+playback_speed_shift) <= MAX_IRQ_FREQ) then If (NOT shift_pressed or (shift_pressed and NOT (_IRQFREQ_blink_flag and (_IRQFREQ_blink_ticks < 5)))) and NOT (_IRQ_freq_shift_reset_flag and _IRQFREQ_blink_flag and (_IRQFREQ_blink_ticks < 5)) then begin Inc(IRQ_freq_shift); _IRQ_freq_shift_reset_flag := FALSE; end else else If NOT scankey(SC_UP) and scankey(SC_DOWN) and (PRED(IRQ_freq+IRQ_freq_shift+playback_speed_shift) >= MIN_IRQ_FREQ) then If (NOT shift_pressed or (shift_pressed and NOT (_IRQFREQ_blink_flag and (_IRQFREQ_blink_ticks < 5)))) and NOT (_IRQ_freq_shift_reset_flag and _IRQFREQ_blink_flag and (_IRQFREQ_blink_ticks < 5)) then begin Dec(IRQ_freq_shift); _IRQ_freq_shift_reset_flag := FALSE; end; If (songdata.bpm_data.tempo_finetune <> IRQ_freq_shift) then module_archived := FALSE; _IRQFREQ_update_event := TRUE; _IRQFREQ_blink_flag := TRUE; _IRQFREQ_blink_ticks := 0; TimerSetup(IRQ_freq+IRQ_freq_shift+playback_speed_shift); keyboard_reset_buffer; end; {$IFNDEF GO32V2} If scankey(SC_F11) and ((alt_pressed and NOT ctrl_pressed) or (ctrl_pressed and NOT alt_pressed)) then begin If ctrl_pressed and NOT opl3_flushmode and ((sdl_opl3_emulator = 0) or (play_status = isStopped)) then begin opl3_channel_recording_mode := TRUE; track_notes := FALSE; If shift_pressed then sdl_opl3_emulator := 0; end; If NOT shift_pressed then sdl_opl3_emulator := 1 else FADE_IN_RECORDING; keyboard_reset_buffer; end; If scankey(SC_F12) and ((alt_pressed and NOT ctrl_pressed) or (ctrl_pressed and NOT alt_pressed)) then begin If NOT shift_pressed then begin flush_WAV_data; sdl_opl3_emulator := 0; opl3_channel_recording_mode := FALSE; end else FADE_OUT_RECORDING; keyboard_reset_buffer; end; {$ENDIF} If track_notes and scankey(SC_BACKSPACE) then begin If NOT ctrl_pressed then begin start_row := pattern_page; end_row := pattern_page; end else begin start_row := 0; end_row := songdata.patt_len; end; For temp2 := start_row to end_row do For temp := 1 to nm_track_chan do If channel_flag[track_chan_start+temp-1] then begin chunk := pattdata^[pattern_patt DIV 8][pattern_patt MOD 8] [track_chan_start+temp-1][temp2]; chunk.note := 0; chunk.instr_def := 0; pattdata^[pattern_patt DIV 8][pattern_patt MOD 8] [track_chan_start+temp-1][temp2] := chunk; end; end; end; procedure PROGRAM_SCREEN_init; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:PROGRAM_SCREEN_init'; {$ENDIF} fr_setting.shadow_enabled := FALSE; Frame(screen_ptr,01,MAX_PATTERN_ROWS+12,MAX_COLUMNS,MAX_PATTERN_ROWS+22, main_background+main_border,'', main_background+main_title, frame_double); Frame(screen_ptr,01,01,MAX_COLUMNS,MAX_PATTERN_ROWS+12, main_background+main_border,'- '+_ADT2_TITLE_STRING_+' -', main_background+main_border, frame_single); Frame(screen_ptr,02,02,24,07, status_background+status_border,' STATUS ', status_background+status_border, frame_double); Frame(screen_ptr,25,02,25+MAX_ORDER_COLS*7-1+PATTORD_xshift*2,07, order_background+order_border,' PATTERN ORDER ( ) ', order_background+order_border, frame_double); fr_setting.shadow_enabled := TRUE; area_x1 := 0; area_y1 := 0; area_x2 := 0; area_y2 := 0; ShowVStr(screen_ptr,02,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,03,MAX_PATTERN_ROWS+13,'MAX MiN', analyzer_bckg+analyzer); For temp := 05 to MAX_COLUMNS-6 do ShowVStr(screen_ptr,temp,MAX_PATTERN_ROWS+13, #242#224#224#224#224#224#224#224#243, analyzer_bckg+analyzer); ShowVStr(screen_ptr,04,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-5,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-3,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-2,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowVStr(screen_ptr,MAX_COLUMNS-1,MAX_PATTERN_ROWS+13,ExpStrL('',9,' '), analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+13,'dB', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+14,#224'47', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+15,#224, analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+16,#224'23', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+17,#224, analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+18,#224'12', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+19,#224'4', analyzer_bckg+analyzer); ShowStr(screen_ptr,MAX_COLUMNS-4,MAX_PATTERN_ROWS+20,#224'2', analyzer_bckg+analyzer); ShowCStr(screen_ptr,03,03,'~ORDER/PATTERN ~ /', status_background+status_dynamic_txt, status_background+status_static_txt); ShowCStr(screen_ptr,03,04,'~ROW ~', status_background+status_dynamic_txt, status_background+status_static_txt); ShowCStr(screen_ptr,03,05,'~SPEED/TEMPO ~ /', status_background+status_dynamic_txt, status_background+status_static_txt); ShowStr(screen_ptr,02,08,patt_win[1], pattern_bckg+pattern_border); ShowStr(screen_ptr,02,09,patt_win[2], pattern_bckg+pattern_border); ShowStr(screen_ptr,02,10,patt_win[3], pattern_bckg+pattern_border); For temp := 11 to 11+MAX_PATTERN_ROWS-1 do ShowStr(screen_ptr,02,temp,patt_win[4], pattern_bckg+pattern_border); ShowStr(screen_ptr,02,11+MAX_PATTERN_ROWS,patt_win[5], pattern_bckg+pattern_border); end; procedure process_config_file; var data: String; function check_number(str: String; base: Byte; limit1,limit2: Longint; default: Longint): Longint; var idx,temp: Byte; temp2: Longint; result: Longint; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:check_number'; {$ENDIF} result := default; temp2 := 1000000000; For idx := 10 downto 1 do begin If (limit2 >= temp2) then begin temp := idx; BREAK; end; temp2 := temp2 DIV 10; end; If SameName(str+'='+ExpStrL('',temp,'?'),data) and (Length(data) < Length(str)+temp+2) then begin result := Str2num(Copy(data,Length(str)+2,temp),base); If (result >= limit1) and (result <= limit2) then else result := default; end; check_number := result; end; function validate_number(var num: Longint; str: String; base: Byte; limit1,limit2: Longint): Boolean; var idx,temp: Byte; temp2: Longint; result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:validate_number'; {$ENDIF} result := FALSE; temp2 := 1000000000; For idx := 10 downto 1 do begin If (limit2 >= temp2) then begin temp := idx; BREAK; end; temp2 := temp2 DIV 10; end; If SameName(str+'='+ExpStrL('',temp,'?'),data) and (Length(data) < Length(str)+temp+2) then begin num := Str2num(Copy(data,Length(str)+2,temp),base); If (num >= limit1) and (num <= limit2) then result := TRUE; end else result := TRUE; validate_number := result; end; type tRANGE = Set of 1..255; function check_boolean(str: String; default: Boolean): Boolean; var result: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:process_config_file:check_boolean'; {$ENDIF} result := default; If SameName(str+'=???',data) and (Length(data) < Length(str)+5) then begin If (Copy(data,Length(str)+2,3) = 'on') then result := TRUE; If (Copy(data,Length(str)+2,3) = 'off') then result := FALSE; end; check_boolean := result; end; procedure check_rgb(str: String; var default: tRGB); var result: tRGB; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:process_config_file:check_rgb'; {$ENDIF} If SameName(str+'=??,??,??',data) and (Length(data) < Length(str)+10) then begin result.r := Str2num(Copy(data,Length(str)+2,2),10); result.g := Str2num(Copy(data,Length(str)+5,2),10); result.b := Str2num(Copy(data,Length(str)+8,2),10); If (result.r <= 63) and (result.g <= 63) and (result.b <= 63) then begin default := result; {$IFNDEF GO32V2} default.r := default.r SHL 2; default.g := default.g SHL 2; default.b := default.b SHL 2; {$ENDIF} end; end; end; procedure check_option_data; var temp: Byte; {$IFNDEF GO32V2} temp_str: String; {$ENDIF} begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:check_option_data'; opl3port := check_number('adlib_port',16,1,$0ffff,opl3port); typematic_rate := check_number('typematic_rate',10,0,31,typematic_rate); typematic_delay:= check_number('typematic_delay',10,0,3,typematic_delay); mouse_hspeed := check_number('mouse_hspeed',10,0,65535,mouse_hspeed); mouse_vspeed := check_number('mouse_vspeed',10,0,65535,mouse_vspeed); mouse_threshold := check_number('mouse_threshold',10,0,65535,mouse_threshold); screen_mode := check_number('screen_mode',10,0,5,screen_mode); comp_text_mode := check_number('comp_text_mode',10,0,4,comp_text_mode); opl_latency := check_number('opl_latency',10,0,1,opl_latency); fps_down_factor := check_number('fps_down_factor',10,0,10,fps_down_factor); mouse_disabled := check_boolean('mouse_disabled',mouse_disabled); // validate custom SVGA text-mode configuration custom_svga_mode := check_boolean('custom_svga_mode',custom_svga_mode); _custom_svga_cfg[1].flag := validate_number(_custom_svga_cfg[1].value,'svga_txt_columns',10,80,180); _custom_svga_cfg[2].flag := validate_number(_custom_svga_cfg[2].value,'svga_txt_rows',10,25,60); _custom_svga_cfg[3].flag := validate_number(_custom_svga_cfg[3].value,'crtc_misc_out',16,0,255); _custom_svga_cfg[4].flag := validate_number(_custom_svga_cfg[4].value,'crtc_h_total',16,0,255); _custom_svga_cfg[5].flag := validate_number(_custom_svga_cfg[5].value,'crtc_h_disp_en_end',16,0,255); _custom_svga_cfg[6].flag := validate_number(_custom_svga_cfg[6].value,'crtc_h_blank_start',16,0,255); _custom_svga_cfg[7].flag := validate_number(_custom_svga_cfg[7].value,'crtc_h_blank_end',16,0,255); _custom_svga_cfg[8].flag := validate_number(_custom_svga_cfg[8].value,'crtc_h_ret_start',16,0,255); _custom_svga_cfg[9].flag := validate_number(_custom_svga_cfg[9].value,'crtc_h_ret_end',16,0,255); _custom_svga_cfg[10].flag := validate_number(_custom_svga_cfg[10].value,'crtc_v_total',16,0,255); _custom_svga_cfg[11].flag := validate_number(_custom_svga_cfg[11].value,'crtc_overflow_reg',16,0,255); _custom_svga_cfg[12].flag := validate_number(_custom_svga_cfg[12].value,'crtc_preset_r_scan',16,0,255); _custom_svga_cfg[13].flag := validate_number(_custom_svga_cfg[13].value,'crtc_max_scan_h',16,0,255); _custom_svga_cfg[14].flag := validate_number(_custom_svga_cfg[14].value,'crtc_v_ret_start',16,0,255); _custom_svga_cfg[15].flag := validate_number(_custom_svga_cfg[15].value,'crtc_v_ret_end',16,0,255); _custom_svga_cfg[16].flag := validate_number(_custom_svga_cfg[16].value,'crtc_v_disp_en_end',16,0,255); _custom_svga_cfg[17].flag := validate_number(_custom_svga_cfg[17].value,'crtc_offs_width',16,0,255); _custom_svga_cfg[18].flag := validate_number(_custom_svga_cfg[18].value,'crtc_underline_loc',16,0,255); _custom_svga_cfg[19].flag := validate_number(_custom_svga_cfg[19].value,'crtc_v_blank_start',16,0,255); _custom_svga_cfg[20].flag := validate_number(_custom_svga_cfg[20].value,'crtc_v_blank_end',16,0,255); _custom_svga_cfg[21].flag := validate_number(_custom_svga_cfg[21].value,'crtc_mode_ctrl',16,0,255); _custom_svga_cfg[22].flag := validate_number(_custom_svga_cfg[22].value,'crtc_clock_m_reg',16,0,255); _custom_svga_cfg[23].flag := validate_number(_custom_svga_cfg[23].value,'crtc_char_gen_sel',16,0,255); _custom_svga_cfg[24].flag := validate_number(_custom_svga_cfg[24].value,'crtc_memory_m_reg',16,0,255); _custom_svga_cfg[25].flag := validate_number(_custom_svga_cfg[25].value,'crtc_mode_reg',16,0,255); _custom_svga_cfg[26].flag := validate_number(_custom_svga_cfg[26].value,'crtc_misc_reg',16,0,255); _custom_svga_cfg[27].flag := validate_number(_custom_svga_cfg[27].value,'crtc_mode_control',16,0,255); _custom_svga_cfg[28].flag := validate_number(_custom_svga_cfg[28].value,'crtc_screen_b_clr',16,0,255); _custom_svga_cfg[29].flag := validate_number(_custom_svga_cfg[29].value,'crtc_colr_plane_en',16,0,255); _custom_svga_cfg[30].flag := validate_number(_custom_svga_cfg[30].value,'crtc_h_panning',16,0,255); _custom_svga_cfg[31].flag := validate_number(_custom_svga_cfg[31].value,'crtc_color_select',16,0,255); {$ELSE} sdl_screen_mode := check_number('sdl_screen_mode',10,0,2,sdl_screen_mode); sdl_frame_rate := check_number('sdl_frame_rate',10,50,200,sdl_frame_rate); sdl_timer_slowdown := check_number('sdl_timer_slowdown',10,0,50,sdl_timer_slowdown); sdl_typematic_rate := check_number('sdl_typematic_rate',10,1,100,sdl_typematic_rate); sdl_typematic_delay := check_number('sdl_typematic_delay',10,0,2000,sdl_typematic_delay); If (Copy(data,1,18) = 'sdl_wav_directory=') and (Length(data) > 18) then begin temp_str := Copy(data,19,Length(data)-18); If (temp_str[1] = PATHSEP) then Delete(temp_str,1,1); If (temp_str <> '') then begin If (Length(temp_str) > 4) then If NOT (Lower(Copy(temp_str,Length(temp_str)-3,4)) = '.wav') then temp_str := temp_str+PATHSEP else opl3_flushmode := TRUE else If (temp_str[Length(temp_str)] <> PATHSEP) then temp_str := temp_str+PATHSEP; end; sdl_wav_directory := temp_str; If NOT (Pos(':',sdl_wav_directory) <> 0) then sdl_wav_directory := PathOnly(ParamStr(0))+PATHSEP+sdl_wav_directory; end; {$ENDIF} init_tempo := check_number('init_tempo',10,1,255,Round(init_tempo)); init_speed := check_number('init_speed',16,1,255,init_speed); init_macro_speedup := check_number('init_macro_speedup',10,1,calc_max_speedup(init_tempo),init_macro_speedup); midiboard := check_boolean('midiboard',midiboard); default_octave := check_number('octave',10,1,8,default_octave); patt_len := check_number('patt_len',10,1,255,patt_len); nm_tracks := check_number('nm_tracks',10,1,20,nm_tracks); mod_description := check_boolean('mod_description',mod_description); highlight_controls := check_boolean('highlight_controls',highlight_controls); use_H_for_B := check_boolean('use_h_for_b',use_H_for_B); linefeed := check_boolean('linefeed',linefeed); lf_in_mboard_mode := check_boolean('lf_in_mboard_mode',lf_in_mboard_mode); update_ins := check_boolean('update_ins',update_ins); adjust_tracks := check_boolean('adjust_tracks',adjust_tracks); cycle_pattern := check_boolean('cycle_pattern',cycle_pattern); keep_track_pos := check_boolean('keep_track_pos',keep_track_pos); remember_ins_pos := check_boolean('remember_ins_pos',remember_ins_pos); backspace_dir := check_number('backspace_dir',10,1,2,backspace_dir); scroll_bars := check_boolean('scroll_bars',scroll_bars); fforward_factor := check_number('fforward_factor',10,1,5,fforward_factor); rewind_factor := check_number('rewind_factor',10,1,5,rewind_factor); ssaver_time := check_number('ssaver_time',10,0,1440,ssaver_time DIV 60)*60; timer_fix := check_boolean('18hz_fix',timer_fix); decay_bar_rise := check_number('decay_bar_rise',10,1,10,Round(decay_bar_rise)); If (check_number('decay_bar_fall',10,1,10,0) <> 0) then decay_bar_fall := check_number('decay_bar_fall',10,1,10,0)/10; force_ins := check_number('force_ins',10,0,2,force_ins); keep_position := check_boolean('keep_position',keep_position); alt_ins_name := check_boolean('alt_ins_name',alt_ins_name); trace_by_default := check_boolean('trace_by_default',trace_by_default); nosync_by_default := check_boolean('nosync_by_default',nosync_by_default); pattern_layout := check_number('pattern_layout',10,0,2,pattern_layout); command_typing := check_number('command_typing',10,0,2,command_typing); mark_lines := check_boolean('mark_lines',mark_lines); fix_c_note_bug := check_boolean('fix_c_note_bug',fix_c_note_bug); accurate_conv := check_boolean('accurate_conv',accurate_conv); pattern_bckg := check_number('pattern_bckg',10,0,15,pattern_bckg SHR 4) SHL 4; pattern_border := check_number('pattern_border',10,0,15,pattern_border); pattern_pos_indic := check_number('pattern_pos_indic',10,0,15,pattern_pos_indic); pattern_pan_indic := check_number('pattern_pan_indic',10,0,15,pattern_pan_indic); pattern_gpan_indic := check_number('pattern_gpan_indic',10,0,15,pattern_gpan_indic); pattern_lock_indic := check_number('pattern_lock_indic',10,0,15,pattern_lock_indic); pattern_perc_indic := check_number('pattern_perc_indic',10,0,15,pattern_perc_indic); pattern_4op_indic := check_number('pattern_4op_indic',10,0,15,pattern_4op_indic); pattern_chan_indic := check_number('pattern_chan_indic',10,0,15,pattern_chan_indic); pattern_row_bckg := check_number('pattern_row_bckg',10,0,15,pattern_row_bckg SHR 4) SHL 4; pattern_row_bckg_p := check_number('pattern_row_bckg_p',10,0,15,pattern_row_bckg_p SHR 4) SHL 4; pattern_row_bckg_m := check_number('pattern_row_bckg_m',10,0,15,pattern_row_bckg_m SHR 4) SHL 4; pattern_block_bckg := check_number('pattern_block_bckg',10,0,15,pattern_block_bckg SHR 4) SHL 4; pattern_line := check_number('pattern_line#',10,0,15,pattern_line); pattern_line_p := check_number('pattern_line#_p',10,0,15,pattern_line_p); pattern_line_m := check_number('pattern_line#_m',10,0,15,pattern_line_m); pattern_hi_line := check_number('pattern_hi_line#',10,0,15,pattern_hi_line); pattern_hi_line_m := check_number('pattern_hi_line#_m',10,0,15,pattern_hi_line_m); pattern_note := check_number('pattern_note',10,0,15,pattern_note); pattern_hi_note := check_number('pattern_hi_note',10,0,15,pattern_hi_note); pattern_note0 := check_number('pattern_note0',10,0,15,pattern_note0); pattern_hi_note0 := check_number('pattern_hi_note0',10,0,15,pattern_hi_note0); pattern_note_hid := check_number('pattern_note_hid',10,0,15,pattern_note_hid); pattern_hi_note_h := check_number('pattern_hi_note_h',10,0,15,pattern_hi_note_h); pattern_inst := check_number('pattern_ins#',10,0,15,pattern_inst); pattern_hi_inst := check_number('pattern_hi_ins#',10,0,15,pattern_hi_inst); pattern_inst0 := check_number('pattern_ins#0',10,0,15,pattern_inst0); pattern_hi_inst0 := check_number('pattern_hi_ins#0',10,0,15,pattern_hi_inst0); pattern_cmnd := check_number('pattern_cmnd',10,0,15,pattern_cmnd); pattern_hi_cmnd := check_number('pattern_hi_cmnd',10,0,15,pattern_hi_cmnd); pattern_cmnd0 := check_number('pattern_cmnd0',10,0,15,pattern_cmnd0); pattern_hi_cmnd0 := check_number('pattern_hi_cmnd0',10,0,15,pattern_hi_cmnd0); pattern_note_m := check_number('pattern_note_m',10,0,15,pattern_note_m); pattern_note0_m := check_number('pattern_note0_m',10,0,15,pattern_note0_m); pattern_note_hid_m := check_number('pattern_note_hid_m',10,0,15,pattern_note_hid_m); pattern_inst_m := check_number('pattern_ins#_m',10,0,15,pattern_inst_m); pattern_inst0_m := check_number('pattern_ins#0_m',10,0,15,pattern_inst0_m); pattern_cmnd_m := check_number('pattern_cmnd_m',10,0,15,pattern_cmnd_m); pattern_cmnd0_m := check_number('pattern_cmnd0_m',10,0,15,pattern_cmnd0_m); pattern_note_b := check_number('pattern_note_b',10,0,15,pattern_note_b); pattern_note0_b := check_number('pattern_note0_b',10,0,15,pattern_note0_b); pattern_note_hid_b := check_number('pattern_note_hid_b',10,0,15,pattern_note_hid_b); pattern_inst_b := check_number('pattern_ins#_b',10,0,15,pattern_inst_b); pattern_inst0_b := check_number('pattern_ins#0_b',10,0,15,pattern_inst0_b); pattern_cmnd_b := check_number('pattern_cmnd_b',10,0,15,pattern_cmnd_b); pattern_cmnd0_b := check_number('pattern_cmnd0_b',10,0,15,pattern_cmnd0_b); pattern_cmnd_ctrl := check_number('pattern_cmnd_ctrl',10,0,15,pattern_cmnd_ctrl); pattern_fix_note := check_number('pattern_fix_note',10,0,15,pattern_fix_note); pattern_hi_fx_note := check_number('pattern_hi_fx_note',10,0,15,pattern_hi_fx_note); pattern_fix_note_m := check_number('pattern_fix_note_m',10,0,15,pattern_fix_note_m); pattern_fix_note_b := check_number('pattern_fix_note_b',10,0,15,pattern_fix_note_b); pattern_input_bckg := check_number('pattern_input_bckg',10,0,15,pattern_input_bckg SHR 4) SHL 4; pattern_input := check_number('pattern_input',10,0,15,pattern_input); pattern_input_warn := check_number('pattern_input_warn',10,0,15,pattern_input_warn SHR 4) SHL 4; analyzer_bckg := check_number('analyzer_bckg',10,0,15,analyzer_bckg SHR 4) SHL 4; analyzer := check_number('analyzer',10,0,15,analyzer); analyzer_ovrllvol := check_number('analyzer_overallvol',10,0,15,analyzer_ovrllvol); analyzer_volumelvl := check_number('analyzer_volumelvl',10,0,15,analyzer_volumelvl); analyzer_carrier := check_number('analyzer_carrier',10,0,15,analyzer_carrier); analyzer_modulator := check_number('analyzer_modulator',10,0,15,analyzer_modulator); debug_info_bckg := check_number('debug_info_bckg',10,0,15,debug_info_bckg SHR 4) SHL 4; debug_info_bckg2 := check_number('debug_info_bckg2',10,0,15,debug_info_bckg2 SHR 4) SHL 4; debug_info_border := check_number('debug_info_border',10,0,15,debug_info_border); debug_info_title := check_number('debug_info_title',10,0,15,debug_info_title); debug_info_border2 := check_number('debug_info_border2',10,0,15,debug_info_border2); debug_info_topic := check_number('debug_info_topic',10,0,15,debug_info_topic); debug_info_txt := check_number('debug_info_txt',10,0,15,debug_info_txt); debug_info_hi_txt := check_number('debug_info_hi_txt',10,0,15,debug_info_hi_txt); debug_info_txt_hid := check_number('debug_info_txt_hid',10,0,15,debug_info_txt_hid); debug_info_mod := check_number('debug_info_mod',10,0,15,debug_info_mod); debug_info_hi_mod := check_number('debug_info_hi_mod',10,0,15,debug_info_hi_mod); debug_info_car := check_number('debug_info_car',10,0,15,debug_info_car); debug_info_hi_car := check_number('debug_info_hi_car',10,0,15,debug_info_hi_car); debug_info_4op := check_number('debug_info_4op',10,0,15,debug_info_4op); debug_info_perc := check_number('debug_info_perc',10,0,15,debug_info_perc); debug_info_bpm := check_number('debug_info_bpm',10,0,15,debug_info_bpm); help_background := check_number('help_background',10,0,15,help_background SHR 4) SHL 4; help_title := check_number('help_title',10,0,15,help_title); help_border := check_number('help_border',10,0,15,help_border); help_topic := check_number('help_topic',10,0,15,help_topic); help_text := check_number('help_text',10,0,15,help_text); help_hi_text := check_number('help_hi_text',10,0,15,help_hi_text); help_indicators := check_number('help_indicators',10,0,15,help_indicators); help_keys := check_number('help_keys',10,0,15,help_keys); dialog_background := check_number('dialog_background',10,0,15,dialog_background SHR 4) SHL 4; dialog_title := check_number('dialog_title',10,0,15,dialog_title); dialog_border := check_number('dialog_border',10,0,15,dialog_border); dialog_text := check_number('dialog_text',10,0,15,dialog_text); dialog_hi_text := check_number('dialog_hi_text',10,0,15,dialog_hi_text); dialog_hid := check_number('dialog_hid',10,0,15,dialog_hid); dialog_item := check_number('dialog_item',10,0,15,dialog_item); dialog_sel_itm_bck := check_number('dialog_sel_itm_bckg',10,0,15,dialog_sel_itm_bck SHR 4) SHL 4; dialog_sel_itm := check_number('dialog_sel_itm',10,0,15,dialog_sel_itm); dialog_short := check_number('dialog_short',10,0,15,dialog_short); dialog_sel_short := check_number('dialog_sel_short',10,0,15,dialog_sel_short); dialog_item_dis := check_number('dialog_item_dis',10,0,15,dialog_item_dis); dialog_context := check_number('dialog_context',10,0,15,dialog_context); dialog_context_dis := check_number('dialog_context_dis',10,0,15,dialog_context_dis); dialog_contxt_dis2 := check_number('dialog_context_dis2',10,0,15,dialog_contxt_dis2); dialog_input_bckg := check_number('dialog_input_bckg',10,0,15,dialog_input_bckg SHR 4) SHL 4; dialog_input := check_number('dialog_input',10,0,15,dialog_input); dialog_def_bckg := check_number('dialog_def_bckg',10,0,15,dialog_def_bckg SHR 4) SHL 4; dialog_def := check_number('dialog_def',10,0,15,dialog_def); dialog_prog_bar1 := check_number('dialog_prog_bar1',10,0,15,dialog_prog_bar1); dialog_prog_bar2 := check_number('dialog_prog_bar2',10,0,15,dialog_prog_bar2); dialog_topic := check_number('dialog_topic',10,0,15,dialog_topic); dialog_hi_topic := check_number('dialog_hi_topic',10,0,15,dialog_hi_topic); dialog_mod_text := check_number('dialog_mod_text',10,0,15,dialog_mod_text); dialog_car_text := check_number('dialog_car_text',10,0,15,dialog_car_text); dialog_misc_indic := check_number('dialog_misc_indic',10,0,15,dialog_misc_indic); macro_background := check_number('macro_background',10,0,15,macro_background SHR 4) SHL 4; macro_title := check_number('macro_title',10,0,15,macro_title); macro_border := check_number('macro_border',10,0,15,macro_border); macro_topic := check_number('macro_topic',10,0,15,macro_topic); macro_topic2 := check_number('macro_topic2',10,0,15,macro_topic2); macro_hi_topic := check_number('macro_hi_topic',10,0,15,macro_hi_topic); macro_text := check_number('macro_text',10,0,15,macro_text); macro_hi_text := check_number('macro_hi_text',10,0,15,macro_hi_text); macro_text_dis := check_number('macro_text_dis',10,0,15,macro_text_dis); macro_text_loop := check_number('macro_text_loop',10,0,15,macro_text_loop); macro_text_keyoff := check_number('macro_text_keyoff',10,0,15,macro_text_keyoff); macro_current_bckg := check_number('macro_current_bckg',10,0,15,macro_current_bckg SHR 4) SHL 4; macro_current := check_number('macro_current',10,0,15,macro_current); macro_current_dis := check_number('macro_current_dis',10,0,15,macro_current_dis); macro_current_loop := check_number('macro_current_loop',10,0,15,macro_current_loop); macro_current_koff := check_number('macro_current_koff',10,0,15,macro_current_koff); macro_input_bckg := check_number('macro_input_bckg',10,0,15,macro_input_bckg SHR 4) SHL 4; macro_input := check_number('macro_input',10,0,15,macro_input); macro_def_bckg := check_number('macro_def_bckg',10,0,15,macro_def_bckg SHR 4) SHL 4; macro_def := check_number('macro_def',10,0,15,macro_def); macro_scrbar_bckg := check_number('macro_scrbar_bckg',10,0,15,macro_scrbar_bckg SHR 4) SHL 4; macro_scrbar_text := check_number('macro_scrbar_text',10,0,15,macro_scrbar_text); macro_scrbar_mark := check_number('macro_scrbar_mark',10,0,15,macro_scrbar_mark); macro_hint := check_number('macro_hint',10,0,15,macro_hint); macro_item := check_number('macro_item',10,0,15,macro_item); macro_sel_itm_bck := check_number('macro_sel_itm_bckg',10,0,15,macro_sel_itm_bck SHR 4) SHL 4; macro_sel_itm := check_number('macro_sel_itm',10,0,15,macro_sel_itm); macro_short := check_number('macro_short',10,0,15,macro_short); macro_sel_short := check_number('macro_sel_short',10,0,15,macro_sel_short); macro_item_dis := check_number('macro_item_dis',10,0,15,macro_item_dis); macro_context := check_number('macro_context',10,0,15,macro_context); macro_context_dis := check_number('macro_context_dis',10,0,15,macro_context_dis); scrollbar_bckg := check_number('scrollbar_bckg',10,0,15,scrollbar_bckg SHR 4) SHL 4; scrollbar_text := check_number('scrollbar',10,0,15,scrollbar_text); scrollbar_mark := check_number('scrollbar_mark',10,0,15,scrollbar_mark); scrollbar_2nd_mark := check_number('scrollbar_2nd_mark',10,0,15,scrollbar_2nd_mark); main_background := check_number('main_background',10,0,15,main_background SHR 4) SHL 4; main_title := check_number('main_title',10,0,15,main_title); main_border := check_number('main_border',10,0,15,main_border); main_stat_line := check_number('main_stat_line',10,0,15,main_stat_line); main_hi_stat_line := check_number('main_hi_stat_line',10,0,15,main_hi_stat_line); main_dis_stat_line := check_number('main_dis_stat_line',10,0,15,main_dis_stat_line); main_behavior := check_number('main_behavior',10,0,15,main_behavior); main_behavior_dis := check_number('main_behavior_dis',10,0,15,main_behavior_dis); status_background := check_number('status_background',10,0,15,status_background SHR 4) SHL 4; status_border := check_number('status_border',10,0,15,status_border); status_static_txt := check_number('status_static_txt',10,0,15,status_static_txt); status_dynamic_txt := check_number('status_dynamic_txt',10,0,15,status_dynamic_txt); status_play_state := check_number('status_play_state',10,0,15,status_play_state); status_text_dis := check_number('status_text_dis',10,0,15,status_text_dis); order_background := check_number('order_background',10,0,15,order_background SHR 4) SHL 4; order_hi_bckg := check_number('order_hi_bckg',10,0,15,order_hi_bckg SHR 4) SHL 4; order_border := check_number('order_border',10,0,15,order_border); order_entry := check_number('order_entry',10,0,15,order_entry); order_hi_entry := check_number('order_hi_entry',10,0,15,order_hi_entry); order_pattn_jump := check_number('order_patt#_jump',10,0,15,order_pattn_jump); order_pattn := check_number('order_patt#',10,0,15,order_pattn); order_hi_pattn := check_number('order_hi_patt#',10,0,15,order_hi_pattn); order_played_b := check_number('order_played_b',10,0,15,order_played_b SHR 4) SHL 4; order_played := check_number('order_played',10,0,15,order_played); order_input_bckg := check_number('order_input_bckg',10,0,15,order_input_bckg SHR 4) SHL 4; order_input := check_number('order_input',10,0,15,order_input); order_input_warn := check_number('order_input_warn',10,0,15,order_input_warn SHR 4) SHL 4; instrument_bckg := check_number('instrument_bckg',10,0,15,instrument_bckg SHR 4) SHL 4; instrument_title := check_number('instrument_title',10,0,15,instrument_title); instrument_border := check_number('instrument_border',10,0,15,instrument_border); instrument_text := check_number('instrument_text',10,0,15,instrument_text); instrument_hi_text := check_number('instrument_hi_text',10,0,15,instrument_hi_text); instrument_glob := check_number('instrument_glob',10,0,15,instrument_glob); instrument_hi_glob := check_number('instrument_hi_glob',10,0,15,instrument_hi_glob); instrument_hid := check_number('instrument_hid',10,0,15,instrument_hid); instrument_mod := check_number('instrument_mod',10,0,15,instrument_mod); instrument_car := check_number('instrument_car',10,0,15,instrument_car); instrument_hi_mod := check_number('instrument_hi_mod',10,0,15,instrument_hi_mod); instrument_hi_car := check_number('instrument_hi_car',10,0,15,instrument_hi_car); instrument_context := check_number('instrument_context',10,0,15,instrument_context); instrument_con_dis := check_number('instrument_con_dis',10,0,15,instrument_con_dis); instrument_adsr := check_number('instrument_adsr',10,0,15,instrument_adsr SHR 4) SHL 4; instrument_ai_off := check_number('instrument_ai_off',10,0,15,instrument_ai_off); instrument_ai_on := check_number('instrument_ai_on',10,0,15,instrument_ai_on); instrument_ai_trig := check_number('instrument_ai_trig',10,0,15,instrument_ai_trig); If (Copy(data,1,14) = 'home_dir_path=') and (Length(data) > 14) then begin home_dir_path := Copy(data,15,Length(data)-14); If (home_dir_path <> '') and (home_dir_path[Length(home_dir_path)] <> PATHSEP) then home_dir_path := home_dir_path+PATHSEP; end; If (Copy(data,1,17) = 'a2m_default_path=') and (Length(data) > 17) then begin a2m_default_path := Copy(data,18,Length(data)-17); If (a2m_default_path <> '') and (a2m_default_path[Length(a2m_default_path)] <> PATHSEP) then a2m_default_path := a2m_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2t_default_path=') and (Length(data) > 17) then begin a2t_default_path := Copy(data,18,Length(data)-17); If (a2t_default_path <> '') and (a2t_default_path[Length(a2t_default_path)] <> PATHSEP) then a2t_default_path := a2t_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2i_default_path=') and (Length(data) > 17) then begin a2i_default_path := Copy(data,18,Length(data)-17); If (a2i_default_path <> '') and (a2i_default_path[Length(a2i_default_path)] <> PATHSEP) then a2i_default_path := a2i_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2f_default_path=') and (Length(data) > 17) then begin a2f_default_path := Copy(data,18,Length(data)-17); If (a2f_default_path <> '') and (a2f_default_path[Length(a2f_default_path)] <> PATHSEP) then a2f_default_path := a2f_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2p_default_path=') and (Length(data) > 17) then begin a2p_default_path := Copy(data,18,Length(data)-17); If (a2p_default_path <> '') and (a2p_default_path[Length(a2p_default_path)] <> PATHSEP) then a2p_default_path := a2p_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2b_default_path=') and (Length(data) > 17) then begin a2b_default_path := Copy(data,18,Length(data)-17); If (a2b_default_path <> '') and (a2b_default_path[Length(a2b_default_path)] <> PATHSEP) then a2b_default_path := a2b_default_path+PATHSEP; end; If (Copy(data,1,17) = 'a2w_default_path=') and (Length(data) > 17) then begin a2w_default_path := Copy(data,18,Length(data)-17); If (a2w_default_path <> '') and (a2w_default_path[Length(a2w_default_path)] <> PATHSEP) then a2w_default_path := a2w_default_path+PATHSEP; end; For temp := 0 to 15 do check_rgb('color'+ExpStrL(Num2str(temp,10),2,'0'),rgb_color[temp]); end; var txtf: Text; idx: Byte; config_found_flag: Boolean; begin { process_config_file } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXT2.PAS:process_config_file'; {$ENDIF} config_found_flag := FALSE; Write('Reading configuration file ... '); {$i-} Assign(txtf,'adtrack2.ini'); Reset (txtf); {$i+} If (IOresult <> 0) then begin {$i-} Assign(txtf,PathOnly(ParamStr(0))+'adtrack2.ini'); Reset (txtf); {$i+} If (IOresult <> 0) then WriteLn('not found!') else begin config_found_flag := TRUE; WriteLn('ok'); end; end else begin config_found_flag := TRUE; WriteLn('ok'); end; If config_found_flag then begin While NOT EOF(txtf) do begin {$i-} ReadLn(txtf,data); {$i+} If (IOresult <> 0) then begin {$i-} Close(txtf); {$i+} If (IOresult <> 0) then ; BREAK; end; If (Pos(';',data) <> 0) then Delete(data,Pos(';',data),Length(data)-Pos(';',data)+1); data := CutStr(Lower(data)); check_option_data; end; {$i-} Close(txtf); {$i+} If (IOresult <> 0) then ; end; If (ParamCount <> 0) then For idx := 1 to ParamCount do begin data := CutStr(Lower(ParamStr(idx))); If (Copy(data,1,5) = '/cfg:') then begin Delete(data,1,5); check_option_data; end; end; end; end. adlibtracker2-2.4.24/instedit.inc0000644000000000000000000045042513411003760015335 0ustar rootroot// 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 reset_instrument_preview; procedure INSTRUMENT_test(instr,instr2: Byte; chan: Byte; fkey: Word; process_macros: Boolean); function _1st_marked: Byte; function _2nd_marked: Byte; function marked_instruments: Byte; procedure reset_marked_instruments; function get_4op_to_test: Word; function check_4op_to_test: Word; function check_4op_instrument(ins: Byte): Word; function check_4op_flag(ins: Byte): Boolean; procedure reset_4op_flag(ins: Byte); procedure set_4op_flag(ins: Byte); procedure update_4op_flag_marks; procedure INSTRUMENT_CONTROL_page_refresh(page: Byte); procedure _show_adsr(var dest; xstart,ystart: Byte; attack,decay,sustain,release,attenuation: Byte; eg_type: Byte; attr,attr_hi: Byte; reset: Boolean); procedure INSTRUMENT_CONTROL_page_refresh_alt(page: Byte); function _4op_conn_to_idx(str: String): Byte; procedure _show_conn_scheme(xstart,ystart,conn: Byte; hi_op: tSET_OF_CHARS); function _get_feedback_val: Byte; procedure _inc_feedback_val; procedure _dec_feedback_val; function _get_finetune_val: Shortint; procedure _inc_finetune_val; procedure _dec_finetune_val; procedure _page_build; procedure _page_refresh; procedure _sync_radio_buttons; procedure INSTRUMENT_CONTROL_edit; procedure copy_object; procedure paste_object(mode: Byte); procedure instr_control_ai; procedure instr_control_proc; function INSTRUMENT_CONTROL: Byte; procedure instr_control_proc_alt; function INSTRUMENT_CONTROL_alt(instr: Byte; title: String): Byte; } const _ADSR_preview_flag: Boolean = TRUE; const _operator_enabled: array[1..4] of Boolean = (TRUE,TRUE,TRUE,TRUE); _carrier_flag: array[BOOLEAN] of Byte = (2,1); _ins_mark_chr = #16; _4op_flag_chr_beg = #172; _4op_flag_chr_end = #173; _4op_flag_chars: Set of Char = [_4op_flag_chr_beg,_4op_flag_chr_end]; _4op_connection_str: array[0..3] of String[5] = ( 'FM/FM','FM/AM','AM/FM','AM/AM'); procedure reset_instrument_preview; var temp: Word; begin If (play_status <> isPlaying) then reset_player; temp := check_4op_to_test; If NOT (temp <> 0) then update_instr_data(instrum_page) else begin update_instr_data(LO(temp)); update_instr_data(HI(temp)); end; end; procedure INSTRUMENT_test(instr,instr2: Byte; chan: Byte; fkey: Word; process_macros: Boolean); var temp,temp2,temp3,temp5: Byte; valid_key,temp4: Boolean; chan_handle: array[1..20] of Byte; channels: Byte; _1op_preview,_4op_mode: Boolean; function _1op_preview_active: Boolean; var temp,nm_slots: Byte; begin nm_slots := 0; For temp := 1 to 4 do If _operator_enabled[temp] then Inc(nm_slots); _1op_preview_active := (nm_slots = 1); end; function output_note(chan,board_pos: Byte): Boolean; var note: Byte; freq: Word; ins: tADTRACK2_INS; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_test:output_note'; {$ENDIF} note := board_pos+12*(current_octave-1); If NOT (note in [0..12*8+1]) then begin output_note := FALSE; EXIT; end; chan_handle[chan] := board_scancodes[board_pos]; If _4op_mode then chan := _4op_main_chan[chan]; If _1op_preview then begin If _operator_enabled[1] or _operator_enabled[2] then ins := songdata.instr_data[instr] else ins := songdata.instr_data[instr2]; pBYTE(@ins)[10] := pBYTE(@ins)[10] OR 1; load_instrument(ins,chan); If _operator_enabled[1] or _operator_enabled[2] then set_ins_volume($3f-ORD(_operator_enabled[1])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[2])*($3f-HI(volume_table[chan])), chan) else set_ins_volume($3f-ORD(_operator_enabled[3])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[4])*($3f-HI(volume_table[chan])), chan); end else begin load_instrument(songdata.instr_data[instr],chan); set_ins_volume($3f-ORD(_operator_enabled[1])*($3f-LO(volume_table[chan])), $3f-ORD(_operator_enabled[2])*($3f-HI(volume_table[chan])), chan); If percussion_mode and (songdata.instr_data[instr].perc_voice in [4,5]) then load_instrument(songdata.instr_data[instr],_perc_sim_chan[chan]); If _4op_mode then begin load_instrument(songdata.instr_data[instr2],PRED(chan)); set_ins_volume($3f-ORD(_operator_enabled[3])*($3f-LO(volume_table[PRED(chan)])), $3f-ORD(_operator_enabled[4])*($3f-HI(volume_table[PRED(chan)])), PRED(chan)); end; end; macro_speedup := songdata.macro_speedup; If (play_status = isStopped) then update_timer(songdata.tempo); freq := nFreq(note-1)+$2000+ SHORTINT(pBYTE(@Addr(songdata.instr_data[instr])^)[12]); event_table[chan].note := note; freq_table[chan] := freq; freqtable2[chan] := freq; key_on(chan); change_freq(chan,freq); If process_macros then If NOT (_1op_preview and (_operator_enabled[3] or _operator_enabled[4])) then init_macro_table(chan,note,instr,freq) else init_macro_table(chan,note,instr2,freq) else begin macro_table[chan].fmreg_table := 0; macro_table[chan].arpg_table := 0; macro_table[chan].vib_table := 0; end; If _4op_mode and NOT _1op_preview then begin If process_macros then init_macro_table(PRED(chan),note,instr2,freq) else begin macro_table[PRED(chan)].fmreg_table := 0; macro_table[PRED(chan)].arpg_table := 0; macro_table[PRED(chan)].vib_table := 0; end; end; end; begin { INSTRUMENT_test } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_test'; {$ENDIF} If ctrl_pressed or alt_pressed or shift_pressed then EXIT; _1op_preview := _1op_preview_active; _4op_mode := NOT _1op_preview_active and (songdata.flag_4op <> 0) and (instr2 <> 0); valid_key := FALSE; For temp := 1 to 29 do If NOT shift_pressed then If (board_scancodes[temp] = HI(fkey)) then begin valid_key := TRUE; BREAK; end; If NOT valid_key or NOT (temp+12*(current_octave-1)-1 in [0..12*8+1]) then EXIT; If (Empty(songdata.instr_data[instr],SizeOf(songdata.instr_data[instr])) and Empty(songdata.instr_macros[instr],SizeOf(songdata.instr_macros[instr]))) or (_4op_mode and Empty(songdata.instr_data[instr2],SizeOf(songdata.instr_data[instr2])) and Empty(songdata.instr_macros[instr2],SizeOf(songdata.instr_macros[instr2]))) then EXIT; temp2 := temp; ins_trailing_flag := TRUE; status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; nul_volume_bars; really_no_status_refresh := TRUE; Move(channel_flag,channel_flag_backup,SizeOf(channel_flag_backup)); Move(event_table,event_table_backup,SizeOf(event_table_backup)); common_flag_backup := songdata.common_flag; volume_scaling_backup := volume_scaling; songdata.common_flag := songdata.common_flag AND NOT $80; volume_scaling := FALSE; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); Move(pan_lock,pan_lock_backup,SizeOf(pan_lock)); Move(volume_lock,volume_lock_backup,SizeOf(volume_lock)); Move(peak_lock,peak_lock_backup,SizeOf(volume_lock)); Move(panning_table,panning_table_backup,SizeOf(panning_table)); FillChar(pan_lock,SizeOf(pan_lock),0); FillChar(volume_lock,SizeOf(volume_lock),0); FillChar(peak_lock,SizeOf(volume_lock),0); flag_4op_backup := songdata.flag_4op; If NOT percussion_mode and NOT (songdata.flag_4op <> 0) then channels := 18 else If NOT (songdata.flag_4op <> 0) then channels := 15 else begin If _4op_mode then begin songdata.flag_4op := $3f; channels := 6; end else begin songdata.flag_4op := 0; If NOT percussion_mode then channels := 18 else channels := 15; end; end; reset_player; FillChar(chan_handle,SizeOf(chan_handle),0); Move(fmpar_table,fmpar_table_backup,SizeOf(fmpar_table_backup)); Move(volume_table,volume_table_backup,SizeOf(volume_table_backup)); Move(freq_table,freq_table_backup,SizeOf(freq_table)); Move(freqtable2,freqtable2_backup,SizeOf(freqtable2)); Move(keyoff_loop,keyoff_loop_backup,SizeOf(keyoff_loop)); FillChar(keyoff_loop,SizeOf(keyoff_loop),FALSE); misc_register := current_tremolo_depth SHL 7+ current_vibrato_depth SHL 6+ BYTE(percussion_mode) SHL 5; key_off(17); key_off(18); opl2out(_instr[11],misc_register); If percussion_mode and (songdata.instr_data[instr].perc_voice in [1..5]) then begin output_note(songdata.instr_data[instr].perc_voice+15,temp2); While scankey(board_scancodes[temp2]) do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; end else Repeat {$IFNDEF GO32V2} keyboard_poll_input; {$ENDIF} valid_key := FALSE; For temp := 1 to 29 do begin temp2 := board_scancodes[temp]; temp4 := scankey(temp2); If NOT _4op_mode then begin temp3 := get_chanpos(chan_handle,channels,temp2); temp5 := get_chanpos(chan_handle,channels,0); end else begin temp3 := get_chanpos2(chan_handle,channels,temp2); temp5 := get_chanpos2(chan_handle,channels,0); end; If temp4 then valid_key := TRUE; If temp4 and (temp3 = 0) and (temp5 <> 0) then output_note(temp5,temp); If NOT temp4 and (temp3 <> 0) then begin chan_handle[temp3] := 0; key_off(temp3); If alt_pressed then keyoff_loop[temp3] := TRUE; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; until NOT valid_key; While ctrl_pressed do begin {$IFDEF GO32V2} realtime_gfx_poll_proc; {$ELSE} _draw_screen_without_delay := TRUE; keyboard_poll_input; {$ENDIF} keyboard_reset_buffer; draw_screen; end; For temp := 1 to 20 do key_off(temp); songdata.flag_4op := flag_4op_backup; Move(fmpar_table_backup,fmpar_table,SizeOf(fmpar_table)); Move(volume_table_backup,volume_table,SizeOf(volume_table)); Move(panning_table_backup,panning_table,SizeOf(panning_table)); songdata.common_flag := common_flag_backup; volume_scaling := volume_scaling_backup; If (status_backup.play_status = isPlaying) then reset_player; Move(channel_flag_backup,channel_flag,SizeOf(channel_flag)); Move(event_table_backup,event_table,SizeOf(event_table)); Move(pan_lock_backup,pan_lock,SizeOf(pan_lock)); Move(volume_lock_backup,volume_lock,SizeOf(volume_lock)); Move(peak_lock_backup,peak_lock,SizeOf(volume_lock)); really_no_status_refresh := FALSE; Move(freq_table_backup,freq_table,SizeOf(freq_table)); Move(freqtable2_backup,freqtable2,SizeOf(freqtable2)); Move(keyoff_loop_backup,keyoff_loop,SizeOf(keyoff_loop)); FillChar(macro_table,SizeOf(macro_table),0); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; ins_trailing_flag := FALSE; keyboard_reset_buffer; end; var color_table: array[1..3] of Byte; function _1st_marked: Byte; var temp,result: Byte; begin result := 0; For temp := 1 to 255 do If (songdata.instr_names[temp][1] = _ins_mark_chr) then begin result := temp; BREAK; end; _1st_marked := result; end; function _2nd_marked: Byte; var temp,result: Byte; begin result := 0; If (_1st_marked <> 0) then For temp := SUCC(_1st_marked) to 255 do If (songdata.instr_names[temp][1] = _ins_mark_chr) then begin result := temp; BREAK; end; _2nd_marked := result; end; function marked_instruments: Byte; var temp,result: Byte; begin result := 0; For temp := 1 to 255 do If (songdata.instr_names[temp][1] = _ins_mark_chr) then Inc(result); marked_instruments := result; end; procedure reset_marked_instruments; begin If (marked_instruments < 2) then If (songdata.instr_names[instrum_page][1] = _ins_mark_chr) then songdata.instr_names[instrum_page][1] := ' ' else else begin songdata.instr_names[_2nd_marked][1] := ' '; songdata.instr_names[_1st_marked][1] := ' '; end; update_4op_flag_marks; end; function get_4op_to_test: Word; var result: Word; begin result := 0; If (songdata.flag_4op <> 0) then If check_4op_flag(current_inst) then result := SUCC(current_inst)+current_inst SHL 8 else If (current_inst > 1) and check_4op_flag(PRED(current_inst)) then result := current_inst+PRED(current_inst) SHL 8; get_4op_to_test := result; end; function check_4op_to_test: Word; var result: Word; begin result := 0; If check_4op_flag(current_inst) then result := SUCC(current_inst)+current_inst SHL 8 else If (current_inst > 1) and check_4op_flag(PRED(current_inst)) then result := current_inst+PRED(current_inst) SHL 8; check_4op_to_test := result; end; function check_4op_instrument(ins: Byte): Word; var result: Word; begin result := 0; If check_4op_flag(ins) then result := SUCC(ins)+ins SHL 8 else If (ins > 1) and check_4op_flag(PRED(ins)) then result := ins+PRED(ins) SHL 8; check_4op_instrument := result; end; function check_4op_flag(ins: Byte): Boolean; var result: Boolean; idx: Byte; begin result := FALSE; For idx := 1 to songdata.ins_4op_flags.num_4op do If (songdata.ins_4op_flags.idx_4op[idx] = ins) then begin result := TRUE; BREAK; end; check_4op_flag := result; end; procedure reset_4op_flag(ins: Byte); var temp_ins_4op_flags: tINS_4OP_FLAGS; idx: Byte; begin If NOT check_4op_flag(ins) then EXIT; temp_ins_4op_flags.num_4op := 0; idx := 1; While (idx <= songdata.ins_4op_flags.num_4op) and (songdata.ins_4op_flags.idx_4op[idx] < ins) do begin Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := songdata.ins_4op_flags.idx_4op[idx]; Inc(idx); end; Inc(idx); While (idx <= songdata.ins_4op_flags.num_4op) do begin Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := songdata.ins_4op_flags.idx_4op[idx]; Inc(idx); end; songdata.ins_4op_flags := temp_ins_4op_flags; end; procedure set_4op_flag(ins: Byte); var temp_ins_4op_flags: tINS_4OP_FLAGS; idx: Byte; begin If (ins = 255) then EXIT; If check_4op_flag(ins) then reset_4op_flag(ins); If (ins > 1) and check_4op_flag(PRED(ins)) then reset_4op_flag(PRED(ins)); If (ins < 255) and check_4op_flag(SUCC(ins)) then reset_4op_flag(SUCC(ins)); temp_ins_4op_flags.num_4op := 0; idx := 1; While (idx <= songdata.ins_4op_flags.num_4op) and (songdata.ins_4op_flags.idx_4op[idx] < ins) do begin Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := songdata.ins_4op_flags.idx_4op[idx]; Inc(idx); end; Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := ins; While (idx <= songdata.ins_4op_flags.num_4op) do begin Inc(temp_ins_4op_flags.num_4op); temp_ins_4op_flags.idx_4op[temp_ins_4op_flags.num_4op] := songdata.ins_4op_flags.idx_4op[idx]; Inc(idx); end; songdata.ins_4op_flags := temp_ins_4op_flags; end; procedure update_4op_flag_marks; var temp: Byte; begin For temp := 1 to PRED(255) do If NOT check_4op_flag(temp) then begin If (songdata.instr_names[temp][1] in _4op_flag_chars) then songdata.instr_names[temp][1] := ' '; If (songdata.instr_names[SUCC(temp)][1] in _4op_flag_chars) then songdata.instr_names[SUCC(temp)][1] := ' '; end; For temp := 1 to PRED(255) do If check_4op_flag(temp) then begin If (songdata.instr_names[temp][1] = ' ') then songdata.instr_names[temp][1] := _4op_flag_chr_beg; If (songdata.instr_names[SUCC(temp)][1] = ' ') then songdata.instr_names[SUCC(temp)][1] := _4op_flag_chr_end; end; end; procedure INSTRUMENT_CONTROL_page_refresh(page: Byte); var temp: Byte; temp_str: String; _status_shift_pos: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_page_refresh'; {$ENDIF} update_4op_flag_marks; If (ins_parameter(page,10) AND 1 <> 1) then For temp := 1 to 18 do ShowCStr(mn_environment.v_dest, INSCTRL_xshift+10,INSCTRL_yshift+06+temp, inst_itm1[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm1[temp].colr]) else For temp := 1 to 18 do ShowCStr(mn_environment.v_dest, INSCTRL_xshift+10,INSCTRL_yshift+06+temp, inst_itm2[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm2[temp].colr]); ShowStr(mn_environment.v_dest, INSCTRL_xshift+56,INSCTRL_yshift+05, byte2hex(page), dialog_background+dialog_title); For temp := 1 to 10 do ShowStr(mn_environment.v_dest, INSCTRL_xshift+32,INSCTRL_yshift+08+pos2[temp], byte2hex(pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[temp]]), dialog_background+dialog_item); ShowCStr(mn_environment.v_dest, INSCTRL_xshift+30,INSCTRL_yshift+08+pos2[11], connection_str[pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[11]] AND 1]+'~/~'+ CHR(ORD('0')+(pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[11]] SHR 1 AND 7)), dialog_background+dialog_item, color_table[inst_itm1[temp].colr]); Case songdata.instr_data[page].panning of 0: ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'CENTER', dialog_background+dialog_item); 1: ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'LEFT ', dialog_background+dialog_item); 2: ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'RiGHT ', dialog_background+dialog_item); end; If (songdata.instr_data[page].fine_tune < 0) then ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[13], '-'+ExpStrR(Num2str(Abs(songdata.instr_data[page].fine_tune),16),2,' '), dialog_background+dialog_item) else ShowStr(mn_environment.v_dest, INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[13], '+'+ExpStrR(Num2str(Abs(songdata.instr_data[page].fine_tune),16),2,' '), dialog_background+dialog_item); _status_shift_pos := 0; If (check_4op_flag(page) or ((page > 1) and check_4op_flag(PRED(page)))) then begin _status_shift_pos := 5; ShowCStr(mn_environment.v_dest, INSCTRL_xshift+09,INSCTRL_yshift+26, ' [~'#4#3'~] '#205#205#205, dialog_background+dialog_border, dialog_background+dialog_context) end else ShowCStr(mn_environment.v_dest, INSCTRL_xshift+09,INSCTRL_yshift+26, ' [~'+perc_voice_str[songdata.instr_data[page].perc_voice]+'~] ', dialog_background+dialog_border, dialog_background+dialog_context); If (songdata.instr_macros[page].length <> 0) then temp_str := ' [~MACRO:FM' else temp_str := ' '; With songdata.macro_table[ songdata.instr_macros[page].arpeggio_table].arpeggio do If (songdata.instr_macros[page].arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'[~MACRO:ARP'; With songdata.macro_table[ songdata.instr_macros[page].vibrato_table].vibrato do If (songdata.instr_macros[page].vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'[~MACRO:ViB'; If (temp_str <> ' ') then temp_str := temp_str+'~] '; ShowCStr(mn_environment.v_dest,INSCTRL_xshift+19-_status_shift_pos,INSCTRL_yshift+26, ExpStrR(temp_str,27,#205), dialog_background+dialog_border, dialog_background+dialog_context); STATUS_LINE_refresh; end; var adsr_bckg: Byte; procedure _show_adsr(dest: tSCREEN_MEM_PTR; xstart,ystart: Byte; attack,decay,sustain,release,attenuation: Byte; eg_type: Byte; attr,attr_hi: Byte; reset: Boolean); function _gfx_bar_str(value: Byte): String; var result: String; begin result := ''; Repeat If (value > 15) then begin result := result+#219; Dec(value,15); end; If (value <= 15) and (value <> 0) then result := result+CHR(127+value) until (value <= 15); _gfx_bar_str := flipstr(result); end; var index,pos: Integer; temp,temp2: Real; function _conv(value,variant: Byte): Byte; begin If (value <> 0) then _conv := variant else _conv := 1; end; begin { _show_adsr } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:_show_adsr'; {$ENDIF} fr_setting.update_area := FALSE; fr_setting.shadow_enabled := FALSE; If NOT is_default_screen_mode then Frame(dest,xstart,ystart+1,xstart+61,ystart+11, instrument_bckg,'',0,frame_solid_type1) else If reset then Frame(dest,xstart,ystart,xstart+63,ystart+12, instrument_bckg,'',0,frame_solid_type1) else Frame(dest,xstart,ystart,xstart+63,ystart+12, instrument_adsr+instrument_text,' ADSR PREViEW ', instrument_adsr+instrument_text, frame_double); fr_setting.update_area := TRUE; fr_setting.shadow_enabled := TRUE; If (attack <> 0) then attack := min(ROUND(15/ln(15)*ln(attack)),1); If (decay <> 0) then decay := min(ROUND(15/ln(15)*ln(decay)),1) else sustain := 0; If (sustain <> 0) then sustain := min(ROUND(15/ln(15)*ln(sustain)),1); If (release <> 0) then release := min(ROUND(15/ln(15)*ln(release)),1); If reset then EXIT; pos := 1; temp := 0; For index := 0 to (15-attack) do begin temp := temp+8*16/(16-attack); If (attack <> 0) then begin ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr_hi); Inc(pos); end; end; If (attack = 0) then begin Inc(pos); temp := 8*16; end; If (decay = 0) and ((release <> 0) or ((sustain <> 0) and (eg_type = 1))) then decay := 15; If (decay <> 0) then For index := 0 to (15-decay) do begin temp := temp-8*16/16*sustain/(16-decay); ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr_hi); Inc(pos); end; If (decay = 0) then Inc(pos); If (eg_type <> 1) and (release <> 0) then sustain := 0; If (sustain = 0) and (release <> 0) then sustain := 1; For index := 1 to sustain do If (sustain <> 0) then begin ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr_hi); Inc(pos); end; If (sustain = 0) then Inc(pos); temp2 := temp; For index := 1 to (15-release) do begin temp := temp-temp2/(16-release); If (release <> 0) and (temp > 0) then begin If (eg_type <> 1) then ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr_hi) else ShowVStr(dest,xstart+1+pos,ystart+1, ExpStrL(_gfx_bar_str(ROUND(temp/63*(63-attenuation))),9,' '), attr); Inc(pos); end; end; If (release > 0) then ShowStr(dest,xstart+2,ystart+10, Copy(Copy(ExpStrR(#246,_conv(attack,16-attack),' ')+ ExpStrR(#246,_conv(decay,16-decay),' ')+ ExpStrR(#246,_conv(sustain,sustain),' ')+ ExpStrR(#246,_conv(release,15-release),' '),1,60-1)+ #246+ExpStrL('',60,' '),1,60), attr_hi) else ShowStr(dest,xstart+2,ystart+10, ExpStrR(#246,_conv(attack,16-attack),' ')+ ExpStrR(#246,_conv(decay,16-decay),' ')+ ExpStrR(#246,_conv(sustain,sustain),' ')+ ExpStrR(#246,_conv(release,15-release)+ 15-_conv(release,15-release)+ 15-_conv(sustain,sustain)+ 15-_conv(decay,16-decay)+ 15-_conv(attack,16-attack),' '), attr_hi); If (release > 0) then ShowStr(dest,xstart+2,ystart+11, Copy(Copy(ExpStrR('A',_conv(attack,16-attack),#250)+ ExpStrR('D',_conv(decay,16-decay),#250)+ ExpStrR('S',_conv(sustain,sustain),#250)+ ExpStrR('R',_conv(release,15-release),#250),1,60-1)+ #175+ExpStrL('',60,#250),1,60), attr_hi) else ShowStr(dest,xstart+2,ystart+11, ExpStrR('A',_conv(attack,16-attack),#250)+ ExpStrR('D',_conv(decay,16-decay),#250)+ ExpStrR('S',_conv(sustain,sustain),#250)+ ExpStrR('R',_conv(release,15-release)+ 15-_conv(release,15-release)+ 15-_conv(sustain,sustain)+ 15-_conv(decay,16-decay)+ 15-_conv(attack,16-attack),#250), attr_hi); end; procedure INSTRUMENT_CONTROL_page_refresh_alt(page: Byte); var temp: Byte; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_page_refresh_alt'; {$ENDIF} update_4op_flag_marks; If (ins_parameter(page,10) AND 1 <> 1) then For temp := 1 to 18 do ShowCStr(mn_environment.v_dest,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm1[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm1[temp].colr]) else For temp := 1 to 18 do ShowCStr(mn_environment.v_dest,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm2[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm2[temp].colr]); For temp := 1 to 10 do ShowStr(mn_environment.v_dest,INSCTRL_xshift+32,INSCTRL_yshift+08+pos2[temp], byte2hex(pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[temp]]), instrument_bckg+instrument_hi_text); ShowCStr(mn_environment.v_dest, INSCTRL_xshift+30,INSCTRL_yshift+08+pos2[11], connection_str[pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[11]] AND 1]+'~/~'+ CHR(ORD('0')+(pBYTE(@Addr(songdata.instr_data[page])^)[_instr_data_ofs[11]] SHR 1 AND 7)), dialog_background+dialog_item, color_table[inst_itm1[temp].colr]); Case songdata.instr_data[page].panning of 0: ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'CENTER', instrument_bckg+instrument_hi_text); 1: ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'LEFT ', instrument_bckg+instrument_hi_text); 2: ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[12], 'RiGHT ', instrument_bckg+instrument_hi_text); end; If (songdata.instr_data[page].fine_tune < 0) then ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[13], '-'+ExpStrR(Num2str(Abs(songdata.instr_data[page].fine_tune),16),2,' '), instrument_bckg+instrument_hi_text) else ShowStr(mn_environment.v_dest,INSCTRL_xshift+24,INSCTRL_yshift+08+pos2[13], '+'+ExpStrR(Num2str(Abs(songdata.instr_data[page].fine_tune),16),2,' '), instrument_bckg+instrument_hi_text); ShowCStr(mn_environment.v_dest, INSCTRL_xshift+09,INSCTRL_yshift+26, ' [~'+perc_voice_str[songdata.instr_data[page].perc_voice]+'~] ', dialog_background+dialog_border, dialog_background+dialog_context); If (songdata.instr_macros[page].length <> 0) then temp_str := ' [~MACRO:FM' else temp_str := ' '; With songdata.macro_table[ songdata.instr_macros[page].arpeggio_table].arpeggio do If (songdata.instr_macros[page].arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'[~MACRO:ARP'; With songdata.macro_table[ songdata.instr_macros[page].vibrato_table].vibrato do If (songdata.instr_macros[page].vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'[~MACRO:ViB'; If (temp_str <> ' ') then temp_str := temp_str+'~] '; ShowCStr(mn_environment.v_dest,INSCTRL_xshift+19,INSCTRL_yshift+26, ExpStrR(temp_str,21+1,#205), dialog_background+dialog_border, dialog_background+dialog_context); end; var temp: Byte; xstart,ystart: Byte; nope: Boolean; hpos,vpos: Byte; carrier: Boolean; inst: ^tADTRACK2_INS; type tSET_OF_CHARS = Set of Char; tBYTE_PTR = ^Byte; function _4op_conn_to_idx(str: String): Byte; var idx,result: Byte; temps: String; begin temps := FilterStr1(str,'~'); result := 2; For idx := 0 to 3 do If (temps = _4op_connection_str[idx]) then begin Inc(result,idx); BREAK; end; _4op_conn_to_idx := result; end; procedure _show_conn_scheme(xstart,ystart,conn: Byte; hi_op: tSET_OF_CHARS); var idx,idx2: Byte; result: array[1..6] of String; begin For idx2 := 1 to 6 do begin result[idx2] := ''; idx := 1; While (idx <= 17) do If (inst_con_scheme[conn][idx2][idx] = #219) and (inst_con_scheme[conn][idx2][idx+1] in ['1'..'4']) then begin If (inst_con_scheme[conn][idx2][idx+1] in hi_op) then result[idx2] := result[idx2]+'`'#219'`^'+inst_con_scheme[conn][idx2][idx+1]+'^`'#219'`' else result[idx2] := result[idx2]+#219'~'+inst_con_scheme[conn][idx2][idx+1]+'~'#219; Inc(idx,3); end else begin result[idx2] := result[idx2]+inst_con_scheme[conn][idx2][idx]; Inc(idx); end; end; For idx := 1 to 6 do ShowC4Str(ptr_temp_screen,xstart,ystart+idx-1,result[idx], instrument_bckg+instrument_glob, instrument_glob SHL 4, instrument_bckg+instrument_hi_glob, instrument_hi_glob SHL 4); end; function _get_feedback_val: Byte; begin If NOT (get_4op_to_test <> 0) then _get_feedback_val := (songdata.instr_data[current_inst].fm_data.FEEDBACK_FM SHR 1) AND 7 else _get_feedback_val := (songdata.instr_data[LO(get_4op_to_test)].fm_data.FEEDBACK_FM SHR 1) AND 7; end; procedure _inc_feedback_val; var feedb_ptr: tBYTE_PTR; begin If NOT (get_4op_to_test <> 0) then feedb_ptr := tBYTE_PTR(Addr(songdata.instr_data[current_inst].fm_data.FEEDBACK_FM)) else feedb_ptr := tBYTE_PTR(Addr(songdata.instr_data[LO(get_4op_to_test)].fm_data.FEEDBACK_FM)); If ((feedb_ptr^ SHR 1) AND 7 < 7) then feedb_ptr^ := feedb_ptr^ AND 1+((feedb_ptr^ SHR 1) AND 7 +1) SHL 1; end; procedure _dec_feedback_val; var feedb_ptr: tBYTE_PTR; begin If NOT (get_4op_to_test <> 0) then feedb_ptr := tBYTE_PTR(Addr(songdata.instr_data[current_inst].fm_data.FEEDBACK_FM)) else feedb_ptr := tBYTE_PTR(Addr(songdata.instr_data[LO(get_4op_to_test)].fm_data.FEEDBACK_FM)); If ((feedb_ptr^ SHR 1) AND 7 > 0) then feedb_ptr^ := feedb_ptr^ AND 1+((feedb_ptr^ SHR 1) AND 7 -1) SHL 1; end; function _get_finetune_val: Shortint; begin If NOT (get_4op_to_test <> 0) then _get_finetune_val := songdata.instr_data[current_inst].fine_tune else _get_finetune_val := songdata.instr_data[LO(get_4op_to_test)].fine_tune; end; procedure _inc_finetune_val; begin If NOT (get_4op_to_test <> 0) then songdata.instr_data[current_inst].fine_tune := max(songdata.instr_data[current_inst].fine_tune+1,127) else songdata.instr_data[LO(get_4op_to_test)].fine_tune := max(songdata.instr_data[LO(get_4op_to_test)].fine_tune+1,127); end; procedure _dec_finetune_val; begin If NOT (get_4op_to_test <> 0) then songdata.instr_data[current_inst].fine_tune := min(songdata.instr_data[current_inst].fine_tune-1,-127) else songdata.instr_data[LO(get_4op_to_test)].fine_tune := min(songdata.instr_data[LO(get_4op_to_test)].fine_tune-1,-127); end; var _curr_connection_str: String; _status_shift_pos: Byte; _4op_conn_str: String; _4op_slot_str: String; _4op_slot_chr: tSET_OF_CHARS; _col_mod,_col_hi_mod: Byte; procedure _page_build; var temp,nm_slots: Byte; temp_str: String; _pan_4op: String; _feedb_4op: String; _ftune_4op: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_edit:page_build'; {$ENDIF} ShowStr(ptr_temp_screen,xstart+45,ystart, byte2hex(instrum_page), instrument_bckg+instrument_title); If NOT is_default_screen_mode then ShowStr(ptr_temp_screen,xstart-1,ystart+24, #204+ExpStrL('',70,#205)+#185, instrument_bckg+instrument_border); If NOT (inst^.perc_voice in [2..5]) and (get_4op_to_test <> 0) then begin If (LO(get_4op_to_test) = HI(get_4op_to_test)) then _4op_conn_str := connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'/'+ connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1] else If (current_inst = HI(get_4op_to_test)) then _4op_conn_str := '~'+connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'~/'+ connection_str[pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1] else _4op_conn_str := connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'/~'+ connection_str[pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'~'; If (current_inst = LO(get_4op_to_test)) then If NOT carrier then If (HI(get_4op_to_test) <> LO(get_4op_to_test)) then begin _4op_slot_str := '~1~`'#27'`2`'#27'`3`'#27'`4'; _4op_slot_chr := ['1']; end else begin _4op_slot_str := '~1~`'#27'`2`'#27'`~3~`'#27'`4'; _4op_slot_chr := ['1','3'] end else If (HI(get_4op_to_test) <> LO(get_4op_to_test)) then begin _4op_slot_str := '1`'#27'`~2~`'#27'`3`'#27'`4'; _4op_slot_chr := ['2']; end else begin _4op_slot_str := '1`'#27'`~2~`'#27'`3`'#27'`~4~'; _4op_slot_chr := ['2','4']; end else If NOT carrier then If (HI(get_4op_to_test) <> LO(get_4op_to_test)) then begin _4op_slot_str := '1`'#27'`2`'#27'`~3~`'#27'`4'; _4op_slot_chr := ['3']; end else begin _4op_slot_str := '~1~`'#27'`2`'#27'`~3~`'#27'`4'; _4op_slot_chr := ['1','3']; end else If (HI(get_4op_to_test) <> LO(get_4op_to_test)) then begin _4op_slot_str := '1`'#27'`2`'#27'`3`'#27'`~4~'; _4op_slot_chr := ['4']; end else begin _4op_slot_str := '1`'#27'`~2~`'#27'`3`'#27'`~4~'; _4op_slot_chr := ['2','4']; end; end; If (inst^.perc_voice in [2..5]) then begin Move(inst_text_ext_perc,inst_text[9],SizeOf(inst_text_ext_perc)); Move(inst_hpos_ext_perc,inst_hpos[12],SizeOf(inst_hpos_ext_perc)); end else If NOT (get_4op_to_test <> 0) then begin Move(inst_text_ext_2op,inst_text[9],SizeOf(inst_text_ext_2op)); Move(inst_hpos_ext_2op,inst_hpos[12],SizeOf(inst_hpos_ext_2op)); end else begin Move(inst_text_ext_4op,inst_text[9],SizeOf(inst_text_ext_4op)); Move(inst_hpos_ext_4op,inst_hpos[12],SizeOf(inst_hpos_ext_4op)); end; If NOT (inst^.perc_voice in [2..5]) and ((NOT (get_4op_to_test <> 0) and carrier) or ((get_4op_to_test <> 0) and (('2' in _4op_slot_chr) or ('4' in _4op_slot_chr)))) then For temp := 1 to 24 do ShowC4Str(ptr_temp_screen,xstart+1,ystart+temp,inst_text[temp], instrument_bckg+instrument_text, instrument_bckg+instrument_car, instrument_bckg+instrument_glob, instrument_bckg+instrument_hid) else For temp := 1 to 24 do ShowC4Str(ptr_temp_screen,xstart+1,ystart+temp,inst_text[temp], instrument_bckg+instrument_text, instrument_bckg+instrument_mod, instrument_bckg+instrument_glob, instrument_bckg+instrument_hid); If (inst^.perc_voice in [2..5]) then _status_shift_pos := 5 else If NOT (get_4op_to_test <> 0) then _status_shift_pos := 9 else _status_shift_pos := 19; If NOT (inst^.perc_voice in [2..5]) and (get_4op_to_test <> 0) then begin If (LO(get_4op_to_test) = HI(get_4op_to_test)) then ShowC3Str(ptr_temp_screen,xstart,ystart+24, ' `[`'#244+byte2hex(HI(get_4op_to_test))+ ','#245+byte2hex(HI(get_4op_to_test))+' '+_4op_conn_str+'`]` ', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border) else If (current_inst = HI(get_4op_to_test)) then ShowC3Str(ptr_temp_screen,xstart,ystart+24, ' `[`~'#244+byte2hex(HI(get_4op_to_test))+ '~,'#245+byte2hex(LO(get_4op_to_test))+' '+_4op_conn_str+'`]` ', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border) else ShowC3Str(ptr_temp_screen,xstart,ystart+24, ' `[`'#244+byte2hex(HI(get_4op_to_test))+ ',~'#245+byte2hex(LO(get_4op_to_test))+'~ '+_4op_conn_str+'`]` ', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border); _show_conn_scheme(xstart+32,ystart+11,_4op_conn_to_idx(_4op_conn_str),_4op_slot_chr); ShowC3Str(ptr_temp_screen,xstart+17,ystart+24,'`[`'#4#3':'+_4op_slot_str+'`]` ', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border); end else begin If NOT (inst^.perc_voice in [2..5]) then _show_conn_scheme(xstart+32,ystart+11,inst^.fm_data.FEEDBACK_FM AND 1,[CHR(BYTE(carrier)+ORD('1'))]) else _show_conn_scheme(xstart+32,ystart+11,6,['1']); Case inst^.perc_voice of 0: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~MELODiC~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 1: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:BD~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 2: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:SD~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 3: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:TT~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 4: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:TC~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); 5: ShowCStr(ptr_temp_screen,xstart,ystart+24,' [~PERC:HH~]', instrument_bckg+instrument_border, instrument_bckg+instrument_context); end; If (inst^.perc_voice in [2..5]) then ShowCStr(ptr_temp_screen,xstart+10,ystart+24, ' [~'#1#3'~] ', instrument_bckg+instrument_border, instrument_bckg+instrument_context) else If NOT carrier then ShowC3Str(ptr_temp_screen,xstart+10,ystart+24,' `[`'#2#3':~1~`'#27'`2`]`', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border) else ShowC3Str(ptr_temp_screen,xstart+10,ystart+24,' `[`'#2#3':1`'#27'`~2~`]`', instrument_bckg+instrument_context, instrument_context SHL 4, instrument_bckg+instrument_border); end; If (songdata.instr_macros[instrum_page].length <> 0) then temp_str := ' [~MACRO:FM' else temp_str := ' '; With songdata.macro_table[ songdata.instr_macros[instrum_page].arpeggio_table].arpeggio do If (songdata.instr_macros[instrum_page].arpeggio_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ARP' else temp_str := temp_str+'[~MACRO:ARP'; With songdata.macro_table[ songdata.instr_macros[instrum_page].vibrato_table].vibrato do If (songdata.instr_macros[instrum_page].vibrato_table <> 0) then If (temp_str <> ' ') then temp_str := temp_str+'+ViB' else temp_str := temp_str+'[~MACRO:ViB'; If (temp_str <> ' ') then temp_str := temp_str+'~] '; ShowCStr(ptr_temp_screen, xstart+10+_status_shift_pos,ystart+24, ExpStrR(temp_str,39,#205), instrument_bckg+instrument_border, instrument_bckg+instrument_context); If (inst^.perc_voice in [2..5]) then begin temp_str := '```` '; nm_slots := 1; end else If NOT (get_4op_to_test <> 0) then begin temp_str := ' `[`12`]` '; nm_slots := 2; end else begin temp_str := ' `[`1234`]` '; nm_slots := 4; end; temp_str := temp_str+'[~SPEED:'+Num2str(songdata.tempo*songdata.macro_speedup,10)+#174+'~] '; ShowC3Str(ptr_temp_screen,xstart+48,ystart+24, ExpStrL(temp_str,28,#205), instrument_bckg+instrument_border, instrument_bckg+instrument_context, instrument_bckg+instrument_con_dis); If (nm_slots > 1) then For temp := 1 to nm_slots do If (NOT _operator_enabled[temp]) then ShowStr(ptr_temp_screen,xstart+72-C3StrLen(temp_str)-1+temp,ystart+24, #250, instrument_bckg+instrument_border); If (inst_hpos[vpos,hpos] = 0) then begin vpos := 1; hpos := 1; end; If NOT (get_4op_to_test <> 0) then begin _pan_4op := ' '; _feedb_4op := ' '; _ftune_4op := ' '; end else begin If (current_inst = HI(get_4op_to_test)) then _pan_4op := '('#244#2#3')' else _pan_4op := '('#245#2#3')'; _feedb_4op := '['#4#3']'; _ftune_4op := '['#4#3']' end; If NOT (inst^.perc_voice in [2..5]) then begin _col_mod := instrument_mod; _col_hi_mod := instrument_hi_mod; end else begin _col_mod := instrument_glob; _col_hi_mod := instrument_hi_glob; end; If NOT ((vpos = 1) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+1,'~A~TTACK RATE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+1,'~A~TTACK RATE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos = 2) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+2,'~D~ECAY RATE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+2,'~D~ECAY RATE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos in [3,6,8,9]) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+51,ystart+1,'~W~AVEFORM TYPE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+51,ystart+1,'~W~AVEFORM TYPE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos = 4) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+4,'~S~USTAiN LEVEL', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+4,'~S~USTAiN LEVEL', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos = 5) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+5,'~R~ELEASE RATE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+5,'~R~ELEASE RATE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos = 7) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+7,'~O~UTPUT LEVEL', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+7,'~O~UTPUT LEVEL', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos in [10..13]) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+9,'~K~EY SCALiNG LEVEL', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+9,'~K~EY SCALiNG LEVEL', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT (inst^.perc_voice in [2..5]) then begin If NOT (((vpos in [12,13]) and (hpos = 2)) or ((vpos in [14,15]) and (hpos = 1)) or ((vpos = 17) and (hpos = 4))) then ShowCStr(ptr_temp_screen,xstart+21,ystart+11,'~C~ONNECTiON', instrument_bckg+instrument_glob, instrument_bckg+instrument_hi_glob); If NOT ((vpos = 12) and (hpos = 3)) then ShowCStr(ptr_temp_screen,xstart+51,ystart+11,'~F~EEDBACK '+_feedb_4op, instrument_bckg+instrument_glob, instrument_bckg+instrument_hi_glob); end; If NOT ((vpos = 16) and (hpos = 2)) then ShowCStr(ptr_temp_screen,xstart+51,ystart+15,'F-~T~UNE '+_ftune_4op, instrument_bckg+instrument_glob, instrument_bckg+instrument_hi_glob); If NOT ((vpos = 17) and (hpos in [1..3])) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+15,'~P~ANNiNG '+_pan_4op, instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+15,'~P~ANNiNG '+_pan_4op, instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos in [18..21]) and (hpos = 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+1,ystart+19,'~E~NVELOPE TYPE', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+1,ystart+19,'~E~NVELOPE TYPE', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); If NOT ((vpos in [18..20]) and (hpos > 1)) then If carrier then ShowCStr(ptr_temp_screen,xstart+28,ystart+19,'FREQUENCY DATA ~M~ULTiPLiER', instrument_bckg+instrument_car, instrument_bckg+instrument_hi_car) else ShowCStr(ptr_temp_screen,xstart+28,ystart+19,'FREQUENCY DATA ~M~ULTiPLiER', instrument_bckg+_col_mod, instrument_bckg+_col_hi_mod); Case hpos of 1: Case vpos of 1: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+1,'ATTACK RATE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+1,'ATTACK RATE', instrument_bckg+_col_hi_mod); 2: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+2,'DECAY RATE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+2,'DECAY RATE', instrument_bckg+_col_hi_mod); 3,6,8, 9: If carrier then ShowStr(ptr_temp_screen,xstart+51,ystart+1,'WAVEFORM TYPE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+51,ystart+1,'WAVEFORM TYPE', instrument_bckg+_col_hi_mod); 4: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+4,'SUSTAiN LEVEL', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+4,'SUSTAiN LEVEL', instrument_bckg+_col_hi_mod); 5: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+5,'RELEASE RATE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+5,'RELEASE RATE', instrument_bckg+_col_hi_mod); 7: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+7,'OUTPUT LEVEL', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+7,'OUTPUT LEVEL', instrument_bckg+_col_hi_mod); 10..17: If (vpos in [10..13]) and (hpos = 1) then If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+9,'KEY SCALiNG LEVEL', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+9,'KEY SCALiNG LEVEL', instrument_bckg+_col_hi_mod) else If (vpos <> 17) then ShowStr(ptr_temp_screen,xstart+21,ystart+11,'CONNECTiON', instrument_bckg+instrument_hi_glob) else If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+15,'PANNiNG '+_pan_4op, instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+15,'PANNiNG '+_pan_4op, instrument_bckg+_col_hi_mod); 18,19,20, 21: If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+19,'ENVELOPE TYPE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+19,'ENVELOPE TYPE', instrument_bckg+_col_hi_mod); end; 2,3,4,5,6, 7: Case vpos of 2,4,5, 7: If carrier then ShowStr(ptr_temp_screen,xstart+51,ystart+1,'WAVEFORM TYPE', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+51,ystart+1,'WAVEFORM TYPE', instrument_bckg+_col_hi_mod); 12..17: If (vpos = 12) and (hpos = 3) then ShowStr(ptr_temp_screen,xstart+51,ystart+11,'FEEDBACK '+_feedb_4op, instrument_bckg+instrument_hi_glob) else If (vpos = 16) and (hpos = 2) then ShowStr(ptr_temp_screen,xstart+51,ystart+15,'F-TUNE '+_ftune_4op, instrument_bckg+instrument_hi_glob) else If (vpos = 17) and (hpos in [1..3]) then If carrier then ShowStr(ptr_temp_screen,xstart+1,ystart+15,'PANNiNG '+_pan_4op, instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+1,ystart+15,'PANNiNG '+_pan_4op, instrument_bckg+_col_hi_mod) else ShowStr(ptr_temp_screen,xstart+21,ystart+11,'CONNECTiON', instrument_bckg+instrument_hi_glob); 18,19,20, 21: If carrier then ShowStr(ptr_temp_screen,xstart+28,ystart+19,'FREQUENCY DATA MULTiPLiER', instrument_bckg+instrument_hi_car) else ShowStr(ptr_temp_screen,xstart+28,ystart+19,'FREQUENCY DATA MULTiPLiER', instrument_bckg+_col_hi_mod); end; end; end; procedure _page_refresh; var temp,x0,y0: Byte; temps1,temps2: String; adsr_vpos: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_edit:page_refresh'; {$ENDIF} x0 := xstart; y0 := ystart; If is_default_screen_mode then begin adsr_vpos := y0+9; adsr_bckg := instrument_adsr; end else begin adsr_vpos := y0+24; adsr_bckg := instrument_bckg; end; If (NOT ((vpos in [1,2,4,5,7,21]) and (hpos = 1)) or NOT _ADSR_preview_flag) then begin _show_adsr(ptr_temp_screen,x0+3,adsr_vpos, BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL, adsr_bckg,adsr_bckg, TRUE); _page_build; end; If carrier then temp := inst^.fm_data.ATTCK_DEC_carrier else temp := inst^.fm_data.ATTCK_DEC_modulator; ShowCStr(ptr_temp_screen,x0+inst_hpos[1,1],y0+inst_vpos[1],'~'+ ExpStrL('', (temp SHR 4),#14)+'~'+ ExpStrL('',15-(temp SHR 4),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowCStr(ptr_temp_screen,x0+inst_hpos[2,1],y0+inst_vpos[2],'~'+ ExpStrL('', (temp AND $0f),#14)+'~'+ ExpStrL('',15-(temp AND $0f),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowStr(ptr_temp_screen,x0+inst_hpos[1,1]+16,y0+inst_vpos[1], ExpStrR(Num2str(temp SHR 4,16),1,' '), instrument_bckg+instrument_text); ShowStr(ptr_temp_screen,x0+inst_hpos[2,1]+16,y0+inst_vpos[2], ExpStrR(Num2str(temp AND $0f,16),1,' '), instrument_bckg+instrument_text); If carrier then temp := inst^.fm_data.SUSTN_REL_carrier else temp := inst^.fm_data.SUSTN_REL_modulator; ShowCStr(ptr_temp_screen,x0+inst_hpos[4,1],y0+inst_vpos[4],'~'+ ExpStrL('', (temp SHR 4),#14)+'~'+ ExpStrL('',15-(temp SHR 4),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowCStr(ptr_temp_screen,x0+inst_hpos[5,1],y0+inst_vpos[5],'~'+ ExpStrL('', (temp AND $0f),#14)+'~'+ ExpStrL('',15-(temp AND $0f),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowStr(ptr_temp_screen,x0+inst_hpos[4,1]+16,y0+inst_vpos[4], ExpStrR(Num2str(temp SHR 4,16),1,' '), instrument_bckg+instrument_text); ShowStr(ptr_temp_screen,x0+inst_hpos[5,1]+16,y0+inst_vpos[5], ExpStrR(Num2str(temp AND $0f,16),1,' '), instrument_bckg+instrument_text); If carrier then temp := inst^.fm_data.WAVEFORM_carrier else temp := inst^.fm_data.WAVEFORM_modulator; ShowVStr(ptr_temp_screen,x0+inst_hpos[2,2],y0+inst_vpos[2], ExpStrL('',temp AND 7,' ')+#11+ExpStrL('',7-temp AND 7,' '), instrument_bckg+instrument_hi_text); If carrier then temp := inst^.fm_data.KSL_VOLUM_carrier else temp := inst^.fm_data.KSL_VOLUM_modulator; ShowCStr(ptr_temp_screen,x0+inst_hpos[7,1],y0+inst_vpos[7],'~'+ ExpStrL('', ((63-(temp AND $3f)) DIV 2),#14)+'~'+ ExpStrL('',31-((63-(temp AND $3f)) DIV 2),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowStr(ptr_temp_screen,x0+inst_hpos[7,1]+32,y0+inst_vpos[7], ExpStrR(Num2str(63-(temp AND $3f),16),2,' '), instrument_bckg+instrument_text); temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; ShowVStr(ptr_temp_screen,x0+inst_hpos[10,1],y0+inst_vpos[10], ExpStrL('',temp,' ')+#11+ExpStrL('',3-temp,' '), instrument_bckg+instrument_hi_text); ShowCStr(ptr_temp_screen,x0+inst_hpos[17,1],y0+inst_vpos[17],ins_pan_str1[inst^.panning], instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); If NOT (inst^.perc_voice in [2..5]) then begin temp := inst^.fm_data.FEEDBACK_FM; ShowCStr(ptr_temp_screen,x0+inst_hpos[12,3],y0+inst_vpos[12],'~'+ ExpStrL('', ROUND(_get_feedback_val*(17/7)),#14)+'~'+ ExpStrL('',17-ROUND(_get_feedback_val*(17/7)),#14), instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text); ShowStr(ptr_temp_screen,x0+inst_hpos[12,3]+16,y0+inst_vpos[12]-1, ExpStrR(Num2str(_get_feedback_val,16),2,' '), instrument_bckg+instrument_text); _curr_connection_str := ExpStrR('',6,' '); If NOT (get_4op_to_test <> 0) then If (temp AND 1 = 0) then _curr_connection_str[1] := #11 else _curr_connection_str[2] := #11 else _curr_connection_str[_4op_conn_to_idx(_4op_conn_str)+1] := #11; If NOT (get_4op_to_test <> 0) then ShowVStr(ptr_temp_screen,x0+inst_hpos[12,2],y0+inst_vpos[12],_curr_connection_str, instrument_bckg+instrument_hi_text) else ShowVStr(ptr_temp_screen,x0+inst_hpos[14,1],y0+inst_vpos[12],_curr_connection_str, instrument_bckg+instrument_hi_text); end; If (_get_finetune_val >= 0) then temp := _get_finetune_val else temp := 0-_get_finetune_val; temps1 := ExpStrL('',17,#14); If (vpos = 16) and (hpos = 2) then temps2 := #15'~'#15'~'#15 else temps2 := #15'`'#15'`'#15; If (_get_finetune_val > 0) then begin Delete(temps1,1+7+(temp DIV 18),3); Insert(temps2,temps1,1+7+(temp DIV 18)); end else begin Delete(temps1,1+7-(temp DIV 18),3); Insert(temps2,temps1,1+7-(temp DIV 18)); end; If (_get_finetune_val > 0) then temps2 := '+' else If (_get_finetune_val < 0) then temps2 := '-' else temps2 := ''; ShowStr(ptr_temp_screen,x0+inst_hpos[16,2]+14,y0+inst_vpos[16]-1, ExpStrL(temps2+ExpStrL(Num2str(temp,16),2,'0'),3,' '), instrument_bckg+instrument_text); ShowC3Str(ptr_temp_screen,x0+inst_hpos[16,2],y0+inst_vpos[16],temps1, instrument_bckg+instrument_text, instrument_bckg+instrument_hi_text, instrument_bckg+instrument_glob); If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier else temp := inst^.fm_data.AM_VIB_EG_modulator; If (temp SHR 7 = 0) then temps1 := ' ' else temps1 := #251; If ((temp SHR 6) AND 1 = 0) then temps1 := temps1+' ' else temps1 := temps1+#251; If ((temp SHR 4) AND 1 = 0) then temps1 := temps1+' ' else temps1 := temps1+#251; If ((temp SHR 5) AND 1 = 0) then temps1 := temps1+' ' else temps1 := temps1+#251; ShowVStr(ptr_temp_screen,x0+inst_hpos[18,1],y0+inst_vpos[18],temps1, instrument_bckg+instrument_hi_text); temps1 := ExpStrL('',16,' '); temps1[(temp AND $0f)+1] := '.'; If ((vpos in [19..21]) and (hpos in [2..7])) then ShowStr(ptr_temp_screen,x0+inst_hpos[21,2]-1,y0+inst_vpos[19]-1, ExpStrR(inst_mult_hint[(vpos-19)*6+hpos-2],34,' '), instrument_bckg+instrument_hi_text) else ShowStr(ptr_temp_screen,x0+inst_hpos[21,2]-1,y0+inst_vpos[19]-1, ExpStrR(inst_mult_hint[temp AND $0f],34,' '), instrument_bckg+instrument_hi_text); For temp := 1 to 6 do If (temps1[temp] = ' ') then ShowStr(ptr_temp_screen,x0+inst_hpos[19,2+temp-1],y0+inst_vpos[19],' ', instrument_bckg+instrument_hi_text) else ShowStr(ptr_temp_screen,x0+inst_hpos[19,2+temp-1],y0+inst_vpos[19],#11, instrument_bckg+instrument_hi_text); For temp := 1 to 6 do If (temps1[6+temp] = ' ') then ShowStr(ptr_temp_screen,x0+inst_hpos[20,2+temp-1],y0+inst_vpos[20],' ', instrument_bckg+instrument_hi_text) else ShowStr(ptr_temp_screen,x0+inst_hpos[20,2+temp-1],y0+inst_vpos[20],#11, instrument_bckg+instrument_hi_text); For temp := 1 to 4 do If (temps1[12+temp] = ' ') then ShowStr(ptr_temp_screen,x0+inst_hpos[21,2+temp-1],y0+inst_vpos[21],' ', instrument_bckg+instrument_hi_text) else ShowStr(ptr_temp_screen,x0+inst_hpos[21,2+temp-1],y0+inst_vpos[21],#11, instrument_bckg+instrument_hi_text); If NOT is_default_screen_mode or ((vpos in [1,2,4,5,7,21]) and (hpos = 1) and _ADSR_preview_flag) then If NOT carrier or (inst^.perc_voice in [2..5]) then _show_adsr(ptr_temp_screen,x0+3,adsr_vpos, inst^.fm_data.ATTCK_DEC_modulator SHR 4, inst^.fm_data.ATTCK_DEC_modulator AND $0f, inst^.fm_data.SUSTN_REL_modulator SHR 4, inst^.fm_data.SUSTN_REL_modulator AND $0f, inst^.fm_data.KSL_VOLUM_modulator AND $3f, inst^.fm_data.AM_VIB_EG_modulator SHR 5 AND 1, adsr_bckg+_col_mod, adsr_bckg+_col_hi_mod,FALSE) else _show_adsr(ptr_temp_screen,x0+3,adsr_vpos, inst^.fm_data.ATTCK_DEC_carrier SHR 4, inst^.fm_data.ATTCK_DEC_carrier AND $0f, inst^.fm_data.SUSTN_REL_carrier SHR 4, inst^.fm_data.SUSTN_REL_carrier AND $0f, inst^.fm_data.KSL_VOLUM_carrier AND $3f, inst^.fm_data.AM_VIB_EG_carrier SHR 5 AND 1, adsr_bckg+instrument_car, adsr_bckg+instrument_hi_car,FALSE); move2screen_alt; end; procedure _sync_radio_buttons; var temp: Byte; begin If ((vpos in [1,2,4,5,7]) and (hpos = 2)) or (vpos in [3,6,8,9]) then // sync WAVEFORM begin If carrier then vpos := 2+songdata.instr_data[current_inst].fm_data.WAVEFORM_carrier else vpos := 2+songdata.instr_data[current_inst].fm_data.WAVEFORM_modulator; If (vpos in [1,2,4,5,7]) then hpos := 2 else If (vpos in [3,6,8,9]) then hpos := 1; end; If (vpos in [10..13]) and (hpos = 1) then // sync SCALING LEVEL begin If carrier then temp := songdata.instr_data[current_inst].fm_data.KSL_VOLUM_carrier else temp := songdata.instr_data[current_inst].fm_data.KSL_VOLUM_modulator; temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; vpos := 10+temp; hpos := 1; end; If (vpos = 17) and (hpos in [1..3]) then // sync PANNING Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end; If ((vpos in [12,13]) and (hpos = 2)) or ((vpos in [14,15,16]) and (hpos = 1)) or ((vpos = 17) and (hpos = 4)) then // sync CONNECTION Case Pos(#11,_curr_connection_str) of 1: begin vpos := 12; hpos := 2; end; 2: begin vpos := 13; hpos := 2; end; 3: begin vpos := 14; hpos := 1; end; 4: begin vpos := 15; hpos := 1; end; 5: begin vpos := 16; hpos := 1; end; 6: begin vpos := 17; hpos := 3; end; end; If (vpos in [19..21]) and (hpos > 1) then // sync FREQ. DATA MULT. begin If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier AND $0f else temp := inst^.fm_data.AM_VIB_EG_modulator AND $0f; hpos := 2+(temp MOD 6); vpos := 19+(temp DIV 6); end; end; procedure INSTRUMENT_CONTROL_edit; function min0(number: Integer): Integer; begin If (number > 0) then min0 := number else min0 := 0; end; function _ftune(ftune: Integer): Integer; var temp: Integer; begin If (ftune DIV 18 = 0) and (ftune <> 0) then temp := 0 else temp := ABS(ftune) DIV 18; _ftune := (ftune DIV min(ABS(ftune),1))*temp; end; function _check_hpos_idx_l(vpos: Byte): Byte; var idx: Byte; begin _check_hpos_idx_l := 0; For idx := 1 to inst_hpos_max do If (inst_hpos[vpos,idx] <> 0) then begin _check_hpos_idx_l := idx; BREAK; end; end; function _check_hpos_idx_r(vpos: Byte): Byte; var idx: Byte; begin _check_hpos_idx_r := 0; For idx := inst_hpos_max downto 1 do If (inst_hpos[vpos,idx] <> 0) then begin _check_hpos_idx_r := idx; BREAK; end; end; procedure _set_operator_flag(operator: Byte; toggle: Boolean); var _temp_operator_enabled: array[1..4] of Boolean; begin If (inst^.perc_voice in [2..5]) or (NOT (get_4op_to_test <> 0) and NOT (operator in [1..2])) or (NOT (operator in [1..4])) then EXIT; If NOT toggle then begin FillChar(_operator_enabled,SizeOf(_operator_enabled),FALSE); _operator_enabled[operator] := TRUE; EXIT; end; Move(_operator_enabled,_temp_operator_enabled,SizeOf(_temp_operator_enabled)); If NOT (get_4op_to_test <> 0) and (operator in [1,2]) then begin _temp_operator_enabled[operator] := NOT _temp_operator_enabled[operator]; If NOT ((_temp_operator_enabled[1] = FALSE) and (_temp_operator_enabled[2] = FALSE)) then Move(_temp_operator_enabled,_operator_enabled,SizeOf(_operator_enabled)); end else If (get_4op_to_test <> 0) and (operator in [1,2,3,4]) then begin _temp_operator_enabled[operator] := NOT _temp_operator_enabled[operator]; If NOT ((_temp_operator_enabled[1] = FALSE) and (_temp_operator_enabled[2] = FALSE) and (_temp_operator_enabled[3] = FALSE) and (_temp_operator_enabled[4] = FALSE)) then Move(_temp_operator_enabled,_operator_enabled,SizeOf(_operator_enabled)); end; end; const KSL_volume: array[0..3] of Byte = (0,$80,$40,$0c0); AM_Vibrato_EG: array[0..3] of Byte = ($80,$40,$10,$20); panning_pos: array[0..2] of Byte = (1,0,2); label _jmp1,_end; begin { INSTRUMENT_CONTROL_edit } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_edit'; {$ENDIF} inst := Addr(songdata.instr_data[instrum_page]); FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); If NOT (inst^.perc_voice in [2..5]) then If remember_ins_pos then begin temp := get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier',-1); If (temp <> 2) then carrier := TRUE else carrier := FALSE; end else carrier := TRUE else carrier := FALSE; If NOT remember_ins_pos then begin hpos := 1; vpos := 1; end else If carrier then begin hpos := min(get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?hpos',-1),1); vpos := min(get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?vpos',-1),1); end else begin hpos := min(get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?hpos',-1),1); vpos := min(get_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?vpos',-1),1); end; _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,71,24+INSEDIT_yshift,' iNSTRUMENT EDiTOR (iNS_ ) ', instrument_bckg+instrument_border, instrument_bckg+instrument_title, frame_double); centered_frame_vdest := screen_ptr; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen_alt; move_to_screen_area[1] := xstart+1; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+70; move_to_screen_area[4] := ystart+24+INSEDIT_yshift; Inc(xstart); _page_build; _sync_radio_buttons; If NOT _force_program_quit then Repeat keyboard_poll_input; _page_build; _page_refresh; If ((vpos in [1,2,4,5,7]) and (hpos = 1)) or ((vpos = 12) and (hpos = 3)) or ((vpos = 16) and (hpos = 2)) then With songdata.instr_data[current_inst] do begin Case vpos of 1: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.ATTCK_DEC_carrier SHR 4-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.ATTCK_DEC_modulator SHR 4-1), ystart+inst_vpos[vpos]); 2: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.ATTCK_DEC_carrier AND $0f-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.ATTCK_DEC_modulator AND $0f-1), ystart+inst_vpos[vpos]); 4: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.SUSTN_REL_carrier SHR 4-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.SUSTN_REL_modulator SHR 4-1), ystart+inst_vpos[vpos]); 5: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.SUSTN_REL_carrier AND $0f-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(fm_data.SUSTN_REL_modulator AND $0f-1), ystart+inst_vpos[vpos]); 7: If carrier then GotoXY(xstart+inst_hpos[vpos,hpos]+ min0((63-fm_data.KSL_VOLUM_carrier AND $3f) DIV 2-1), ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+ min0((63-fm_data.KSL_VOLUM_modulator AND $3f) DIV 2-1), ystart+inst_vpos[vpos]); 12: GotoXY(xstart+inst_hpos[vpos,hpos]+ min0(ROUND(_get_feedback_val*(17/7))-1), ystart+inst_vpos[vpos]); 16: If (_get_finetune_val > 0) then GotoXY(xstart+inst_hpos[vpos,hpos]+7+_ftune(_get_finetune_val)+1, ystart+inst_vpos[vpos]) else If (_get_finetune_val < 0) then GotoXY(xstart+inst_hpos[vpos,hpos]+1+7+_ftune(_get_finetune_val)-1, ystart+inst_vpos[vpos]) else GotoXY(xstart+inst_hpos[vpos,hpos]+1+7+_ftune(_get_finetune_val), ystart+inst_vpos[vpos]); end; SetCursorShape($010c); end else begin ThinCursor; GotoXY(xstart+inst_hpos[vpos,hpos],ystart+inst_vpos[vpos]); end; nope := FALSE; If keypressed then fkey := getkey else GOTO _end; If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then If (get_4op_to_test <> 0) then INSTRUMENT_test(LO(get_4op_to_test),HI(get_4op_to_test),count_channel(pattern_hpos),fkey,TRUE) else INSTRUMENT_test(instrum_page,0,count_channel(pattern_hpos),fkey,TRUE); Case fkey of kAlt0: FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); kAlt1: If shift_pressed then _set_operator_flag(1,TRUE) else _set_operator_flag(1,FALSE); kAlt2: If shift_pressed then _set_operator_flag(2,TRUE) else _set_operator_flag(2,FALSE); kAlt3: If shift_pressed then _set_operator_flag(3,TRUE) else _set_operator_flag(3,FALSE); kAlt4: If shift_pressed then _set_operator_flag(4,TRUE) else _set_operator_flag(4,FALSE); kAltA: begin hpos := 1; vpos := 1; end; kAltD: begin hpos := 1; vpos := 2; end; kAltS: begin hpos := 1; vpos := 4; end; kAltR: begin hpos := 1; vpos := 5; end; kAltO: begin hpos := 1; vpos := 7; end; kAltW: begin If carrier then vpos := 2+inst^.fm_data.WAVEFORM_carrier else vpos := 2+inst^.fm_data.WAVEFORM_modulator; If (vpos in [2,4,5,7]) then hpos := 2 else hpos := 1; end; kAltK: begin If carrier then temp := inst^.fm_data.KSL_VOLUM_carrier else temp := inst^.fm_data.KSL_VOLUM_modulator; temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; vpos := 10+temp; hpos := 1; end; kAltP: Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end; kAltC: If NOT (inst^.perc_voice in [2..5]) then Case Pos(#11,_curr_connection_str) of 1: begin vpos := 12; hpos := 2; end; 2: begin vpos := 13; hpos := 2; end; 3: begin vpos := 14; hpos := 1; end; 4: begin vpos := 15; hpos := 1; end; 5: begin vpos := 16; hpos := 1; end; 6: begin vpos := 17; hpos := 4; end; end; kAltF: If NOT (inst^.perc_voice in [2..5]) then begin vpos := 12; hpos := 3; end; kAltT: begin vpos := 16; hpos := 2; end; kAltE: begin vpos := 18; hpos := 1; end; kAltM: begin If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier AND $0f else temp := inst^.fm_data.AM_VIB_EG_modulator AND $0f; hpos := 2+(temp MOD 6); vpos := 19+(temp DIV 6); end; kLEFT: If (hpos-1 >= 1) and (inst_hpos[vpos,hpos-1] <> 0) then Dec(hpos) else If (hpos-2 >= 1) and (inst_hpos[vpos,hpos-2] <> 0) then Dec(hpos,2) else If (vpos > 1) then begin Repeat Dec(vpos) until (_check_hpos_idx_r(vpos) <> 0); hpos := _check_hpos_idx_r(vpos); end else begin vpos := inst_vpos_max; hpos := inst_hpos_max; While (hpos > 1) and (inst_hpos[vpos,hpos] = 0) do Dec(hpos); end; kRIGHT: If (hpos+1 <= inst_hpos_max) and (inst_hpos[vpos,hpos+1] <> 0) then Inc(hpos) else If (hpos+2 <= inst_hpos_max) and (inst_hpos[vpos,hpos+2] <> 0) then Inc(hpos,2) else If (vpos < inst_vpos_max) then begin Repeat Inc(vpos) until (_check_hpos_idx_l(vpos) <> 0); hpos := _check_hpos_idx_l(vpos); end else begin vpos := 1; hpos := 1; end; kUP: If (vpos > 1) then begin Repeat Dec(vpos) until (inst_hpos[vpos,1] <> 0); temp := hpos; hpos := inst_hpos_max; While (hpos > 1) and ((inst_hpos[vpos,hpos] = 0) or (inst_hpos[vpos,hpos] > inst_hpos[vpos+1,temp])) do Dec(hpos); end else begin vpos := inst_vpos_max; temp := hpos; hpos := inst_hpos_max; While (hpos > 1) and ((inst_hpos[vpos,hpos] = 0) or (inst_hpos[vpos,hpos] > inst_hpos[vpos+1,temp])) do Dec(hpos); end; kDOWN: If (vpos < inst_vpos_max) then begin Repeat Inc(vpos) until (inst_hpos[vpos,1] <> 0); temp := hpos; hpos := inst_hpos_max; While (hpos > 1) and ((inst_hpos[vpos,hpos] = 0) or (inst_hpos[vpos,hpos] > inst_hpos[vpos-1,temp])) do Dec(hpos); end else begin vpos := 1; temp := hpos; hpos := inst_hpos_max; While (hpos > 1) and ((inst_hpos[vpos,hpos] = 0) or (inst_hpos[vpos,hpos] > inst_hpos[vpos-1,temp])) do Dec(hpos) end; kHOME: begin vpos := 1; hpos := 1; end; kEND: begin vpos := inst_vpos_max; hpos := inst_hpos_max; While (hpos > 1) and (inst_hpos[vpos,hpos] = 0) do Dec(hpos); end; kTAB: Case vpos of 1: begin vpos := 2; hpos := 1; end; // ATTACK RATE -> DECAY RATE 2: If (hpos = 1) then begin vpos := 4; hpos := 1; end // DECAY RATE -> SUSTAIN LEVEL else begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 3: begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 4: If (hpos = 1) then begin vpos := 5; hpos := 1; end // SUSTAIN LEVEL -> RELEASE RATE else begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 5: If (hpos = 1) then // RELEASE RATE -> WAVEFORM TYPE begin If carrier then vpos := 2+inst^.fm_data.WAVEFORM_carrier else vpos := 2+inst^.fm_data.WAVEFORM_modulator; If (vpos in [2,4,5,7]) then hpos := 2 else hpos := 1; end else begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 6: begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 7: If (hpos = 1) then // OUTPUT LEVEL -> KEY SCALiNG LEVEL begin If carrier then temp := inst^.fm_data.KSL_VOLUM_carrier else temp := inst^.fm_data.KSL_VOLUM_modulator; temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; vpos := 10+temp; hpos := 1; end else begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 8, 9: begin vpos := 7; hpos := 1; end; // WAVEFORM TYPE -> OUTPUT LEVEL 10,11,12, 13: If (hpos = 1) then // KEY SCALING LEVEL -> PANNING Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end else If (vpos in [12,13]) and (hpos = 2) then // CONNECTION -> FEEDBACK begin vpos := 12; hpos := 3; end else begin vpos := 16; hpos := 2; end; // FEEDBACK -> F-TUNE 14,15, 16: If (hpos = 1) then // CONNECTION -> FEEDBACK begin vpos := 12; hpos := 3; end else begin vpos := 18; hpos := 1; end; // F-TUNE -> AM/VIB/EG/KSR 17: If (hpos in [1,2,3]) then If NOT (inst^.perc_voice in [2..5]) then // PANNING -> CONNECTION Case Pos(#11,_curr_connection_str) of 1: begin vpos := 12; hpos := 2; end; 2: begin vpos := 13; hpos := 2; end; 3: begin vpos := 14; hpos := 1; end; 4: begin vpos := 15; hpos := 1; end; 5: begin vpos := 16; hpos := 1; end; 6: begin vpos := 17; hpos := 3; end; end else begin vpos := 16; hpos := 2; end // PERC:SD/TT/TC/HH == PANNING -> F-TUNE else begin vpos := 12; hpos := 3; end; // CONNECTION -> FEEDBACK 18,19,20, 21: If (vpos = 18) or (hpos = 1) then // AM/VIB/EG/KSR -> FREQ. DATA MULT. begin If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier AND $0f else temp := inst^.fm_data.AM_VIB_EG_modulator AND $0f; hpos := 2+(temp MOD 6); vpos := 19+(temp DIV 6); end else begin // *NEXT SLOT* vpos := 1; hpos := 1; If NOT (inst^.perc_voice in [2..5]) then begin carrier := NOT carrier; If carrier and (get_4op_to_test <> 0) then begin If (current_inst = LO(get_4op_to_test)) then current_inst := HI(get_4op_to_test) else current_inst := LO(get_4op_to_test); instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); _page_build; _page_refresh; end; end; end; end; kShTAB: Case vpos of 1: begin // *PREVIOUS SLOT* If NOT (inst^.perc_voice in [2..5]) then begin carrier := NOT carrier; If NOT carrier and (get_4op_to_test <> 0) then begin If (current_inst = LO(get_4op_to_test)) then current_inst := HI(get_4op_to_test) else current_inst := LO(get_4op_to_test); instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); _page_build; _page_refresh; end; end; If carrier then temp := inst^.fm_data.AM_VIB_EG_carrier AND $0f else temp := inst^.fm_data.AM_VIB_EG_modulator AND $0f; hpos := 2+(temp MOD 6); vpos := 19+(temp DIV 6); end; 2: If (hpos = 1) then begin vpos := 1; hpos := 1; end // DECAY RATE -> ATTACK RATE else begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 3: begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 4: If (hpos = 1) then begin vpos := 2; hpos := 1; end else begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 5: If (hpos = 1) then begin vpos := 4; hpos := 1; end else begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 6: begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 7: If (hpos = 1) then // OUTPUT LEVEL -> WAVEFORM TYPE begin If carrier then vpos := 2+inst^.fm_data.WAVEFORM_carrier else vpos := 2+inst^.fm_data.WAVEFORM_modulator; If (vpos in [2,4,5,7]) then hpos := 2 else hpos := 1; end else begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 8, 9: begin vpos := 5; hpos := 1; end; // WAVEFORM TYPE -> RELEASE RATE 10,11,12, 13: If (hpos = 1) then // KEY SCALING RATE -> OUTPUT LEVEL begin vpos := 7; hpos := 1; end else If (hpos = 2) then // CONNECTION -> PANNING Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end else Case Pos(#11,_curr_connection_str) of // FEEDBACK -> CONNECTION 1: begin vpos := 12; hpos := 2; end; 2: begin vpos := 13; hpos := 2; end; 3: begin vpos := 14; hpos := 1; end; 4: begin vpos := 15; hpos := 1; end; 5: begin vpos := 16; hpos := 1; end; 6: begin vpos := 17; hpos := 3; end; end; 14,15, 16: If (hpos = 1) then // CONNECTION -> PANNING Case inst^.panning of 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end else If NOT (inst^.perc_voice in [2..5]) then // F-TUNE -> FEEDBACK begin vpos := 12; hpos := 3; end else Case inst^.panning of // PERC:SD/TT/TC/HH == F-TUNE -> PANNING 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end; 17: If (hpos in [1,2,3]) then // PANNING -> KEY SCALING LEVEL begin If carrier then temp := inst^.fm_data.KSL_VOLUM_carrier else temp := inst^.fm_data.KSL_VOLUM_modulator; temp := temp SHR 6; temp := temp SHR 1+temp AND 1 SHL 1; vpos := 10+temp; hpos := 1; end else Case inst^.panning of // CONNECTION -> PANNING 1: begin vpos := 17; hpos := 1; end; 0: begin vpos := 17; hpos := 2; end; 2: begin vpos := 17; hpos := 3; end; end; 18,19,20, 21: If (vpos = 18) or (hpos = 1) then begin vpos := 16; hpos := 2; end // AM/VIB/EG/KSR -> F-TUNE else begin vpos := 18; hpos := 1; end; // FREQ. DATA MULT. -> AM/VIB/EG/KSR end; kSPACE: If ctrl_pressed then _ADSR_preview_flag := NOT _ADSR_preview_flag else begin Case vpos of 2: If (hpos = 2) then If carrier then inst^.fm_data.WAVEFORM_carrier := 0 else inst^.fm_data.WAVEFORM_modulator := 0; 3: If carrier then inst^.fm_data.WAVEFORM_carrier := 1 else inst^.fm_data.WAVEFORM_modulator := 1; 4: If (hpos = 2) then If carrier then inst^.fm_data.WAVEFORM_carrier := 2 else inst^.fm_data.WAVEFORM_modulator := 2; 5: If (hpos = 2) then If carrier then inst^.fm_data.WAVEFORM_carrier := 3 else inst^.fm_data.WAVEFORM_modulator := 3; 6: If carrier then inst^.fm_data.WAVEFORM_carrier := 4 else inst^.fm_data.WAVEFORM_modulator := 4; 7: If (hpos = 2) then If carrier then inst^.fm_data.WAVEFORM_carrier := 5 else inst^.fm_data.WAVEFORM_modulator := 5; 8: If carrier then inst^.fm_data.WAVEFORM_carrier := 6 else inst^.fm_data.WAVEFORM_modulator := 6; 9: If carrier then inst^.fm_data.WAVEFORM_carrier := 7 else inst^.fm_data.WAVEFORM_modulator := 7; 10..16, 17: If (vpos in [10..13]) and (hpos = 1) then If carrier then inst^.fm_data.KSL_VOLUM_carrier := inst^.fm_data.KSL_VOLUM_carrier AND $3f+KSL_volume[vpos-10] else inst^.fm_data.KSL_VOLUM_modulator := inst^.fm_data.KSL_VOLUM_modulator AND $3f+KSL_volume[vpos-10] else If ((vpos in [12,13]) and (hpos = 2)) or ((vpos in [14,15,16]) and (hpos = 1)) or ((vpos = 17) and (hpos = 4)) then Case vpos of 12,13: If NOT (get_4op_to_test <> 0) then inst^.fm_data.FEEDBACK_FM := vpos-12+inst^.fm_data.FEEDBACK_FM AND $0e; 14: If (get_4op_to_test <> 0) then begin pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] := 0+ pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] := 0+ pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; end; 15: If (get_4op_to_test <> 0) then begin pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] := 0+ pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] := 1+ pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; end; 16: If (get_4op_to_test <> 0) then begin pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] := 1+ pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] := 0+ pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; end; 17: If (get_4op_to_test <> 0) then begin pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] := 1+ pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] := 1+ pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND $0e; end; end else If (vpos = 17) and (hpos in [1..3]) then inst^.panning := panning_pos[hpos-1]; 18,19,20, 21: If (vpos = 18) or (hpos = 1) then begin If carrier then inst^.fm_data.AM_VIB_EG_carrier := inst^.fm_data.AM_VIB_EG_carrier XOR AM_Vibrato_EG[vpos-18] else inst^.fm_data.AM_VIB_EG_modulator := inst^.fm_data.AM_VIB_EG_modulator XOR AM_Vibrato_EG[vpos-18]; end else begin If carrier then inst^.fm_data.AM_VIB_EG_carrier := inst^.fm_data.AM_VIB_EG_carrier AND $0f0+ (vpos-19)*6+hpos-2 else inst^.fm_data.AM_VIB_EG_modulator := inst^.fm_data.AM_VIB_EG_modulator AND $0f0+ (vpos-19)*6+hpos-2; end; end; reset_instrument_preview; end; kPgUP, kCHplus, kNPplus: begin If carrier then begin If (vpos = 1) and (inst^.fm_data.ATTCK_DEC_carrier SHR 4 < $0f) then inst^.fm_data.ATTCK_DEC_carrier := inst^.fm_data.ATTCK_DEC_carrier AND $0f+ (inst^.fm_data.ATTCK_DEC_carrier SHR 4 +1) SHL 4; If (vpos = 2) and (hpos = 1) and (inst^.fm_data.ATTCK_DEC_carrier AND $0f < $0f) then Inc(inst^.fm_data.ATTCK_DEC_carrier); If (vpos = 4) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_carrier SHR 4 < $0f) then inst^.fm_data.SUSTN_REL_carrier := inst^.fm_data.SUSTN_REL_carrier AND $0f+ (inst^.fm_data.SUSTN_REL_carrier SHR 4 +1) SHL 4; If (vpos = 5) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_carrier AND $0f < $0f) then Inc(inst^.fm_data.SUSTN_REL_carrier); If (vpos = 7) and (hpos = 1) and (inst^.fm_data.KSL_VOLUM_carrier AND $3f > 0) then Dec(inst^.fm_data.KSL_VOLUM_carrier); end else begin If (vpos = 1) and (inst^.fm_data.ATTCK_DEC_modulator SHR 4 < $0f) then inst^.fm_data.ATTCK_DEC_modulator := inst^.fm_data.ATTCK_DEC_modulator AND $0f+ (inst^.fm_data.ATTCK_DEC_modulator SHR 4 +1) SHL 4; If (vpos = 2) and (hpos = 1) and (inst^.fm_data.ATTCK_DEC_modulator AND $0f < $0f) then Inc(inst^.fm_data.ATTCK_DEC_modulator); If (vpos = 4) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_modulator SHR 4 < $0f) then inst^.fm_data.SUSTN_REL_modulator := inst^.fm_data.SUSTN_REL_modulator AND $0f+ (inst^.fm_data.SUSTN_REL_modulator SHR 4 +1) SHL 4; If (vpos = 5) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_modulator AND $0f < $0f) then Inc(inst^.fm_data.SUSTN_REL_modulator); If (vpos = 7) and (hpos = 1) and (inst^.fm_data.KSL_VOLUM_modulator AND $3f > 0) then Dec(inst^.fm_data.KSL_VOLUM_modulator); end; If (vpos = 12) and (hpos = 3) then _inc_feedback_val; If (vpos = 16) and (hpos = 2) then _inc_finetune_val; reset_instrument_preview; end; kPgDOWN, kCHmins, kNPmins: begin If carrier then begin If (vpos = 1) and (inst^.fm_data.ATTCK_DEC_carrier SHR 4 > 0) then inst^.fm_data.ATTCK_DEC_carrier := inst^.fm_data.ATTCK_DEC_carrier AND $0f+ (inst^.fm_data.ATTCK_DEC_carrier SHR 4 -1) SHL 4; If (vpos = 2) and (hpos = 1) and (inst^.fm_data.ATTCK_DEC_carrier AND $0f > 0) then Dec(inst^.fm_data.ATTCK_DEC_carrier); If (vpos = 4) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_carrier SHR 4 > 0) then inst^.fm_data.SUSTN_REL_carrier := inst^.fm_data.SUSTN_REL_carrier AND $0f+ (inst^.fm_data.SUSTN_REL_carrier SHR 4 -1) SHL 4; If (vpos = 5) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_carrier AND $0f > 0) then Dec(inst^.fm_data.SUSTN_REL_carrier); If (vpos = 7) and (hpos = 1) and (inst^.fm_data.KSL_VOLUM_carrier AND $3f < $3f) then Inc(inst^.fm_data.KSL_VOLUM_carrier); end else begin If (vpos = 1) and (inst^.fm_data.ATTCK_DEC_modulator SHR 4 > 0) then inst^.fm_data.ATTCK_DEC_modulator := inst^.fm_data.ATTCK_DEC_modulator AND $0f+ (inst^.fm_data.ATTCK_DEC_modulator SHR 4 -1) SHL 4; If (vpos = 2) and (hpos = 1) and (inst^.fm_data.ATTCK_DEC_modulator AND $0f > 0) then Dec(inst^.fm_data.ATTCK_DEC_modulator); If (vpos = 4) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_modulator SHR 4 > 0) then inst^.fm_data.SUSTN_REL_modulator := inst^.fm_data.SUSTN_REL_modulator AND $0f+ (inst^.fm_data.SUSTN_REL_modulator SHR 4 -1) SHL 4; If (vpos = 5) and (hpos = 1) and (inst^.fm_data.SUSTN_REL_modulator AND $0f > 0) then Dec(inst^.fm_data.SUSTN_REL_modulator); If (vpos = 7) and (hpos = 1) and (inst^.fm_data.KSL_VOLUM_modulator AND $3f < $3f) then Inc(inst^.fm_data.KSL_VOLUM_modulator); end; If (vpos = 12) and (hpos = 3) then _dec_feedback_val; If (vpos = 16) and (hpos = 2) then _dec_finetune_val; reset_instrument_preview; end; kCtLbr: If shift_pressed then begin If (songdata.macro_speedup > 1) then Dec(songdata.macro_speedup); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If (current_inst > 1) then begin Dec(current_inst); reset_marked_instruments; instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); If NOT (inst^.perc_voice in [2..5]) then carrier := TRUE else carrier := FALSE; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); _page_build; _page_refresh; _sync_radio_buttons; end; kCtRbr: If shift_pressed then begin Inc(songdata.macro_speedup); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); macro_speedup := songdata.macro_speedup; keyboard_reset_buffer; end else If (current_inst < 255) then begin Inc(current_inst); reset_marked_instruments; instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); If NOT (inst^.perc_voice in [2..5]) then carrier := TRUE else carrier := FALSE; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); _page_build; _page_refresh; _sync_radio_buttons; end; kF1: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; HELP('instrument_editor'); GOTO _jmp1; end; kF2, kCtrlS: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; quick_cmd := FALSE; FILE_save('a2i'); GOTO _jmp1; end; kShF2: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; quick_cmd := FALSE; FILE_save('a2f'); GOTO _jmp1; end; kF3, kCtrlL: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); quick_cmd := FALSE; FILE_open('*.a2i$*.a2f$*.a2b$*.a2w$'+ '*.bnk$*.cif$*.fib$*.fin$*.ibk$*.ins$*.sbi$*.sgi$',FALSE);// load bank is not possible reset_instrument_preview; GOTO _jmp1; end; kF7: For temp := 1 to 20 do reset_chan_data(temp); kCtrlO: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; OCTAVE_CONTROL; GOTO _jmp1; end; kCtrlQ: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; MACRO_EDITOR(current_inst,FALSE); GOTO _jmp1; end; kCtrlE: begin Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; MACRO_EDITOR(current_inst,TRUE); GOTO _jmp1; end; kENTER: If NOT (inst^.perc_voice in [2..5]) then If NOT shift_pressed then begin If remember_ins_pos then If carrier then begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?hpos',-1,hpos); add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?vpos',-1,vpos); end else begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?hpos',-1,hpos); add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?vpos',-1,vpos); end; carrier := NOT carrier; If carrier and (get_4op_to_test <> 0) then begin If (current_inst = LO(get_4op_to_test)) then current_inst := HI(get_4op_to_test) else current_inst := LO(get_4op_to_test); instrum_page := current_inst; STATUS_LINE_refresh; inst := Addr(songdata.instr_data[instrum_page]); _page_build; _page_refresh; end; _sync_radio_buttons; end else With songdata.instr_data[instrum_page].fm_data do If carrier then begin ATTCK_DEC_carrier := ATTCK_DEC_modulator; AM_VIB_EG_carrier := AM_VIB_EG_modulator; KSL_VOLUM_carrier := KSL_VOLUM_modulator; SUSTN_REL_carrier := SUSTN_REL_modulator; WAVEFORM_carrier := WAVEFORM_modulator; end else begin 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; end; else nope := TRUE; end; If shift_pressed and (UpCase(CHR(LO(fkey))) in ['M','O','B','S','T','C','H']) then begin If (UpCase(CHR(LO(fkey))) = 'O') then begin songdata.instr_data[instrum_page].perc_voice := 0; If (instrum_page <> 255) then songdata.instr_data[SUCC(instrum_page)].perc_voice := 0 else songdata.instr_data[PRED(instrum_page)].perc_voice := 0; If (instrum_page <> 255) then If check_4op_flag(instrum_page) then reset_4op_flag(instrum_page) else set_4op_flag(instrum_page) else If check_4op_flag(PRED(instrum_page)) then reset_4op_flag(PRED(instrum_page)) else set_4op_flag(PRED(instrum_page)); update_4op_flag_marks; end else If NOT check_4op_flag(instrum_page) then Case UpCase(CHR(LO(fkey))) of 'M': inst^.perc_voice := 0; 'B': inst^.perc_voice := 1; 'S': inst^.perc_voice := 2; 'T': inst^.perc_voice := 3; 'C': inst^.perc_voice := 4; 'H': inst^.perc_voice := 5; end; update_4op_flag_marks; end; _end: {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (nope and (fkey = kESC)) or _force_program_quit; FillChar(_operator_enabled,SizeOf(_operator_enabled),TRUE); If remember_ins_pos then begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier',-1,_carrier_flag[carrier]); If carrier then begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?hpos',-1,hpos); add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?carrier?vpos',-1,vpos); end else begin add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?hpos',-1,hpos); add_bank_position('?instrument_editor?'+byte2hex(instrum_page)+'?modulator?vpos',-1,vpos); end; end; Dec(xstart); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+71+2; move_to_screen_area[4] := ystart+24+INSEDIT_yshift+1; move2screen; end; procedure copy_object; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:copy_object'; {$ENDIF} Case clipboard.object_type of objInstrument: begin clipboard.instrument.names[1] := Copy(songdata.instr_names[instrum_page],10,32); clipboard.instrument.data[1] := songdata.instr_data[instrum_page]; end; objInstrumentWithMacros: begin clipboard.instrument.names[1] := Copy(songdata.instr_names[instrum_page],10,32); clipboard.instrument.data[1] := songdata.instr_data[instrum_page]; clipboard.instrument.macros[1] := songdata.instr_macros[instrum_page]; clipboard.instrument.dis_fmreg_col[1] := songdata.dis_fmreg_col[instrum_page]; end; objInstrumentBank: For temp := 1 to 255 do begin clipboard.instrument.names[temp] := Copy(songdata.instr_names[temp],10,32); clipboard.instrument.data[temp] := songdata.instr_data[temp]; clipboard.instrument.macros[temp] := songdata.instr_macros[temp]; clipboard.instrument.arpvib[temp] := songdata.macro_table[temp]; clipboard.instrument.dis_fmreg_col[temp] := songdata.dis_fmreg_col[temp]; end; end; end; procedure paste_object(mode: Byte); var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:paste_object'; {$ENDIF} Case clipboard.object_type of objInstrument: Case mode of 0: begin songdata.instr_names[instrum_page] := Copy(songdata.instr_names[instrum_page],1,9)+ clipboard.instrument.names[1]; songdata.instr_data[instrum_page] := clipboard.instrument.data[1]; reset_instrument_preview; end; 1: begin songdata.instr_data[instrum_page] := clipboard.instrument.data[1]; reset_instrument_preview; end; 2: songdata.instr_names[instrum_page] := Copy(songdata.instr_names[instrum_page],1,9)+ clipboard.instrument.names[1]; end; objInstrumentWithMacros: Case mode of 0: begin songdata.instr_names[instrum_page] := Copy(songdata.instr_names[instrum_page],1,9)+ clipboard.instrument.names[1]; songdata.instr_data[instrum_page] := clipboard.instrument.data[1]; songdata.instr_macros[instrum_page] := clipboard.instrument.macros[1]; songdata.dis_fmreg_col[instrum_page] := clipboard.instrument.dis_fmreg_col[1]; reset_instrument_preview; end; 1: begin songdata.instr_data[instrum_page] := clipboard.instrument.data[1]; songdata.instr_macros[instrum_page] := clipboard.instrument.macros[1]; songdata.dis_fmreg_col[instrum_page] := clipboard.instrument.dis_fmreg_col[1]; reset_instrument_preview; end; 2: songdata.instr_names[instrum_page] := Copy(songdata.instr_names[instrum_page],1,9)+ clipboard.instrument.names[1]; end; objInstrumentBank: For temp := 1 to 255 do Case mode of 0: begin songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ clipboard.instrument.names[temp]; songdata.instr_data[temp] := clipboard.instrument.data[temp]; songdata.instr_macros[temp] := clipboard.instrument.macros[temp]; songdata.macro_table[temp] := clipboard.instrument.arpvib[temp]; songdata.dis_fmreg_col[temp] := clipboard.instrument.dis_fmreg_col[temp]; update_instr_data(temp); end; 1: begin songdata.instr_data[temp] := clipboard.instrument.data[temp]; songdata.instr_macros[temp] := clipboard.instrument.macros[temp]; songdata.macro_table[temp] := clipboard.instrument.arpvib[temp]; songdata.dis_fmreg_col[temp] := clipboard.instrument.dis_fmreg_col[temp]; update_instr_data(temp); end; 2: songdata.instr_names[temp] := Copy(songdata.instr_names[temp],1,9)+ clipboard.instrument.names[temp]; end; end; end; procedure instr_control_ai; var temp,temp2: Byte; iflag: array[1..18] of Byte; istr: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:instr_control_ai'; {$ENDIF} istr := ''; For temp := 1 to 18 do iflag[temp] := ai_table[mn_environment.curr_page+temp-1]; For temp2 := 1 to 18 do begin For temp := 1 to songdata.nm_tracks do If (event_table[temp].instr_def = mn_environment.curr_page+temp2-1) then If channel_flag[temp] then If event_new[temp] and (iflag[temp] < 2) then iflag[temp2] := 2 else If (iflag[temp2] < 1) then iflag[temp2] := 1; Case iflag[temp2] of 0: istr := istr+#28; 1: istr := istr+'~'#28'~'; 2: istr := istr+'`'#11'`'; end; end; For temp := 1 to 18 do If (iflag[temp] <> 0) then ai_table[mn_environment.curr_page+temp-1] := 1; ShowVC3Str(mn_environment.v_dest, INSCTRL_xshift+37, INSCTRL_yshift+07, istr, dialog_background+instrument_ai_off, dialog_background+instrument_ai_on, dialog_background+instrument_ai_trig); end; procedure instr_control_proc; var temp,temp2,ins1,ins2: Byte; temps: String; ins_4op,ins_4op_2: Word; temp_inst: Record name: String; data: tADTRACK2_INS; macros: tREGISTER_TABLE; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:instr_control_proc'; {$ENDIF} Case mn_environment.keystroke of kCtLEFT: If NOT debugging and (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If NOT debugging and (play_status = isPlaying) then fast_forward := TRUE; kCHmins, kNPmins, kCtHOME: If (play_status <> isStopped) then If NOT mn_environment.is_editing then If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp > 0) and NOT (songdata.pattern_order[temp-1] < $80) do begin Dec(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp > 0) then begin Dec(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (mn_environment.keystroke = kCtHOME) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCHplus, kNPplus, kCtEND: If (play_status <> isStopped) then If NOT mn_environment.is_editing then If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp < $7f) and (songdata.pattern_order[SUCC(temp)] > $80) do begin Inc(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp < $7f) then begin Inc(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (mn_environment.keystroke = kCtEND) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kF5: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; isStopped: begin If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; start_playing; end; end; kF6: Case play_status of isPlaying: begin If NOT debugging then begin replay_forbidden := TRUE; play_status := isPaused; end; debugging := FALSE; end; isPaused: begin debugging := FALSE; replay_forbidden := FALSE; play_status := isPlaying; end; end; kF7: If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else For temp := 1 to 20 do reset_chan_data(temp); kF9: If play_single_patt and (play_status = isPaused) then begin replay_forbidden := FALSE; play_status := isPlaying; end else Case play_status of isPlaying: begin debugging := FALSE; repeat_pattern := TRUE; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; isPaused: begin debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; isStopped: begin start_playing; debugging := FALSE; repeat_pattern := TRUE; replay_forbidden := FALSE; play_status := isPlaying; If NOT nosync_by_default or nosync_by_default then no_sync_playing := TRUE; end; end; kCtrlC: begin If NOT shift_pressed then clipboard.object_type := objInstrument else clipboard.object_type := objInstrumentWithMacros; copy_object; end; kAltP: begin paste_object(0); mn_environment.do_refresh := TRUE; mn_environment.refresh; end; kCtrlV: begin If NOT shift_pressed then paste_object(0) else paste_object(1); mn_environment.do_refresh := TRUE; mn_environment.refresh; end; kAltV: begin If NOT shift_pressed then paste_object(2); mn_environment.do_refresh := TRUE; mn_environment.refresh; end; kCtrlW: If (marked_instruments = 2) then begin ins1 := 1; While (songdata.instr_names[ins1][1] <> _ins_mark_chr) do Inc(ins1); ins2 := SUCC(ins1); While (songdata.instr_names[ins2][1] <> _ins_mark_chr) do Inc(ins2); ins_4op := check_4op_instrument(ins1); ins_4op_2 := check_4op_instrument(ins2); If NOT ((ins_4op <> 0) and (ins_4op_2 <> 0)) then begin temp_inst.name := songdata.instr_names[ins1]; temp_inst.data := songdata.instr_data[ins1]; temp_inst.macros := songdata.instr_macros[ins1]; songdata.instr_macros[ins1] := songdata.instr_macros[ins2]; songdata.instr_macros[ins2] := temp_inst.macros; songdata.instr_data[ins1] := songdata.instr_data[ins2]; update_instr_data(ins1); songdata.instr_data[ins2] := temp_inst.data; update_instr_data(ins2); If NOT shift_pressed then begin songdata.instr_names[ins1] := Copy(songdata.instr_names[ins1],1,9)+ Copy(songdata.instr_names[ins2],10,32); songdata.instr_names[ins2] := Copy(songdata.instr_names[ins2],1,9)+ Copy(temp_inst.name,10,32); end; end else begin // 4OP 1/2 temp_inst.name := songdata.instr_names[HI(ins_4op)]; temp_inst.data := songdata.instr_data[HI(ins_4op)]; temp_inst.macros := songdata.instr_macros[HI(ins_4op)]; songdata.instr_macros[HI(ins_4op)] := songdata.instr_macros[HI(ins_4op_2)]; songdata.instr_macros[HI(ins_4op_2)] := temp_inst.macros; songdata.instr_data[HI(ins_4op)] := songdata.instr_data[HI(ins_4op_2)]; update_instr_data(HI(ins_4op)); songdata.instr_data[HI(ins_4op_2)] := temp_inst.data; update_instr_data(HI(ins_4op_2)); If NOT shift_pressed then begin songdata.instr_names[HI(ins_4op)] := Copy(songdata.instr_names[HI(ins_4op)],1,9)+ Copy(songdata.instr_names[HI(ins_4op_2)],10,32); songdata.instr_names[HI(ins_4op_2)] := Copy(songdata.instr_names[HI(ins_4op_2)],1,9)+ Copy(temp_inst.name,10,32); end; // 4OP 2/2 temp_inst.name := songdata.instr_names[LO(ins_4op)]; temp_inst.data := songdata.instr_data[LO(ins_4op)]; temp_inst.macros := songdata.instr_macros[LO(ins_4op)]; songdata.instr_macros[LO(ins_4op)] := songdata.instr_macros[LO(ins_4op_2)]; songdata.instr_macros[LO(ins_4op_2)] := temp_inst.macros; songdata.instr_data[LO(ins_4op)] := songdata.instr_data[LO(ins_4op_2)]; update_instr_data(LO(ins_4op)); songdata.instr_data[LO(ins_4op_2)] := temp_inst.data; update_instr_data(LO(ins_4op_2)); If NOT shift_pressed then begin songdata.instr_names[LO(ins_4op)] := Copy(songdata.instr_names[LO(ins_4op)],1,9)+ Copy(songdata.instr_names[LO(ins_4op_2)],10,32); songdata.instr_names[LO(ins_4op_2)] := Copy(songdata.instr_names[LO(ins_4op_2)],1,9)+ Copy(temp_inst.name,10,32); end; end; mn_environment.do_refresh := TRUE; mn_environment.refresh; end; kTAB: reset_marked_instruments; kSPACE: begin If (songdata.instr_names[instrum_page][1] <> _ins_mark_chr) then If (marked_instruments < 2) then songdata.instr_names[instrum_page][1] := _ins_mark_chr else begin reset_marked_instruments; songdata.instr_names[instrum_page][1] := _ins_mark_chr; end else reset_marked_instruments; mn_environment.do_refresh := TRUE; mn_environment.refresh; end; end; instrum_page := mn_environment.curr_pos; current_inst := instrum_page; If shift_pressed and (UpCase(CHR(LO(mn_environment.keystroke))) in ['M','O','B','S','T','C','H']) then If (UpCase(CHR(LO(mn_environment.keystroke))) = 'O') then begin songdata.instr_data[current_inst].perc_voice := 0; If (current_inst <> 255) then songdata.instr_data[SUCC(current_inst)].perc_voice := 0 else songdata.instr_data[PRED(current_inst)].perc_voice := 0; If (current_inst <> 255) then If check_4op_flag(current_inst) then reset_4op_flag(current_inst) else set_4op_flag(current_inst) else If check_4op_flag(PRED(current_inst)) then reset_4op_flag(PRED(current_inst)) else set_4op_flag(PRED(current_inst)); update_4op_flag_marks; mn_environment.do_refresh := TRUE; mn_environment.refresh; end else If NOT check_4op_flag(current_inst) then Case UpCase(CHR(LO(mn_environment.keystroke))) of 'M': songdata.instr_data[current_inst].perc_voice := 0; 'B': songdata.instr_data[current_inst].perc_voice := 1; 'S': songdata.instr_data[current_inst].perc_voice := 2; 'T': songdata.instr_data[current_inst].perc_voice := 3; 'C': songdata.instr_data[current_inst].perc_voice := 4; 'H': songdata.instr_data[current_inst].perc_voice := 5; end; INSTRUMENT_CONTROL_page_refresh(instrum_page); If (get_4op_to_test <> 0) and (songdata.flag_4op <> 0) then begin temps := connection_str[pBYTE(@Addr(songdata.instr_data[HI(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]+'/'+ connection_str[pBYTE(@Addr(songdata.instr_data[LO(get_4op_to_test)])^)[_instr_data_ofs[11]] AND 1]; ShowCStr(mn_environment.v_dest,INSCTRL_xshift+39,INSCTRL_yshift+26, ' ~[~'#244+byte2hex(HI(get_4op_to_test))+ ','#245+byte2hex(LO(get_4op_to_test))+' '+temps+'~]~ ', dialog_background+dialog_context, dialog_background+dialog_border); end else If (check_4op_to_test <> 0) then ShowCStr(mn_environment.v_dest,INSCTRL_xshift+39,INSCTRL_yshift+26, ExpStrR(' ~[~'#2#3' MODE~]~ ',17,#205), dialog_background+dialog_context, dialog_background+dialog_border) else ShowStr(mn_environment.v_dest,INSCTRL_xshift+39,INSCTRL_yshift+26, ExpStrL('',17,#205), dialog_background+dialog_border); If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then If (get_4op_to_test <> 0) then INSTRUMENT_test(LO(get_4op_to_test),HI(get_4op_to_test),count_channel(pattern_hpos),mn_environment.keystroke,TRUE) else INSTRUMENT_test(instrum_page,0,count_channel(pattern_hpos),mn_environment.keystroke,TRUE); end; function INSTRUMENT_CONTROL: Byte; const new_keys: array[1..20] of Word = (kESC,kENTER,kTAB,kShTAB,kCtrlO,kCtrlM,kAltC,kCtrlA,kCtrlQ,kCtrlE, kF1,kF2,kF4,kAltF2,kCtrlF2,kCtrlS,kShF2,kF3,kCtrlL,kShF3); var old_keys: array[1..20] of Word; temp: Byte; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL'; {$ENDIF} update_4op_flag_marks; songdata_crc := Update32(songdata,SizeOf(songdata),0); _jmp1: If _force_program_quit then EXIT; keyboard_reset_buffer; ScreenMemCopy(screen_ptr,ptr_screen_backup); mn_environment.v_dest := ptr_temp_screen; ScreenMemCopy(screen_ptr,mn_environment.v_dest); mn_setting.center_box := FALSE; mn_setting.cycle_moves := FALSE; mn_environment.edit_pos := 9; mn_environment.ext_proc := instr_control_proc; mn_environment.ext_proc_rt := instr_control_ai; mn_environment.context := ' TAB '#196#16' EDiTOR '; Move(mn_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,mn_setting.terminate_keys,SizeOf(new_keys)); Frame(ptr_temp_screen,INSCTRL_xshift+07,INSCTRL_yshift+05, INSCTRL_xshift+83,INSCTRL_yshift+26, dialog_background+dialog_border, ' iNSTRUMENT CONTROL (iNS_ ) ', dialog_background+dialog_title, frame_double); fr_setting.update_area := FALSE; fr_setting.shadow_enabled := FALSE; Frame(ptr_temp_screen,INSCTRL_xshift+09,INSCTRL_yshift+06, INSCTRL_xshift+34,INSCTRL_yshift+25, dialog_background+dialog_border, '', dialog_background+dialog_title, frame_single); Frame(ptr_temp_screen,INSCTRL_xshift+36,INSCTRL_yshift+06, INSCTRL_xshift+81,INSCTRL_yshift+25, dialog_background+dialog_border, '', dialog_background+dialog_title, frame_single); ShowStr(ptr_temp_screen,INSCTRL_xshift+66,INSCTRL_yshift+25, ' TAB '#196#16' EDITOR ', dialog_background+dialog_context); ShowStr(ptr_temp_screen,INSCTRL_xshift+58,INSCTRL_yshift+26, ' [SHiFT] TAB '#196#16' MACROS ', dialog_background+dialog_context); ShowVStr(mn_environment.v_dest,INSCTRL_xshift+37,INSCTRL_yshift+07, ExpStrL('',18,#28), dialog_background+instrument_ai_off); ShowVStr(mn_environment.v_dest,INSCTRL_xshift+38,INSCTRL_yshift+06, #194+ExpStrL('',18,#179)+#193, dialog_background+dialog_border); fr_setting.shadow_enabled := TRUE; color_table[1] := dialog_background+dialog_context_dis; color_table[2] := dialog_background+dialog_mod_text; color_table[3] := dialog_background+dialog_car_text; If (ins_parameter(instrum_page,10) AND 1 <> 1) then For temp := 1 to 18 do ShowCStr(ptr_temp_screen,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm1[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm1[temp].colr]) else For temp := 1 to 18 do ShowCStr(ptr_temp_screen,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm2[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm2[temp].colr]); mn_setting.edit_contents := TRUE; mn_setting.shadow_enabled := FALSE; mn_setting.frame_enabled := FALSE; mn_environment.unpolite := FALSE; mn_environment.preview := TRUE; mn_environment.hlight_chrs := 1; If NOT _force_program_quit then Menu(songdata.instr_names,INSCTRL_xshift+38,INSCTRL_yshift+06,instrum_page,42,18,255,''); INSTRUMENT_CONTROL_page_refresh(instrum_page); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := INSCTRL_xshift+7; move_to_screen_area[2] := INSCTRL_yshift+5; move_to_screen_area[3] := INSCTRL_xshift+83+2; move_to_screen_area[4] := INSCTRL_yshift+26+1; move2screen_alt; mn_environment.v_dest := screen_ptr; If NOT _force_program_quit then temp := Menu(songdata.instr_names,INSCTRL_xshift+38,INSCTRL_yshift+06,instrum_page,42,18,255,''); reset_marked_instruments; mn_environment.unpolite := FALSE; mn_environment.preview := FALSE; mn_setting.frame_enabled := TRUE; mn_setting.shadow_enabled := TRUE; fr_setting.update_area := TRUE; mn_setting.center_box := TRUE; mn_environment.context := ''; Move(old_keys,mn_setting.terminate_keys,SizeOf(old_keys)); mn_setting.edit_contents := FALSE; mn_environment.ext_proc := NIL; mn_environment.ext_proc_rt := NIL; mn_environment.hlight_chrs := 0; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := INSCTRL_xshift+7; move_to_screen_area[2] := INSCTRL_yshift+5; move_to_screen_area[3] := INSCTRL_xshift+83+2; move_to_screen_area[4] := INSCTRL_yshift+26+1; move2screen; Case mn_environment.keystroke of kAltC: begin mn_setting.cycle_moves := TRUE; temp := Menu(copy_menu_str1,01,01,copypos1,30,15,15,' COPY OBJECT '); If (mn_environment.keystroke <> kESC) then begin copypos1 := temp; clipboard.object_type := tCOPY_OBJECT(temp); copy_object; end; GOTO _jmp1; end; kTAB: begin If (get_4op_to_test <> 0) then begin If (songdata.instr_data[HI(get_4op_to_test)].perc_voice <> 0) then songdata.instr_data[HI(get_4op_to_test)].perc_voice := 0; If (songdata.instr_data[LO(get_4op_to_test)].perc_voice <> 0) then songdata.instr_data[LO(get_4op_to_test)].perc_voice := 0; end; INSTRUMENT_CONTROL_edit; GOTO _jmp1; end; kCtrlQ, kShTAB: begin MACRO_EDITOR(instrum_page,FALSE); GOTO _jmp1; end; kCtrlO: begin OCTAVE_CONTROL; mn_environment.keystroke := BYTE_NULL; GOTO _jmp1; end; kCtrlE: begin MACRO_EDITOR(current_inst,TRUE); GOTO _jmp1; end; kCtrlM: begin MACRO_BROWSER(TRUE,TRUE); GOTO _jmp1; end; kF1: begin HELP('instrument_control'); GOTO _jmp1; end; kF2, kCtrlS: begin quick_cmd := FALSE; FILE_save('a2i'); GOTO _jmp1; end; kAltF2: begin quick_cmd := FALSE; FILE_save('a2b'); GOTO _jmp1; end; kShF2: begin quick_cmd := FALSE; FILE_save('a2f'); GOTO _jmp1; end; kCtrlF2: begin quick_cmd := FALSE; FILE_save('a2w'); GOTO _jmp1; end; kF3, kShF3, kCtrlL: begin If (mn_environment.keystroke = kShF3) then quick_cmd := TRUE; FILE_open('*.a2i$*.a2f$*.a2b$*.a2w$'+ '*.bnk$*.cif$*.fib$*.fin$*.ibk$*.ins$*.sbi$*.sgi$',TRUE);// load bank is possible reset_instrument_preview; update_4op_flag_marks; quick_cmd := FALSE; GOTO _jmp1; end; kF4, kCtrlA: begin NUKE; GOTO _jmp1; end; end; If (Update32(songdata,SizeOf(songdata),0) <> songdata_crc) then module_archived := FALSE; If (mn_environment.keystroke = kENTER) then INSTRUMENT_CONTROL := instrum_page else INSTRUMENT_CONTROL := 0; end; procedure instr_control_proc_alt; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:instr_control_proc_alt'; {$ENDIF} INSTRUMENT_CONTROL_page_refresh_alt(mn_environment.curr_pos); If NOT shift_pressed and NOT alt_pressed and NOT ctrl_pressed then If (get_4op_to_test <> 0) then INSTRUMENT_test(LO(get_4op_to_test),HI(get_4op_to_test),count_channel(pattern_hpos),mn_environment.keystroke,FALSE) else INSTRUMENT_test(mn_environment.curr_pos,0,count_channel(pattern_hpos),mn_environment.keystroke,FALSE); end; function INSTRUMENT_CONTROL_alt(instr: Byte; title: String): Byte; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'INSTEDIT.INC:INSTRUMENT_CONTROL_alt'; {$ENDIF} keyboard_reset_buffer; ScreenMemCopy(screen_ptr,ptr_screen_backup); mn_environment.v_dest := ptr_temp_screen; ScreenMemCopy(screen_ptr,mn_environment.v_dest); mn_setting.center_box := FALSE; mn_setting.cycle_moves := FALSE; mn_environment.ext_proc := instr_control_proc_alt; mn_environment.ext_proc_rt := instr_control_ai; Frame(ptr_temp_screen,INSCTRL_xshift+07,INSCTRL_yshift+05, INSCTRL_xshift+83,INSCTRL_yshift+26, dialog_background+dialog_border, ' '+title+' ', dialog_background+dialog_title, frame_double); fr_setting.update_area := FALSE; fr_setting.shadow_enabled := FALSE; Frame(ptr_temp_screen,INSCTRL_xshift+09,INSCTRL_yshift+06, INSCTRL_xshift+34,INSCTRL_yshift+25, instrument_bckg+instrument_border, '', instrument_bckg+instrument_title, frame_single); Frame(ptr_temp_screen,INSCTRL_xshift+36,INSCTRL_yshift+06, INSCTRL_xshift+81,INSCTRL_yshift+25, instrument_bckg+instrument_border, '', instrument_bckg+instrument_title, frame_single); ShowVStr(mn_environment.v_dest,INSCTRL_xshift+37,INSCTRL_yshift+07, ExpStrL('',18,#28), dialog_background+instrument_ai_off); ShowVStr(mn_environment.v_dest,INSCTRL_xshift+38,INSCTRL_yshift+06, #194+ExpStrL('',18,#179)+#193, dialog_background+dialog_border); fr_setting.shadow_enabled := TRUE; color_table[1] := instrument_bckg+instrument_text; color_table[2] := instrument_bckg+instrument_hi_mod; color_table[3] := instrument_bckg+instrument_hi_car; If (ins_parameter(instr,10) AND 1 <> 1) then For temp := 1 to 18 do ShowCStr(ptr_temp_screen,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm1[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm1[temp].colr]) else For temp := 1 to 18 do ShowCStr(ptr_temp_screen,INSCTRL_xshift+10,INSCTRL_yshift+06+temp,inst_itm2[temp].str, dialog_background+dialog_contxt_dis2, color_table[inst_itm2[temp].colr]); mn_setting.shadow_enabled := FALSE; mn_setting.frame_enabled := FALSE; mn_environment.unpolite := FALSE; mn_environment.preview := TRUE; If NOT _force_program_quit then Menu(songdata.instr_names,INSCTRL_xshift+38,INSCTRL_yshift+06,instr,42,18,255,''); INSTRUMENT_CONTROL_page_refresh_alt(instr); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := INSCTRL_xshift+7; move_to_screen_area[2] := INSCTRL_yshift+5; move_to_screen_area[3] := INSCTRL_xshift+83+2; move_to_screen_area[4] := INSCTRL_yshift+26+1; move2screen_alt; mn_environment.v_dest := screen_ptr; If NOT _force_program_quit then temp := Menu(songdata.instr_names,INSCTRL_xshift+38,INSCTRL_yshift+06,instr,42,18,255,''); reset_marked_instruments; mn_environment.unpolite := FALSE; mn_environment.preview := FALSE; mn_setting.frame_enabled := TRUE; mn_setting.shadow_enabled := TRUE; fr_setting.update_area := TRUE; mn_setting.center_box := TRUE; mn_environment.context := ''; mn_environment.ext_proc := NIL; mn_environment.ext_proc_rt := NIL; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := INSCTRL_xshift+7; move_to_screen_area[2] := INSCTRL_yshift+5; move_to_screen_area[3] := INSCTRL_xshift+83+2; move_to_screen_area[4] := INSCTRL_yshift+26+1; move2screen; If (mn_environment.keystroke = kENTER) then INSTRUMENT_CONTROL_alt := temp else INSTRUMENT_CONTROL_alt := 0; end; adlibtracker2-2.4.24/adt2keyb.pas0000644000000000000000000006673513411003760015240 0ustar rootroot// 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 AdT2keyb; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface {$IFDEF GO32V2} {$MODE FPC} const keyboard_sleep: Boolean = FALSE; CTRL_ALT_DEL_pressed: Boolean = FALSE; _ctrl_pressed: Boolean = FALSE; _2x_ctrl_pressed: Boolean = FALSE; {$ENDIF} procedure keyboard_init; procedure keyboard_done; procedure keyboard_reset_buffer; procedure wait_until_F11_F12_released; procedure keyboard_poll_input; function keypressed: Boolean; function getkey: Word; function scankey(scancode: Byte): Boolean; function CapsLock: Boolean; function NumLock: Boolean; function shift_pressed: Boolean; function left_shift_pressed: Boolean; function right_shift_pressed: Boolean; function alt_pressed: Boolean; function ctrl_pressed: Boolean; function ctrl_tab_pressed: Boolean; function LookUpKey(key: Word; var table; size: Byte): Boolean; procedure screen_saver; {$IFDEF GO32V2} procedure keyboard_reset_buffer_alt; procedure keyboard_toggle_sleep; function ScrollLock: Boolean; function both_shifts_pressed: Boolean; {$ENDIF} implementation uses {$IFNDEF UNIX} CRT, {$ENDIF} DOS, {$IFDEF GO32V2} GO32, {$ELSE} SDL_Types,SDL_Timer,SDL_Events,SDL_Keyboard, {$ENDIF} AdT2unit,AdT2sys,AdT2ext2, TxtScrIO,DialogIO,ParserIO; var {$IFDEF GO32V2} keydown: array[0..127] of Boolean; {$ELSE} keydown: array[0..255] of Boolean; {$ENDIF} {$IFDEF GO32V2} var oldint09_handler: tSegInfo; newint09_handler: tSegInfo; user_proc_ptr: Pointer; backupDS_adt2keyb: Word; EXTERNAL NAME '___v2prt0_ds_alias'; procedure newint09_proc; assembler; asm cli push ds push es push fs push gs pushad mov ax,cs:[backupDS_adt2keyb] mov ds,ax mov es,ax mov ax,DosMemSelector mov fs,ax call dword ptr [user_proc_ptr] popad pop gs pop fs pop es pop ds jmp cs:[oldint09_handler] end; procedure newint09_proc_end; begin end; procedure int09_user_proc; forward; procedure int09_user_proc_end; forward; {$ELSE} const _numlock: Boolean = FALSE; _capslock: Boolean = FALSE; var keystate: ^BoolArray; varnum: Longint; {$ENDIF} procedure keyboard_init; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:keyboard_init'; FillChar(keydown,SizeOf(keydown),FALSE); user_proc_ptr := @int09_user_proc; lock_data(user_proc_ptr,SizeOf(user_proc_ptr)); lock_data(DosMemSelector,SizeOf(DosMemSelector)); lock_code(@int09_user_proc,DWORD(@int09_user_proc_end)-DWORD(@int09_user_proc)); lock_code(@newint09_proc,DWORD(@newint09_proc_end)-DWORD(@newint09_proc)); newint09_handler.offset := @newint09_proc; newint09_handler.segment := get_cs; get_pm_interrupt($09,oldint09_handler); set_pm_interrupt($09,newint09_handler); {$ELSE} SDL_EnableKeyRepeat(sdl_typematic_delay,sdl_typematic_rate); keystate := SDL_GetKeyState(varnum); {$ENDIF} end; procedure keyboard_done; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:keyboard_done'; set_pm_interrupt($09,oldint09_handler); unlock_data(DosMemSelector,SizeOf(DosMemSelector)); unlock_data(user_proc_ptr,SizeOf(user_proc_ptr)); unlock_code(@int09_user_proc,DWORD(@int09_user_proc_end)-DWORD(@int09_user_proc)); lock_code(@newint09_proc,DWORD(@newint09_proc_end)-DWORD(@newint09_proc)); keyboard_reset_buffer; {$ENDIF} end; {$IFDEF GO32V2} function keypressed: Boolean; begin realtime_gfx_poll_proc; draw_screen; // filter out CTRL+TAB combo as it is handled within timer routine If ctrl_tab_pressed then begin keyboard_reset_buffer; keypressed := FALSE; end else keypressed := CRT.KeyPressed; end; function getkey: Word; var result: Word; key_c,scan_c: Byte; begin no_status_refresh := FALSE; While NOT keypressed do begin realtime_gfx_poll_proc; draw_screen; If (seconds_counter >= ssaver_time) then screen_saver; end; key_c := BYTE(CRT.ReadKey); If (key_c = 0) then result := BYTE(CRT.ReadKey) SHL 8 else begin scan_c := inportb($60); If (scan_c > $80) then scan_c := scan_c-$80; result := key_c+(scan_c SHL 8); end; getkey := result; end; function scankey(scancode: Byte): Boolean; begin scankey := keydown[scancode]; end; {$ASMMODE INTEL} procedure int09_user_proc; assembler; asm push eax push ebx push es push ds call process_global_keys pop ds pop es mov dword ptr [seconds_counter],0 in al,60h xor ebx,ebx mov bx,ax and bx,007fh and al,80h jz @@4 @@1: mov byte ptr keydown[ebx],0 cmp ebx,1dh // [Ctrl] jnz @@3 cmp byte ptr [_ctrl_pressed],1 jnz @@2 mov byte ptr [_2x_ctrl_pressed],1 @@2: mov byte ptr [_ctrl_pressed],1 @@3: jmp @@5 @@4: mov byte ptr keydown[ebx],1 cmp ebx,1dh // [Ctrl] jz @@5 mov byte ptr [_ctrl_pressed],0 mov byte ptr [_2x_ctrl_pressed],0 @@5: cmp keyboard_sleep,1 jz @@10 cmp byte ptr keydown[1dh],1 // [Ctrl] jnz @@6 cmp byte ptr keydown[38h],1 // [Alt] jnz @@6 cmp byte ptr keydown[4ah],1 // *[-] jz @@10 cmp byte ptr keydown[4eh],1 // *[+] jz @@10 @@6: cmp byte ptr keydown[1dh],1 // [Ctrl] jnz @@7 cmp byte ptr keydown[38h],1 // [Alt] jnz @@7 cmp byte ptr keydown[53h],1 // [Del] jz @@9 @@7: cmp byte ptr keydown[1dh],1 // [Ctrl] jnz @@8 cmp byte ptr keydown[02h],1 // *[1] jz @@10 cmp byte ptr keydown[03h],1 // *[2] jz @@10 cmp byte ptr keydown[04h],1 // *[3] jz @@10 cmp byte ptr keydown[05h],1 // *[4] jz @@10 cmp byte ptr keydown[06h],1 // *[5] jz @@10 cmp byte ptr keydown[07h],1 // *[6] jz @@10 cmp byte ptr keydown[08h],1 // *[7] jz @@10 cmp byte ptr keydown[09h],1 // *[8] jz @@10 @@8: jmp @@11 @@9: mov CTRL_ALT_DEL_pressed,1 @@10: in al,61h mov ah,al or al,80h out 61h,al xchg ah,al out 61h,al mov al,20h out 20h,al pop ebx pop eax jmp @@12 @@11: pop ebx pop eax @@12: end; procedure int09_user_proc_end; begin end; procedure keyboard_toggle_sleep; begin keyboard_sleep := NOT keyboard_sleep; end; procedure keyboard_reset_buffer; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:keyboard_reset_buffer'; MEMW[0:$041c] := MEMW[0:$041a]; end; procedure keyboard_reset_buffer_alt; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:keyboard_reset_buffer_alt'; If (MEMW[0:$041c]-MEMW[0:$041a] > 5) then MEMW[0:$041c] := MEMW[0:$041a]; end; procedure wait_until_F11_F12_released; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:wait_until_key_released'; Repeat realtime_gfx_poll_proc; draw_screen; keyboard_reset_buffer; If (inportb($60) > $80) then FillChar(keydown,SizeOf(keydown),0); until NOT keydown[$57] and NOT keydown[$58]; end; procedure keyboard_poll_input; begin // relevant for SDL version only end; var temp_buf: array[1..32,1..255] of Record r,g,b: Byte; end; procedure screen_saver; procedure fadeout; var r,g,b: Byte; index: Byte; depth: Byte; function min0(val: Integer): Integer; begin If (val <= 0) then min0 := 0 else min0 := val; end; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:screen_saver:fadeout'; For depth := 1 to 32 do begin For index := 1 to 255 do begin GetRGBitem(index,r,g,b); temp_buf[depth][index].r := r; temp_buf[depth][index].g := g; temp_buf[depth][index].b := b; SetRGBitem(index,min0(r-1),min0(g-1),min0(b-1)); end; WaitRetrace; realtime_gfx_poll_proc; If (depth MOD 4 = 0) then draw_screen; keyboard_reset_buffer; end; end; procedure fadein; var index: Byte; depth: Byte; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:screen_saver:fadein'; For depth := 32 downto 1 do begin For index := 1 to 255 do SetRGBitem(index,temp_buf[depth][index].r, temp_buf[depth][index].g, temp_buf[depth][index].b); If (depth MOD 4 <> 0) then WaitRetrace; realtime_gfx_poll_proc; If (depth MOD 4 = 0) then draw_screen; keyboard_reset_buffer; end; end; begin _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2KEYB.PAS:screen_saver'; If (ssaver_time = 0) then EXIT; fadeout; Repeat realtime_gfx_poll_proc; draw_screen; until (seconds_counter = 0); fadein; end; var keyboard_flag: Byte ABSOLUTE 0:$0417; function CapsLock: Boolean; begin CapsLock := (keyboard_flag OR $40 = keyboard_flag); end; function NumLock: Boolean; begin NumLock := (keyboard_flag OR $20 = keyboard_flag); end; function ScrollLock: Boolean; begin ScrollLock := (keyboard_flag OR $10 = keyboard_flag); end; function shift_pressed: Boolean; begin shift_pressed := (keyboard_flag OR 1 = keyboard_flag) or (keyboard_flag OR 2 = keyboard_flag); end; function left_shift_pressed: Boolean; begin left_shift_pressed := (keyboard_flag OR 2 = keyboard_flag); end; function right_shift_pressed: Boolean; begin right_shift_pressed := (keyboard_flag OR 1 = keyboard_flag); end; function both_shifts_pressed: Boolean; begin both_shifts_pressed := (keyboard_flag OR 1 = keyboard_flag) and (keyboard_flag OR 2 = keyboard_flag); end; function alt_pressed: Boolean; begin alt_pressed := scankey(SC_ALT); end; function ctrl_pressed: Boolean; begin ctrl_pressed := scankey(SC_CTRL); end; {$ELSE} const SYMTABSIZE = $65; symtab: array[0..PRED(SYMTABSIZE*10)] of word = ( { Key Scan ASCII Shift Ctrl Alt Num Caps Sh+Caps Sh+Num SDLK_Keycode} { Esc } $01, $1B, $1B, $F000, $F000, $1B, $1B, $1B, $1B, SDLK_ESCAPE, { 1! } $02, $31, $21, $0200, $7800, $31, $31, $21, $21, SDLK_1, { 2@ } $03, $32, $40, $0300, $7900, $32, $32, $40, $40, SDLK_2, { 3# } $04, $33, $23, $0400, $7A00, $33, $33, $23, $23, SDLK_3, { 4$ } $05, $34, $24, $0500, $7B00, $34, $34, $24, $24, SDLK_4, { 5% } $06, $35, $25, $0600, $7C00, $35, $35, $25, $25, SDLK_5, { 6^ } $07, $36, $5E, $0700, $7D00, $36, $36, $5E, $5E, SDLK_6, { 7& } $08, $37, $26, $0800, $7E00, $37, $37, $26, $26, SDLK_7, { 8* } $09, $38, $2A, $0900, $7F00, $38, $38, $2A, $2A, SDLK_8, { 9( } $0A, $39, $28, $0A00, $8000, $39, $39, $28, $28, SDLK_9, { 0) } $0B, $30, $29, $0B00, $8100, $30, $30, $29, $29, SDLK_0, { -_ } $0C, $2D, $5F, $1F, $8200, $2D, $2D, $5F, $5F, SDLK_MINUS, { =+ } $0D, $3D, $2B, $F000, $8300, $3D, $3D, $2B, $2B, SDLK_EQUALS, {Bksp} $0E, $08, $08, $7F, $F000, $08, $08, $08, $08, SDLK_BACKSPACE, { Tab} $0F, $09, $0F00, $F000, $F000, $09, $09, $0F00, $0F00, SDLK_TAB, { Q } $10, $71, $51, $11, $1000, $71, $51, $71, $51, SDLK_q, { W } $11, $77, $57, $17, $1100, $77, $57, $77, $57, SDLK_w, { E } $12, $65, $45, $05, $1200, $65, $45, $65, $45, SDLK_e, { R } $13, $72, $52, $12, $1300, $72, $52, $72, $52, SDLK_r, { T } $14, $74, $54, $14, $1400, $74, $54, $74, $54, SDLK_t, { Y } $15, $79, $59, $19, $1500, $79, $59, $79, $59, SDLK_y, { U } $16, $75, $55, $15, $1600, $75, $55, $75, $55, SDLK_u, { I } $17, $69, $49, $09, $1700, $69, $49, $69, $49, SDLK_i, { O } $18, $6F, $4F, $0F, $1800, $6F, $4F, $6F, $4F, SDLK_o, { P } $19, $70, $50, $10, $1900, $70, $50, $70, $50, SDLK_p, { [ } $1A, $5B, $7B, $1B, $F000, $5B, $5B, $7B, $7B, SDLK_LEFTBRACKET, { ] } $1B, $5D, $7D, $1D, $F000, $5D, $5D, $7D, $7D, SDLK_RIGHTBRACKET, {enter} $1C, $0D, $0D, $0A, $F000, $0D, $0D, $0D, $0D, SDLK_RETURN, { A } $1E, $61, $41, $01, $1E00, $61, $41, $61, $41, SDLK_a, { S } $1F, $73, $53, $13, $1F00, $73, $53, $73, $53, SDLK_s, { D } $20, $64, $44, $04, $2000, $64, $44, $64, $44, SDLK_d, { F } $21, $66, $46, $06, $2100, $66, $46, $66, $46, SDLK_f, { G } $22, $67, $47, $07, $2200, $67, $47, $67, $47, SDLK_g, { H } $23, $68, $48, $08, $2300, $68, $48, $68, $48, SDLK_h, { J } $24, $6A, $4A, $0A, $2400, $6A, $4A, $6A, $4A, SDLK_j, { K } $25, $6B, $4B, $0B, $2500, $6B, $4B, $6B, $4B, SDLK_k, { L } $26, $6C, $4C, $0C, $2600, $6C, $4C, $6C, $4C, SDLK_l, { ;:} $27, $3B, $3A, $F000, $F000, $3B, $3B, $3A, $3A, SDLK_SEMICOLON, { '"} $28, $27, $22, $F000, $F000, $27, $27, $22, $22, SDLK_QUOTE, { `~} $29, $60, $7E, $F000, $F000, $60, $60, $7E, $7E, SDLK_BACKQUOTE, {Lshft} $2A, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_LSHIFT, { \|} $2B, $5C, $7C, $1C, $F000, $5C, $5C, $7C, $7C, SDLK_BACKSLASH, { Z } $2C, $7A, $5A, $1A, $2C00, $7A, $5A, $7A, $5A, SDLK_z, { X } $2D, $78, $58, $18, $2D00, $78, $58, $78, $58, SDLK_x, { C } $2E, $63, $43, $03, $2E00, $63, $43, $63, $43, SDLK_c, { V } $2F, $76, $56, $16, $2F00, $76, $56, $76, $56, SDLK_v, { B } $30, $62, $42, $02, $3000, $62, $42, $62, $42, SDLK_b, { Key Scan ASCII Shift Ctrl Alt Num Caps Sh+Caps Sh+Num SDLK_Keycode} { N } $31, $6E, $4E, $0E, $3100, $6E, $4E, $6E, $4E, SDLK_n, { M } $32, $6D, $4D, $0D, $3200, $6D, $4D, $6D, $4D, SDLK_m, { ,<} $33, $2C, $3C, $F000, $F000, $2C, $2C, $3C, $3C, SDLK_COMMA, { .>} $34, $2E, $3E, $F000, $F000, $2E, $2E, $3E, $3E, SDLK_PERIOD, { /?} $35, $2F, $3F, $F000, $F000, $2F, $2F, $3F, $3F, SDLK_SLASH, {Rshft} $36, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_RSHIFT, {PrtSc} $37, $2A, $F000, $F000, $F000, $2A, $2A, $F000, $F000, SDLK_PRINT, {space} $39, $20, $20, $20, $20, $20, $20, $20, $20, SDLK_SPACE, {caps} $3A, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_CAPSLOCK, { F1 } $3B, $3B00, $5400, $5E00, $6800, $3B00, $3B00, $5400, $5400, SDLK_F1, { F2 } $3C, $3C00, $5500, $5F00, $6900, $3C00, $3C00, $5500, $5500, SDLK_F2, { F3 } $3D, $3D00, $5600, $6000, $6A00, $3D00, $3D00, $5600, $5600, SDLK_F3, { F4 } $3E, $3E00, $5700, $6100, $6B00, $3E00, $3E00, $5700, $5700, SDLK_F4, { F5 } $3F, $3F00, $5800, $6200, $6C00, $3F00, $3F00, $5800, $5800, SDLK_F5, { F6 } $40, $4000, $5900, $6300, $6D00, $4000, $4000, $5900, $5900, SDLK_F6, { F7 } $41, $4100, $5A00, $6400, $6E00, $4100, $4100, $5A00, $5A00, SDLK_F7, { F8 } $42, $4200, $5B00, $6500, $6F00, $4200, $4200, $5B00, $5B00, SDLK_F8, { F9 } $43, $4300, $5C00, $6600, $7000, $4300, $4300, $5C00, $5C00, SDLK_F9, { F10} $44, $4400, $5D00, $6700, $7100, $4400, $4400, $5D00, $5D00, SDLK_F10, { num} $45, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_NUMLOCK, {scrl} $46, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_SCROLLOCK, {home} $47, $4700, $4700, $7700, $F000, $4700, $4700, $4700, $4700, SDLK_HOME, { up } $48, $0000, $4800, $F000, $F000, $4800, $4800, $4800, $4800, SDLK_UP, {pgup} $49, $4900, $4900, $8400, $F000, $4900, $4900, $4900, $4900, SDLK_PAGEUP, { np-} $4A, $2D, $2D, $F000, $F000, $2D, $2D, $2D, $2D, SDLK_KP_MINUS, {left} $4B, $4B00, $4B00, $7300, $F000, $4B00, $4B00, $4B00, $4B00, SDLK_LEFT, {centr} $4C, $4C00, $4C00, $F000, $F000, $4C00, $4C00, $4C00, $4C00, SDLK_UNKNOWN, {right} $4D, $4D00, $4D00, $7400, $F000, $4D00, $4D00, $4D00, $4D00, SDLK_RIGHT, { np+} $4E, $2B, $2B, $F000, $F000, $2B, $2B, $2B, $2B, SDLK_KP_PLUS, {end} $4F, $4F00, $4F00, $7500, $F000, $4F00, $4F00, $4F00, $4F00, SDLK_END, {down} $50, $0000, $5000, $F000, $F000, $5000, $5000, $5000, $5000, SDLK_DOWN, {pgdn} $51, $5100, $5100, $7600, $F000, $5100, $5100, $5100, $5100, SDLK_PAGEDOWN, { ins} $52, $5200, $5200, $F000, $F000, $5200, $5200, $5200, $5200, SDLK_INSERT, { del} $53, $5300, $5300, $F000, $F000, $5300, $5300, $5300, $5300, SDLK_DELETE, { F11} $57, $4500, $5E00, $6800, $F000, $4500, $4500, $5E00, $5E00, SDLK_F11, { F12} $58, $4500, $F000, $6900, $F000, $4600, $4600, $5F00, $5F00, SDLK_F12, { np0 } $52, $5200, $5200, $F000, $F000, $30, $30, $29, $30, SDLK_KP0, { np1 } $4F, $4F00, $4F00, $F000, $F000, $31, $31, $21, $31, SDLK_KP1, { np2 } $50, $5000, $5000, $F000, $F000, $32, $32, $40, $32, SDLK_KP2, { np3 } $51, $5100, $5100, $F000, $F000, $33, $33, $23, $33, SDLK_KP3, { np4 } $4B, $4B00, $4B00, $F000, $F000, $34, $34, $24, $34, SDLK_KP4, { np5 } $4C, $4C00, $4C00, $F000, $F000, $35, $35, $25, $35, SDLK_KP5, { np6 } $4D, $4D00, $4D00, $F000, $F000, $36, $36, $5E, $36, SDLK_KP6, { np7 } $47, $4700, $4700, $F000, $F000, $37, $37, $26, $37, SDLK_KP7, { np8 } $48, $4800, $4800, $F000, $F000, $38, $38, $2A, $38, SDLK_KP8, { np9 } $49, $4900, $4900, $F000, $F000, $39, $39, $28, $39, SDLK_KP9, { np. } $53, $5300, $5300, $F000, $F000, $2E, $2E, $3E, $3E, SDLK_KP_PERIOD, { np/ } $35, $2F, $2F, $F000, $F000, $2F, $2F, $2F, $2F, SDLK_KP_DIVIDE, { np* } $37, $2A, $2A, $F000, $F000, $2A, $2A, $2A, $2A, SDLK_KP_MULTIPLY, {NPent} $1C, $0D, $0D, $0A, $F000, $0D, $0D, $0A, $0A, SDLK_KP_ENTER, {LALT} $FC, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_LALT, {RALT} $FD, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_RALT, {LCTRL} $FE, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_LCTRL, {RCTRL} $FF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, $FFFF, SDLK_RCTRL { Key Scan ASCII Shift Ctrl Alt Num Caps Sh+Caps Sh+Num SDLK_Keycode} ); procedure TranslateKeycodes; var i,j: Integer; modkeys: SDLMod; begin // translate SDL_Keycodes to scancodes For i := 0 to SDLK_LAST do For j := 0 to PRED(SYMTABSIZE) do If (i = symtab[j*10+9]) then keydown[symtab[j*10]] := keystate^[i]; // read capslock and numlock state modkeys := SDL_GetModState; _capslock := (modkeys AND KMOD_CAPS) <> 0; _numlock := (modkeys AND KMOD_NUM) <> 0; end; procedure keyboard_poll_input; begin SDL_PumpEvents; TranslateKeycodes; process_global_keys; end; function keypressed: Boolean; var event: SDL_Event; begin keypressed := FALSE; Repeat keyboard_poll_input; If (SDL_PeepEvents(event,1,SDL_PEEKEVENT,SDL_QUITMASK) > 0) then begin _force_program_quit := TRUE; keypressed := TRUE; EXIT; end; If (SDL_PeepEvents(event,1,SDL_PEEKEVENT,SDL_MOUSEEVENTMASK) > 0) then begin // skip mouse events SDL_PeepEvents(event,1,SDL_GETEVENT,SDL_MOUSEEVENTMASK); CONTINUE; end; If (SDL_PeepEvents(event,1,SDL_PEEKEVENT,SDL_KEYDOWNMASK) > 0) then If (event.key.keysym.sym >= SDLK_NUMLOCK) then begin // skip modifier key presses SDL_PeepEvents(event,1,SDL_GETEVENT,SDL_KEYDOWNMASK); CONTINUE; end else keypressed := TRUE; EXIT; until FALSE; end; function getkey: Word; function getkey_proc: Word; var event: SDL_Event; i,j: Integer; begin Repeat draw_screen; If (SDL_PollEvent(@event) <> 0) then begin If (event.eventtype = SDL_EVENTQUIT) or _force_program_quit then begin _force_program_quit := TRUE; getkey_proc := kESC; EXIT; end; // skip all other event except key presses If (event.eventtype <> SDL_KEYDOWN) then CONTINUE else begin // skip all modifier keys If (event.key.keysym.sym >= SDLK_NUMLOCK) then CONTINUE; // roll thru symtab, form correct getkey value For j := 0 to PRED(SYMTABSIZE) do begin If (event.key.keysym.sym = symtab[j*10+9]) then begin // first check with modifier keys, order: ALT, CTRL, SHIFT (as DOS does) { ALT } If (keydown[SC_LALT] = TRUE) or (keydown[SC_RALT] = TRUE) then begin // impossible combination If (symtab[j*10+4] = WORD_NULL) then CONTINUE; If (symtab[j*10+4] > BYTE_NULL) then begin getkey_proc := symtab[j*10+4]; EXIT; end; getkey_proc := (symtab[j*10] SHL 8) OR symtab[j*10+4]; EXIT; end; { CTRL } If (keydown[SC_LCTRL] = TRUE) or (keydown[SC_RCTRL] = TRUE) then begin // impossible combination If (symtab[j*10+3] = WORD_NULL) then CONTINUE; If (symtab[j*10+3] > BYTE_NULL) then begin getkey_proc := symtab[j*10+3]; EXIT; end; getkey_proc := (symtab[j*10] SHL 8) OR symtab[j*10+3]; EXIT; end; { SHIFT } If (keydown[SC_LSHIFT] = TRUE) or (keydown[SC_RSHIFT] = TRUE) then begin i := 2; // SHIFT If (_capslock = TRUE) then i := 7 // caps lock else If (_numlock = TRUE) then i := 8; // num lock // impossible combination If (symtab[j*10+i] = WORD_NULL) then CONTINUE; If (symtab[j*10+i] > BYTE_NULL) then getkey_proc := symtab[j*10+i] else getkey_proc := (symtab[j*10] SHL 8) OR symtab[j*10+i]; EXIT; end; { normal ASCII } i := 1; If (_capslock = TRUE) then i := 6 // caps lock else If (_numlock = TRUE) then i := 5; // num lock // impossible combination If (symtab[j*10+i] = WORD_NULL) then CONTINUE; If (symtab[j*10+i] > BYTE_NULL) then getkey_proc := symtab[j*10+i] else getkey_proc := (symtab[j*10] SHL 8) OR symtab[j*10+i]; // (scancode << 8) + ASCII EXIT; end; end; end; end; until FALSE; end; begin Repeat draw_screen until keypressed; // filter out CTRL+TAB combo as it is handled within timer routine If ctrl_tab_pressed then begin draw_screen; keyboard_reset_buffer; getkey := WORD_NULL; end else getkey := getkey_proc; end; function scankey(scancode: Byte): Boolean; begin TranslateKeycodes; scankey := keydown[scancode]; end; procedure keyboard_reset_buffer; var event: SDL_Event; begin // flush all unused events While (SDL_PollEvent(@event) <> 0) do ; end; procedure wait_until_F11_F12_released; begin _debug_str_ := 'ADT2KEYB.PAS:wait_until_F11_F12_released'; Repeat draw_screen; SDL_PumpEvents; TranslateKeycodes; until NOT keydown[SC_F11] and NOT keydown[SC_F12]; keyboard_reset_buffer; end; function CapsLock: Boolean; begin CapsLock := _capslock; end; function NumLock: Boolean; begin NumLock := _numlock; end; function shift_pressed: Boolean; begin shift_pressed := scankey(SC_LSHIFT) or scankey(SC_RSHIFT); end; function left_shift_pressed: Boolean; begin left_shift_pressed := scankey(SC_LSHIFT); end; function right_shift_pressed: Boolean; begin right_shift_pressed := scankey(SC_RSHIFT); end; function alt_pressed: Boolean; begin alt_pressed := scankey(SC_LALT) or scankey(SC_RALT); end; function ctrl_pressed: Boolean; begin ctrl_pressed := scankey(SC_LCTRL) or scankey(SC_RCTRL); end; procedure screen_saver; begin // relevant for DOS version only end; {$ENDIF} function ctrl_tab_pressed: Boolean; begin ctrl_tab_pressed := ctrl_pressed and scankey(SC_TAB); end; function LookUpKey(key: Word; var table; size: Byte): Boolean; var idx: Byte; begin LookUpKey := FALSE; If (size <> 0) then For idx := 0 to PRED(size) do If (pWord(@table)[idx] = key) then begin LookUpKey := TRUE; BREAK; end; end; end. adlibtracker2-2.4.24/make_win.bat0000644000000000000000000000365713411003760015302 0ustar rootroot@echo off set homedir=%~d1\AT2_Compilation_Environment cd %homedir%\git set ERR_RESULT=??? rem ------------------------------------- set VERSION=2.4.24 rem ------------------------------------- echo. echo ************************************ echo ** ** echo ** STEP 1/4 ** echo ** Validating version info ** echo ** ** echo ************************************ echo. copy /y utils\val_win.exe validate.exe >nul validate.exe %VERSION% del validate.exe >nul echo. echo ************************************ echo ** ** echo ** STEP 2/4 ** echo ** Compiling sources ** echo ** ** echo ************************************ echo. call makefile.bat >!log if not exist adtrack2.exe goto :compile_error if not %ERR_RESULT% == "OK" GOTO :compile_error if not exist *.ppu goto :no_ppu_file del /F /Q *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del /F /Q *.o >nul :no_o_file if not exist *.or goto :no_or_file del /F /Q *.or >nul :no_or_file if not exist *.res goto :no_res_file del /F /Q *.res >nul :no_res_file if not exist !log goto :no_log_file del /F /Q !log >nul :no_log_file echo. echo ************************************ echo ** ** echo ** STEP 3/4 ** echo ** UPX: Compressing EXE file ** echo ** ** echo ************************************ echo. upx -9 adtrack2.exe >nul echo. echo ************************************ echo ** ** echo ** STEP 4/4 ** echo ** Executing program ** echo ** ** echo ************************************ echo. start adtrack2 goto :end :compile_error start %windir%\notepad.exe !log. :end adlibtracker2-2.4.24/typcons2.inc0000644000000000000000000005311213411003760015263 0ustar rootroot// 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 frame_solid_type1 = ' '; frame_solid_type2 = 'ÛßÛÛÛÛÜÛ'; frame_single = 'ÚÄ¿³³ÀÄÙ'; frame_double = 'ÉÍ»ººÈͼ'; frame_double_side = 'ÖÄ·ººÓĽ'; frame_double_top = 'Õ͸³³Ô;'; const prog_exception_title = 'ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ'#13#10+ 'Û ABNORMAL PROGRAM TERMiNATiON Û'#13#10+ 'ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß'#13#10; const patt_win_tracks: array[0..2,1..5] of String[176] = ( ('ÉÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ PATTERN EDiTOR ( ) ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍ»', 'ºLiNEº 1 ³ 2 ³ 3 ³ 4 ³ 5 ºLiNEº', 'ÌÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍ͹', 'º º ³ ³ ³ ³ º º', 'ÈÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍͼ'), ('ÉÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ PATTERN EDiTOR ( ) ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍ»', 'ºLiNEº 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ºLiNEº', 'ÌÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍ͹', 'º º ³ ³ ³ ³ ³ ³ º º', 'ÈÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍͼ'), ('ÉÍÍÍÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ PATTERN EDiTOR ( ) ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍÍÍÍ»', 'ºLiNEº 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ³ 8 ³ 9 ³ 10 ³ 11 ºLiNEº', 'ÌÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍ͹', 'º º ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ º º', 'ÈÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍͼ')); patt_win: array[1..5] of String[176] = ('','','','',''); patt_tab_str: array[0..4] of String[18] = ( 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~~Í~~ÍÍÍÍÍÍÍÍÍÍÍ', 'ÍÍÍÍ~~ÍÍÍÍÍÍÍÍ', 'ÍÍÍÍÍÍÍ~~ÍÍÍÍ', 'ÍÍÍÍÍÍÍÍÍÍÍ~~'); ins_pan_str1: array[0..2] of String[23] = ( '~ú~úúúúú ~ ~ úúúúú~ú~', '~ ~ úúú~ú~úúúúúúú~ú~', '~ú~úúúúúúú~ú~úúú ~ ~'); ins_pan_str2: array[0..2] of String[7] = ( 'úú úú', ' úúúú', 'úúúú '); voice_pan_str: array[0..3] of String[13] = ( '~ú~ú ~ ~ ú~ú~', '~ ~ ~ú~úú~ú~', '~ú~úú~ú~ ~ ~', 'úúúúúúú'); note_keyoff_str: array[0..2] of String[3] = ( 'þþþ', 'ÍÍÍ', '^^ú'); perc_voice_str: array[0..5] of String[7] = ( 'MELODiC', 'PERC:BD', 'PERC:SD', 'PERC:TT', 'PERC:TC', 'PERC:HH'); a2b_header_str: array[1..3] of String[74] = ( ' iNSTRUMENT PANNiNG iNSTRUMENT ', ' NAME DESCRiPTiON ª c « F.TUNE VOiCE ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); a2b_header_hires_str: array[1..3] of String[104] = ( ' iNSTRUMENT PANNiNG iNSTRUMENT ', ' NAME DESCRiPTiON Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 ª c « F.TUNE VOiCE ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); av_browser_str: array[1..6] of String[75] = ( 'ÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ', ' º ~ARPEGGiO MACRO TABLE~ º ~ViBRATO MACRO TABLE~', ' ÇÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄ×ÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄ', ' NO.ºLEN. ³SPEED³L.BEG³L.LEN³K.OFF ºLEN. ³SPEED³DELAY³L.BEG³L.LEN³K.OFF ', 'ÍÍÍÍÎÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍÎÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍ', 'ÍÍÍÍÊÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÍÊÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÏÍÍÍÍÍÍ'); a2w_header_str: array[1..3] of String[72] = ( ' iNSTRUMENT iNSTRUMENT ', ' NAME DESCRiPTiON VOiCE MACROS ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); a2w_header_hires1_str: array[1..3] of String[102] = ( ' iNSTRUMENT iNSTRUMENT ', ' NAME DESCRiPTiON Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 VOiCE MACROS ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); a2w_header_hires2_str: array[1..3] of String[121] = ( ' iNSTRUMENT PANNiNG iNSTRUMENT ', ' NAME DESCRiPTiON Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 ª c « F.TUNE VOiCE MACROS ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); bnk_header_str: array[1..3] of String[72] = ( ' iNSTRUMENT MELODiC/ ', ' NAME Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 PERCUSSiON (VOiCE) ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); fib_header_str: array[1..3] of String[72] = ( ' DOS iNSTRUMENT ', ' NAME NAME Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); ibk_header_str: array[1..3] of String[44] = ( ' iNSTRUMENT ', ' NAME Ú20¿ Ú40¿ Ú60¿ Ú80¿ ÚE0¿ C0 ', 'ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ'); debug_win_str1: array[1..3] of String[130] = ( ' TRACK ~³~ iNSTRUMENT ~³~NOTE~³ ~FX Nù1~ ³ ~FX Nù2~ ³~FREQ~³ ~VOL', 'ÄÄÂÄÄÂÄÄÄÂÄÄÂÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÂÄÄ', 'ÄÄÁÄÄÁÄÄÄÁÄÄÁÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÁÄÄ'); debug_win_str2: array[1..3] of String[130] = ( 'TRACK~³~iNS~³~NOTE~³ ~FX Nù1~ ³ ~FX Nù2~ ³~FREQ~³~CN/FB/ADSR/WF/KSL/MUL/TRM/ViB/KSR/EG~³ ~VOL', 'ÄÄÂÄÄÅÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÂÄÄ', 'ÄÄÁÄÄÁÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÁÄÄ'); debug_win_str3: array[1..3] of String[130] = ( 'TRACK~³~iNS~³~NOTE~³ ~FX Nù1~ ³ ~FX Nù2~ ³~MACRO FM-REG~ ³~MACRO ARPG~³~MACRO ViBR ~³~FREQ~³ ~VOL', 'ÄÄÂÄÄÅÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÅÄÄÂÄÄ', 'ÄÄÁÄÄÁÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÁÄÄÁÄÄ'); const inst_itm1: array[1..18] of Record str: String[24]; colr: Byte; end = ( (str: '~ENV.TYPE/MULT~ ÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~KSL/VOLUME~ ÄÄÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~ATTACK/DECAY~ ÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~SUSTAiN/RELEASE~ ÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~WAVEFORM~ ÄÄÄÄÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~CONNECTiON/FB~  ÄÄ'; colr: 1), (str: '~PANNiNG~  ÄÄ'; colr: 1), (str: '~F-TUNE~  ÄÄ'; colr: 1)); const inst_itm2: array[1..18] of Record str: String[25]; colr: Byte; end = ( (str: '~ENV.TYPE/MULT~ ÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~KSL/VOLUME~ ÄÄÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~ATTACK/DECAY~ ÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~SUSTAiN/RELEASE~ ÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~WAVEFORM~ ÄÄÄÄÄÄÄÄÄÄ¿ '; colr: 1), (str: '~Carrier~ ÃÄ'; colr: 3), (str: '~Modulator~ ÀÄ'; colr: 2), (str: '~CONNECTiON/FB~  ÄÄ'; colr: 1), (str: '~PANNiNG~  ÄÄ'; colr: 1), (str: '~F-TUNE~  ÄÄ'; colr: 1)); const inst_text: array[1..23] of String[72] = ( '~ATTACK RATE~ ±±±±±±±±±±±±±±± ~WAVEFORM TYPE~', '~DECAY RATE~ ±±±±±±±±±±±±±±± ( ) Sine', ' ( ) Half-Sine', '~SUSTAiN LEVEL~ ±±±±±±±±±±±±±±± ( ) Abs-Sine', '~RELEASE RATE~ ±±±±±±±±±±±±±±± ( ) Pulse-Sine', ' ( ) Sine (EPO)', '~OUTPUT LEVEL~ ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±± ( ) Abs-Sine (EPO)', ' ( ) Square', '', '', '', '', '', '', '', '', '', '', '~ENVELOPE TYPE FREQUENCY DATA MULTiPLiER~', '[ ] Tremolo (AM)', '[ ] Vibrato ( )'#159'0 ( )'#159'1 ( )'#159'2 ( )'#159'3 ( )'#159'4 ( )'#159'5', '[ ] Key scale rate (KSR) ( )'#159'6 ( )'#159'7 ( )'#159'8 ( )'#159'9 ( )'#159'10 ( )'#159'10', '[ ] Sustain ( )'#159'12 ( )'#159'12 ( )'#159'15 ( )'#159'15'); const inst_text_ext_2op: array[1..9] of String[72] = ( '~KEY SCALiNG LEVEL~ `GLOBAL iNSTRUMENT SETTiNGS` ( ) Derived square', '( ) Default `šššššššššššššššššššššššššš`', '( ) 1.5 dB/octave `CONNECTiON` `FEEDBACK`', '( ) 3.0 dB/octave ( ) FM ±±±±±±±±±±±±±±±±±', '( ) 6.0 dB/octave ( ) AM MiN MAX', ' ^( ) FM/FM^', '~PANNiNG~ ^( ) FM/AM^ `F-TUNE`', 'ª c « ^( ) AM/FM^ ±±±±±±±±±±±±±±±±±', 'úúúúúúúúúúúúúúúúú ^( ) AM/AM^ - ù +'); const inst_text_ext_perc: array[1..9] of String[72] = ( '~KEY SCALiNG LEVEL~ ^GLOBAL iNSTRUMENT SETTiNGS^ ( ) Derived square', '( ) Default ^šššššššššššššššššššššššššš^', '( ) 1.5 dB/octave ^CONNECTiON FEEDBACK 0^', '( ) 3.0 dB/octave ^( ) FM ±±±±±±±±±±±±±±±±±^', '( ) 6.0 dB/octave ^( ) AM MiN MAX^', ' ^( ) FM/FM^', '~PANNiNG~ ^( ) FM/AM^ `F-TUNE`', 'ª c « ^( ) AM/FM^ ±±±±±±±±±±±±±±±±±', 'úúúúúúúúúúúúúúúúú ^( ) AM/AM^ - ù +'); const inst_text_ext_4op: array[1..9] of String[72] = ( '~KEY SCALiNG LEVEL~ `GLOBAL iNSTRUMENT SETTiNGS` ( ) Derived square', '( ) Default `šššššššššššššššššššššššššš`', '( ) 1.5 dB/octave `CONNECTiON` `FEEDBACK`', '( ) 3.0 dB/octave ^( ) FM^ ±±±±±±±±±±±±±±±±±', '( ) 6.0 dB/octave ^( ) AM^ MiN MAX', ' ( ) FM/FM', '~PANNiNG~ ( ) FM/AM `F-TUNE`', 'ª c « ( ) AM/FM ±±±±±±±±±±±±±±±±±', 'úúúúúúúúúúúúúúúúú ( ) AM/AM - ù +'); const inst_con_scheme: array[0..6,1..6] of String[17] = ( (' ', ' ', ' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁÛ2Û'#26' ', ' ', ' '), (' ', ' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁ¿ ', ' ³ ', ' Û2ÛÄÁ'#26' ', ' '), (' ', ' ', 'ÚÄÄÄ¿ ', 'ÀÛ1ÛÁÛ2ÛÄÛ3ÛÄÛ4Û'#26, ' ', ' '), (' ', ' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁÄÄÄÄÄÄÄÄ¿ ', ' ³ ', ' Û2ÛÄÛ3ÛÄÛ4ÛÄÁ'#26' ', ' '), (' ', ' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁÛ2ÛÄ¿ ', ' Ã'#26' ', ' Û3ÛÄÛ4ÛÄÙ ', ' '), (' ÚÄÄÄ¿ ', ' ÀÛ1ÛÁÄÄÄÄ¿ ', ' ³ ', ' Û2ÛÄÛ3ÛÄÅ'#26' ', ' ³ ', ' Û4ÛÄÄÄÄÄÙ '), (' ', ' ', ' ', ' ', ' ', ' ')); const copy_menu_str1: array[1..15] of String[30] = ( ' COPY ORDER DEF.', ' COPY ORDER TABLE', ' COPY ~i~NSTRUMENT', ' COPY iNSTRUMENT ~B~ANK', ' COPY NOTE', ' COPY iNSTRUMENT DEF.', ' COPY 1ST EFFECT', ' COPY 2ND EFFECT', ' COPY LiNE', ' COPY TRACK', ' COPY PATTERN', ' COPY MARKED BLOCK', ' COPY MACRO-TABLE LiNE', ' COPY MACRO-TABLE COLUMN', ' COPY MACRO-TABLE'); copy_menu_str2: array[1..15] of String[30] = ( ' COPY ORDER DEF.', ' COPY ORDER TABLE', ' COPY iNSTRUMENT', ' COPY iNSTRUMENT BANK', ' COPY ~N~OTE', ' COPY iN~S~TRUMENT DEF.', ' COPY ~1~ST EFFECT', ' COPY ~2~ND EFFECT', ' COPY ~L~iNE', ' COPY ~T~RACK', ' COPY ~P~ATTERN', '', ' COPY MACRO-TABLE LiNE', ' COPY MACRO-TABLE COLUMN', ' COPY MACRO-TABLE'); copy_menu_str3: array[1..15] of String[30] = ( ' COPY ~O~RDER DEF.', ' COPY O~R~DER TABLE', ' COPY iNSTRUMENT', ' COPY iNSTRUMENT BANK', ' COPY NOTE', ' COPY iNSTRUMENT DEF.', ' COPY 1ST EFFECT', ' COPY 2ND EFFECT', ' COPY LiNE', ' COPY TRACK', ' COPY PATTERN', ' COPY MARKED BLOCK', ' COPY MACRO-TABLE LiNE', ' COPY MACRO-TABLE COLUMN', ' COPY MACRO-TABLE'); copy_menu_str4: array[1..15] of String[30] = ( ' COPY ORDER DEF.', ' COPY ORDER TABLE', ' COPY iNSTRUMENT', ' COPY iNSTRUMENT BANK', ' COPY NOTE', ' COPY iNSTRUMENT DEF.', ' COPY 1ST EFFECT', ' COPY 2ND EFFECT', ' COPY LiNE', ' COPY TRACK', ' COPY PATTERN', ' COPY MARKED BLOCK', ' COPY M~A~CRO-TABLE LiNE', ' COPY MA~C~RO-TABLE COLUMN', ' COPY ~M~ACRO-TABLE'); copy_marked_str: array[1..2] of String[30] = ( ' COPY MARKED BLOCK', ' COPY MARKED BLOC~K~'); copy_macro_str: array[1..4] of String[30] = ( ' COPY MACRO-TABLE LiNE', ' COPY M~A~CRO-TABLE LiNE', ' COPY MACRO-TABLE COLUMN', ' COPY MA~C~RO-TABLE COLUMN'); const transp_menu_str1: array[1..17] of String[50] = ( ' [~1~] 1 UP ¿', ' [~2~] 12 UP ö CURRENT', ' [~3~] 1 DOWN ø iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', '', ' [~5~] 1 UP ¿ ÀÄÄÄÄÄÄÄÄÄÙ', ' [~6~] 12 UP ö ALL', ' [~7~] 1 DOWN ø iNSTRUMENTS', ' [~8~] 12 DOWN Ù', '', ' [~A~] 1 UP ¿', ' [~B~] 12 UP ö CURRENT', ' [~C~] 1 DOWN ø iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', '', ' [~E~] 1 UP ¿ ÀÄÄÄÄÄÄÄÄÄÙ', ' [~F~] 12 UP ö ALL', ' [~G~] 1 DOWN ø iNSTRUMENTS', ' [~H~] 12 DOWN Ù'); transp_menu_str2: array[1..8] of String[50] = ( ' [~A~] 1 UP ¿', ' [~B~] 12 UP ö CURRENT', ' [~C~] 1 DOWN ø iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', '', ' [~E~] 1 UP ¿ ÀÄÄÄÄÄÄÄÄÄÙ', ' [~F~] 12 UP ö ALL', ' [~G~] 1 DOWN ø iNSTRUMENTS', ' [~H~] 12 DOWN Ù'); transp_menu_str3: array[1..8] of String[50] = ( ' [A] 1 UP ¿', ' [B] 12 UP ö CURRENT', ' [C] 1 DOWN ø iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', ' [D] 12 DOWN Ù ³ BLOCK ³', ' [E] 1 UP ¿ ÀÄÄÄÄÄÄÄÄÄÙ', ' [F] 12 UP ö ALL', ' [G] 1 DOWN ø iNSTRUMENTS', ' [H] 12 DOWN Ù'); transp_menu_str4: array[1..4] of String[50] = ( ' [~4~] 12 DOWN Ù ³ PATTERN ³', ' [~D~] 12 DOWN Ù ³ SONG ³', ' [~4~] 12 DOWN Ù ³ TRACK ³', ' [~D~] 12 DOWN Ù ³ BLOCK ³'); transp_mnu_str5: array[1..19] of String[32] = ( '~CURRENT~', '~iNSTRUMENT ÉÍÍÍÍÍÍÍÍÍ»~', 'ALL', 'iNSTRUMENTS', 'CURRENT', 'iNSTRUMENT ~ÉÍÍÍÍÍÍÍÍÍ»~', '~ALL~', '~iNSTRUMENTS~', 'iNSTRUMENT ÚÄÄÄÄÄÄÄÄÄ¿', '~º PATTERN º~', '~º TRACK º~', '³ PATTERN ³', '³ TRACK ³', '~º SONG º~', '~º BLOCK º~', '³ SONG ³', '³ BLOCK ³', '~ÈÍÍÍÍÍÍÍÍͼ~', 'ÀÄÄÄÄÄÄÄÄÄÙ'); const macro_table_hint_str: array[1..20+35] of String[77] = ( 'Length of FM-register definition macro-table {1-FF} (0 means no macros)', 'Loop cycle starting position {1-FF} (0 means no loop)', 'Length of loop cycle {1-FF} (0 means no loop)', 'Key-Off jump position {1-FF} (0 means no jump)', 'Arpeggio table number {1-FF} (0 means no arpeggio)', 'Vibrato table number {1-FF} (0 means no vibrato)', '', 'Length of arpeggio macro-table {1-FF} (0 means no macros)', 'Speed of arpeggio in macro-table {1-FF} (0 means no arpeggio)', 'Loop cycle starting position {1-FF} (0 means no loop)', 'Length of loop cycle {1-FF} (0 means no loop)', 'Key-Off jump position {1-FF} (0 means no jump)', 'Number of half-tones to add [1-96] or fixed-note [C,C-,C#,C1,C-1,C#1,...]', 'Length of vibrato macro-table {1-FF} (0 means no macros)', 'Speed of vibrato in macro-table {1-FF} (0 means no vibrato)', 'Delay before starting vibrato in macro-table {1-FF} (0 means no delay)', 'Loop cycle starting position {1-FF} (0 means no loop)', 'Length of loop cycle {1-FF} (0 means no loop)', 'Key-Off jump position {1-FF} (0 means no jump)', 'Frequency to add {1..7F} or subtract {-7F..-1}', 'Attack rate [modulator] {0-F}', 'Decay rate [modulator] {0-F}', 'Sustain level [modulator] {0-F}', 'Release rate [modulator] {0-F}', 'Waveform type [modulator] {0-7}', 'Output level [modulator] {0-3F}', 'Output level [modulator] {0-3F}', 'Key scaling level [modulator] {0-3}', 'Multiplier [modulator] {0-F}', 'Amplitude modulation (tremolo) [modulator] {on/off}', 'Vibrato [modulator] {on/off}', 'Key scale rate [modulator] {on/off}', 'Sustain [modulator] {on/off}', 'Attack rate [carrier] {0-F}', 'Decay rate [carrier] {0-F}', 'Sustain level [carrier] {0-F}', 'Release rate [carrier] {0-F}', 'Waveform type [carrier] {0-7}', 'Output level [carrier] {0-3F}', 'Output level [carrier] {0-3F}', 'Key scaling level [carrier] {0-3}', 'Multiplier [carrier] {0-F}', 'Amplitude modulation (tremolo) [carrier] {on/off}', 'Vibrato [carrier] {on/off}', 'Key scale rate [carrier] {on/off}', 'Sustain [carrier] {on/off}', 'Connection type {0-1} (0=FM,1=AM)', 'Feedback {0-7}', 'Frequency slide {-FFF..+FFF}', 'Frequency slide {-FFF..+FFF}', 'Frequency slide {-FFF..+FFF}', 'Frequency slide {-FFF..+FFF}', 'Panning {Left/Center/Right}', 'Duration {1-FF} (0 means skip)', 'Duration {1-FF} (0 means skip)'); inst_mult_hint: array[0..15] of String[35] = ( '1 octave below', 'at the voice''s specified frequency', '1 octave above', '1 octave and a 5th above', '2 octaves above', '2 octaves and a Major 3rd above', '2 octaves and a 5th above', '2 octaves and a Minor 7th above', '3 octaves above', '3 octaves and a Major 2nd above', '3 octaves and a Major 3rd above', '3 octaves and a Major 3rd above', '3 octaves and a 5th above', '3 octaves and a 5th above', '3 octaves and a Major 7th above', '3 octaves and a Major 7th above'); adlibtracker2-2.4.24/make_dos.bat0000644000000000000000000000357313411003760015267 0ustar rootroot@echo off rem ------------------------------------- set VERSION=2.3.57 rem ------------------------------------- if not exist *.exe goto :no_exe_file del *.exe >nul :no_exe_file if not exist *.ppu goto :no_ppu_file del *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del *.o >nul :no_o_file if not exist !log goto :no_log_file del !log >nul :no_log_file echo. echo ************************************ echo ** ** echo ** STEP 1/4 ** echo ** Validating version info ** echo ** ** echo ************************************ copy /y utils\val_dos.exe validate.exe >nul validate.exe %VERSION% del validate.exe >nul echo. echo ************************************ echo ** ** echo ** STEP 2/4 ** echo ** Compiling sources ** echo ** ** echo ************************************ ppc386 -O2 -OpPENTIUM2 -Ccpascal -Mtp -Rintel -Tgo32v2 adtrack2.pas >!log if not exist adtrack2.exe goto :compile_error if not exist *.ppu goto :no_ppu_file del *.ppu >nul :no_ppu_file if not exist *.o goto :no_o_file del *.o >nul :no_o_file if not exist !log goto :no_log_file del !log >nul :no_log_file echo. echo ************************************ echo ** ** echo ** STEP 3/4 ** echo ** UPX: Compressing EXE file ** echo ** ** echo ************************************ c:\utils\upx -9 adtrack2.exe >nul echo. echo ************************************ echo ** ** echo ** STEP 4/4 ** echo ** Executing program ** echo ** ** echo ************************************ echo. adtrack2 :compile_error adlibtracker2-2.4.24/adt2text.pas0000644000000000000000000023611613411003760015262 0ustar rootroot// 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 . //{$DEFINE BETA} unit AdT2text; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const {__AT2VER__}at2ver = '2.4.24'; {__AT2DAT__}at2date = '12-27-2018'; {__AT2LNK__}at2link = '9:12am'; const {$IFNDEF BETA} _ADT2_TITLE_STRING_ = '/´DLiB TR/´CK3R ]['; {$ELSE} _ADT2_TITLE_STRING_ = '/´DLiB TR/´CK3R ][ BETA VERSiON'; {$ENDIF} {$IFDEF GO32V2} _PLATFORM_STR_ = 'DOS'; {$ELSE} _PLATFORM_STR_ = 'SDL'; {$ENDIF} const {$IFDEF GO32V2} HELP_LINES = 1135; {$ELSE} HELP_LINES = 1163; {$ENDIF} {$IFDEF GO32V2} const ascii_line_01 = ' Ú-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-¿'; ascii_line_02 = ' ³ ~Û~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛÛÛ~`²`° ~ÛÛÛÛÛÛ~`²`° ³'; ascii_line_03 = ' ³ ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_04 = ' ù ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_05 = ' ú ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_06 = ' ~Û~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛ~`²`° ~Û~`²`° ~ÛÛ~`²`° ³'; ascii_line_07 = ' ~Û~`²`° ~ÛÛÛÛ~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_08 = ' ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_09 = ' ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_10 = ' ú ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_11 = ' ù ~Û~`²`° ~ÛÛÛÛÛÛÛÛ~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛÛÛÛ~`²`° ³'; ascii_line_12 = ' À-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄ-Äùú úù-ÄÄÄÄ-Ù'; ascii_line_13 = ' .:: ~THE ULTiMATE FM-TRACKiNG TOOL~ ::. '; ascii_line_14 = ' Ú-Ä--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-¿'; ascii_line_15 = ' ³ `code:` ~ÄÂÄ ÄÄ~ ù'; ascii_line_16 = ' ³ ~subz3ro/Altair~ ~/´DLiB³R/´CK3R ³³ G3~ ú'; ascii_line_17 = ' ³ `additional ideas:` ~³ ³ ÄÄ~ '; ascii_line_18 = ' ³ ~Malfunction/Altair~ ~'+at2ver+'~ '; ascii_line_19 = ' ³ ~Diode Millimpere~ ú'; ascii_line_20 = ' ³ `special thanks:` ú'; ascii_line_21 = ' ³ ~encore~ HOMEPAGE www.adlibtracker.net ³'; ascii_line_22 = ' ³ ~Maan M. Hamze~ EMAiL subz3ro.altair@gmail.com ³'; ascii_line_23 = ' À-ÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù'; procedure C3WriteLn(str: String; atr1,atr2,atr3: Byte); {$ELSE} const ascii_line_01 = 'Ú-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-¿'; ascii_line_02 = '³ ~Û~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛÛÛ~`²`° ~ÛÛÛÛÛÛ~`²`° ³'; ascii_line_03 = '³ ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_04 = 'ù ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_05 = 'ú ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_06 = ' ~Û~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛ~`²`° ~Û~`²`° ~ÛÛ~`²`° ³'; ascii_line_07 = ' ~Û~`²`° ~ÛÛÛÛ~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_08 = ' ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_09 = ' ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_10 = 'ú ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ~Û~`²`° ³'; ascii_line_11 = 'ù ~Û~`²`° ~ÛÛÛÛÛÛÛÛ~`²`° ~Û~`²`° ~ÛÛÛÛÛÛÛÛÛÛ~`²`° ³'; ascii_line_12 = 'À-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄ-Äùú úù-ÄÄÄÄ-Ù'; ascii_line_13 = ' .:: ~THE ULTiMATE FM-TRACKiNG TOOL~ ::. '; ascii_line_14 = 'Ú-Ä--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-¿'; ascii_line_15 = '³ `code:` ~ÄÂÄ ÄÄ~ ù'; ascii_line_16 = '³ ~subz3ro/Altair~ ~/´DLiB³R/´CK3R ³³ SDL~ ú'; ascii_line_17 = '³ `additional ideas:` ~³ ³ ÄÄ~ '; ascii_line_18 = '³ ~Malfunction/Altair~ ~'+at2ver+'~ '; ascii_line_19 = '³ ~Diode Milliampere~'; ascii_line_20 = '³ `special thanks:` ù'; ascii_line_21 = '³ ~Dmitry Smagin~ ú'; ascii_line_22 = '³ ~Windfisch~ HOMEPAGE www.adlibtracker.net ³'; ascii_line_23 = '³ ~insane/Altair~ EMAiL subz3ro.altair@gmail.com ³'; ascii_line_24 = 'À-ÄÄÄÄÄÄÄÄÄÄ--ùú úù-ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ-Ù'; procedure C3WriteLn(posX,PosY: Byte; str: String; atr1,atr2,atr3: Byte); {$ENDIF} const help_data: array[1..HELP_LINES] of String[128] = ( '@topic:general', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `GENERAL KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~F1~ Help', '~F2 (^S)~ Save file', '~F3 (^L)~ Load file', '~F4 (^A)~ Toggle Nuke''m dialog', '~F5~ Play', '~F6~ Pause', '~F7~ Stop', '~F8~ Play song from current pattern or order', '~F9~ Play current pattern or order only', '~[Ctrl] F8~ @F8 from current line ¿ ', '~[Ctrl] F9~ @F9 from current line à (Pattern Editor)', '~[Alt] F6~ Single-play pattern Ù (~Shift~ toggles trace)', '~[Alt] F5~ @F5 ¿', '@input:alt_f8', '~[Alt] F9~ @F9 Ù', '~[Shift] F2~ Quick Save', '~[Shift] F3~ Quick Load', '@input:shift_f5', '~[Shift] F6~ Toggle Debug mode from position at cursor', '@input:shift_f8', '@input:shift_f9', '~[Shift] Space~ Toggle MidiBoard mode ON/OFF', '~^Space~ Toggle Note Recorder mode ON/OFF', '~[Ctrl] Home,End~ Skip to previous/next pattern while Tracing', '~+,-~ Same as above; play pattern from start', '', '@topic:note_recorder', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `WHEN iN NOTE RECORDER MODE` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~[Ctrl] ,'#26'~ Select group of tracks for recording ³', '³ ~[Alt] Q~ Quick reset last selected group of tracks ³', '³ ~Enter~ Start recording from current position ~(*)~ ³', '³ ~Space~ `Toggle` using custom instrument for all tracks ¿ ³@@spec_attr:01@@', '³ ~[Alt] Space~ `Toggle` using present instruments in tracks ö ref. ³@@spec_attr:02@@', '³ ~MBoard keys~ Write notes to corresponding tracks ø ~(*)~ ³', '³ ~F8,F9~ Toggle pattern repeat OFF/ON Ù ³', '³ ~Backspace~ Clear note/instrument sequence in tracks ³', '³ ~^Backspace~ Clear complete note/instrument columns ³', '³ ~,~ Rewind/Fast-Forward while recording ³', '³ ~[Shift] ,~ Increase/Decrease row correction for writing notes ³', '³ ~[Shift] F6~ Continue in Debug mode from position at cursor ³', '³ ~F7~ Stop recording and reset starting position; ³', '³ current group of tracks can be modified ³', '³ ~[Alt] 1..9,0~ Toggle track channel ON/OFF (~Shift~ toggles 1`X`) ³', '³ ~[Alt] R~ Reset flags on all tracks ³', '³ ~*~ Reverse ON/OFF on all tracks ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ In case you need non-continuos track selection, you can choose ³', '³ from already selected group a subset of tracks where notes will be ³', '³ written by manipulating track ON/OFF flags. ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `iF SONG iS PLAYED WiTH TRACE, iT CAN BE REMOVED WHiLE...` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~Enter~ Playback is paused and cursor stays on position ³', '³ ~Esc~ Cursor jumps to last position and playback continues ³', '³ ~[Shift] Esc~ Cursor stays on position and playback continues ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', '~^Enter~ Play next pattern according to order', '~[Ctrl]  ()~ Rewind current pattern (with Trace)', '~[Ctrl] '#26' ()~ Fast-Forward (with Trace)', '~[Ctrl]{Shift} ,~ Change playback speed up/down `{fine stepping}`', '~[Ctrl]{Shift} []~ Reset playback speed `{default speed}`', '~[Ctrl][Alt] ~ Temporarily show Debug Info window', '~^B~ Toggle Message Board window', '~^D~ Toggle Debug Info window', '~^Q~ Toggle Instrument Macro Editor window', '~^G~ Toggle Arpeggio/Vibrato Macro Editor window', '~^M~ Toggle Macro Browser window', '~^F~ Toggle Song Variables window', '~^H~ Toggle Replace window', '~^I~ Toggle Instrument Control panel', '~^E~ Toggle Instrument Editor window', '~^O~ Toggle Octave Control panel', '~^P~ Toggle Pattern List window', '~^R~ Toggle Remap Instrument window', '~^T~ Toggle Transpose window', '~^X~ Toggle Rearrange Tracks window', '~^1..^8~ Quick-set octave', '~[Alt]{Shift} +,- {,}~ Adjust volume level of sound output', '~[Alt] C~ Copy object to clipboard (with selection)', '~[Alt] P~ Paste object from clipboard', '~[Alt] M~ Toggle marking lines ON/OFF', '~[Alt] L~ Toggle Line Marking Setup window', '~[Alt] 1..9,0~ Toggle track channel ON/OFF (~Shift~ toggles 1`X`)', '~[Alt] S~ Set all OFF except current track (solo)', '~[Alt] R~ Reset flags on all tracks', '~*~ Reverse ON/OFF on all tracks', '~F10~ Quit program', '~F11~ Toggle typing mode in Pattern Editor (`AT`'#26'`FT`'#26'`ST`)', '~F12~ Toggle `line feed` in Pattern Editor', '~[Shift] F12~ Toggle `jump to marked line` in Pattern Editor', {$IFDEF GO32V2} '~[Ctrl][Tab] [...] (*)~ Scroll screen content (if necessary)', '', '~(*) ,,,'#26',PgUp,PgDown,Home,End~', {$ELSE} '~[Ctrl][Tab] [...] (*)~ Scroll Volume Analyzer section (if necessary)', '', '~(*) ,,PgUp,PgDown~', '', '@topic:wav_recorder', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `WAV RECORDER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '', '~[Alt|Ctrl]{Shift} F11~ Toggle WAV recording ON', '~[Alt|Ctrl]{Shift} F12~ Toggle WAV recording OFF', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `FUNCTiONALiTY OF ALTERNATiVE KEYS` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~Alt~ Toggle normal recording mode ³', '³ ~Ctrl~ Toggle ''per track'' recording mode ³', '³ ~Shift~ Toggle Fade in / Fade out sound processing ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ POSSiBLE COMBiNATiONS: Alt,Ctrl,Alt+Shift,Ctrl+Shift ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', 'If ''per track'' recording mode is activated and song playback is stopped,', 'you can exclude/include corresponding tracks from/to being recorded', 'with ordinary track selection procedure:', '', '~[Alt] 1..9,0~ Toggle track channel ON/OFF (~Shift~ toggles 1`X`)', '~[Alt] S~ Set all OFF except current track (solo)', '~[Alt] R~ Reset flags on all tracks', {$ENDIF} '', '@topic:pattern_order', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `PATTERN ORDER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26'~ Cursor navigation', '~PgUp,PgDn~ Move up/down 32 patterns', '~Home,End~ Move to the top/end of pattern order', '~Tab,[Shift] Tab~ Move to next/previous entry', '~Insert~ Insert entry', '~Delete~ Delete entry', '~Backspace~ Clear entry', '~^Space~ Enter skip mark', '~^C~ Copy entry to clipboard', '~^V~ Paste entry from clipboard', '~+,-~ Adjust entry', '~^F2~ Save module in tiny format', '~Enter~ Switch to Pattern Editor', '', 'ORDER ENTRiES: 0-7F', ' 80-FF = jump to pattern order 0-7F', ' syntax: order_number[hex](+80h); e.g. "9A" jumps to order 1A', '', '@topic:pattern_editor', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `PATTERN EDiTOR KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26'~ Cursor navigation', '~PgUp,PgDn~ Move up/down 16 lines', '~Home,End~ Move to the top/end of current pattern', '~Tab,[Shift] Tab~ Move to next/previous track', '~[Shift] PgDn,PgUp (+,-)~ Move to next/previous pattern', '~[Shift] Home,End~ Move fwd./bckwd. to the first/last pattern', '~^Home,^End~ Move to the end/top of previous/next pattern', '~Space~ Advance to next row', '~^PgUp,^PgDn~ Transpose note or block halftone up/down', '~Backspace~ Remove note or clear attributes', '~Insert~ Insert new line (within track only)', '~Delete~ Delete line (within track only)', '~[Shift] Insert~ Insert new line', '~[Shift] Delete~ Delete line', '~[Shift] Enter~ Toggle fixed and regular note', '~^K~ Insert Key-Off', '~^C~ Copy object at cursor to clipboard', '~^V~ Paste object from clipboard', '~[Alt][Shift] P~ Paste object from clipboard to more patterns', '~^Z~ Undo last operation (if possible)', '~{Ctrl} "[","]"~ Change current instrument', '~[Alt] F2~ Save current pattern to file', '~^F2~ Save module in tiny format', '~[Shift] F3~ Quick load recent pattern data', '~Enter~ Switch to Pattern Order', '', 'NOTE SYSTEM: C,C#,D,D#,E,F,F#,G,G#,A,A#,B(H)', 'VALiD NOTE ENTRiES: C,C-,C#,C1,C-1,C#1...', '', '@topic:block_operations', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `BLOCK OPERATiONS iN PATTERN EDiTOR` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ Starting to mark a block: ~[Shift] ,,,'#26'~ ³', '³ When at least one row in one track is marked, you can continue ³', '³ marking also with ~PgUp,PgDn,Home,End~ (~Shift~ is still held down!) ³', '³ Quick mark: ~[Alt] Q~ (1x-2x-3x) track Ä pattern Ä discard ³', '³ Toggle last marked block: ~[Alt] B~ ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~^B~ Blank block (Insert blank block to pattern) ³', '³ ~^C~ Copy block (Copy block to clipboard) ³', '³ ~^D~ Delete block (Remove block from pattern) ³', '³ ~^N~ Nuke block (Clear block contents) ³', '³ ~^V~ Paste block (Paste block from clipboard to pattern) ~(*)~ ³', '³ ~^X~ Cut block (Combine both Copy and Delete operation) ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ `(*) PASTE BLOCK OPERATiON VARiANTS` ³', '³ œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœ ³', '³ "Paste block" operation has three other functional variants ³', '³ with different key shortcuts for activation: ³', '³ 1) ~[Alt] V~ toggles "Mix block" operation, when block data ³', '³ from clipboard is applied without overwriting existing data; ³', '³ 2) ~[Shift] ^V~ toggles "Selective paste block" operation, ³', '³ when only block data from clipboard corresponding to current ³', '³ cursor position is being applied (i.e. note, instrument, ³', '³ 1st effect or 2nd effect); ³', '³ 3) ~[Alt][Shift] V~ toggles "Flipped paste block" operation, ³', '³ when block data from clipboard is applied vertically flipped. ³', '³ ³', '³ `MANiPULATiON WiTH FX VOLUME iNFORMATiON` ³', '³ œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœ ³', '³ When there is block marked, which contains some effect ³', '³ commands carrying volume information, you can increase/decrease ³', '³ their values with ~+~/~-~ keys. ³', '³ Effect commands are processed with following priority: ³', '³ 1) Set instrument volume (~Cxx~), ³', '³ Force instrument volume (~=xx~) ³', '³ 2) Set modulator volume (~9xx~) ³', '³ 3) Set carrier volume (~Ixx~) ³', '³ 4) Set global volume (~%xx~) ³', '³ If effect command with higher priority has been processed, ³', '³ all remaining effect commands with lower priority are skipped. ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', '@topic:pattern_list', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `PATTERN LiST WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,~ Cursor navigation', '~PgUp,PgDn~ Move up/down 20 patterns', '~Home,End~ Move to the top/end of pattern list', '~Space~ Mark/Unmark pattern', '~^Space~ Unmark all marked patterns', '~[Shift] ^Space~ Reverse marks on all patterns', '~[Alt] C (^C)~ Copy pattern to clipboard', '~[Alt] P (^V)~ Paste pattern from clipboard', '~[Shift] ^V~ Paste pattern data from clipboard', '~[Alt] V~ Paste pattern name(s) from clipboard', '~^N~ Nuke current pattern', '~[Shift] ^N~ Nuke all marked patterns', '~^W~ Swap marked patterns', '~[Shift] ^W~ Swap marked patterns w/o names', '~[Shift] Insert~ Insert new pattern', '~[Shift] Delete~ Delete current pattern', '~Enter~ Rename pattern / Multiple paste', '~[Shift] F3~ Quick load recent pattern data', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:instrument_control', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT CONTROL PANEL KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,~ Cursor navigation', '~PgUp,PgDn~ Move up/down 16 instruments', '~Home,End~ Move to the top/end of instrument list', '~Space~ Mark/Unmark instrument', '~Enter~ Rename instrument', '~^C~ Copy instrument to clipboard', '~[Shift] ^C~ Copy instrument also with macro-definitions', '~^V~ Paste instrument(s) from clipboard', '~[Shift] ^V~ Paste instrument data from clipboard', '~[Alt] V~ Paste instrument name(s) from clipboard', '~^W~ Swap marked instruments', '~[Shift] ^W~ Swap marked instruments w/o names', '~Tab~ Toggle Instrument Editor window', '~[Shift] Tab~ Toggle Macro Editor window', '~[Shift] O~ Toggle operator mode  / ', '~[Shift] M,B,S,T,C,H~ Toggle `m`elodic and percussion (`B`D,`S`D,`T`T,T`C`,`H`H)', '~[Shift] F2~ Save instrument w/ fm-register macro to file', '~[Alt] F2~ Save instrument bank to file', '~^F2~ Save instrument bank w/ all macros to file', '~[Shift] F3~ Quick load recent instrument data', '~MBoard keys ~ Preview instrument', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:instrument_editor', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT EDiTOR WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~[Alt]
~ Jump to section', '~Tab~ Jump to next setting', '~[Shift] Tab~ Jump to previous setting', '~PgUp,PgDn (+,-)~ Adjust value', '~Space~ Select item', '~^Space~ `(opt.)` Toggle ADSR preview ON/OFF', '~[Ctrl] "[","]"~ Change current instrument', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~[Alt]{Shift} 1..4,0~ Set operators for instrument preview ~(*)~', '~Enter~ Toggle carrier/modulator/ slot settings', '~[Shift] O~ Toggle operator mode  / ', '~[Shift] M,B,S,T,C,H~ Toggle `m`elodic and percussion (`B`D,`S`D,`T`T,T`C`,`H`H)', '~[Shift] F2~ Save instrument w/ fm-register macro to file', '~[Shift] Enter~ Copy values from carrier/modulator slot', '~MBoard keys ~ Preview instrument', '~Esc~ Return to Instrument Control panel', '', '~(*) [Alt] 1..4~ Set solo operator', ' ~[Alt][Shift] 1..4~ Toggle operator ON/OFF', ' ~[Alt] 0~ Reset', '', '@topic:macro_editor', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT MACRO EDiTOR WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~PgUp,PgDown~ Move up/down 16 lines', '~Tab (Enter)~ Jump to next field in order', '~[Shift] Tab~ Jump to previous field in order', '~[Shift] ,~ Synchronous navigation within tables', '~[Shift] Home,End~ Move to the start/end of current line in table', '~[Ctrl] ,'#26'~ Switch between macro tables', '~[Ctrl][Shift] ,'#26'~ Navigate to start/end of macro table', '~^PgUp,^PgDown~ Change current arpeggio/vibrato table', '~[Ctrl] "[","]"~ Change current instrument', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~[Alt]{Shift} 1..4,0~ Set operators for instrument preview ~(*)~', '~[Alt] ^C~ Copy values from carrier column', '~[Alt] ^M~ Copy values from modulator column', '~^C~ Copy line in table (whole table respectively)', '~[Shift] ^C~ Copy column in table', '~^V~ Paste object from clipboard', '~^Enter~ Paste data from instrument registers', '~[Shift] Enter~ Paste data to instrument registers', '~[Shift] ^Enter~ Paste data from instrument registers w/ selection', '~Backspace~ Clear current item in table', '~[Shift] Backspace~ Clear line in table', '~+,-~ Adjust value at cursor / current item in table', '~^Home,^End~ Quick-adjust table length', '~[Shift] ^Home,^End~ Quick-adjust loop begin position', '~[Shift] ^PgUp,^PgDown~ Quick-adjust loop length', '~Insert~ Insert new line in table', '~Delete~ Delete line in table', '~^E~ Toggle envelope restart ON/OFF ¿', '~^N~ Toggle note retrigger ON/OFF ö', '~^Z~ Toggle ZERO frequency ON/OFF ö', '~[Alt] ^E,^N,^Z~ Reset all alike flags in table ö FM-register', '~^Backspace~ Toggle corresponding column ON/OFF ø table', '~[Alt] S~ Set all OFF except current column ö', '~[Alt] R~ Reset flags on all columns ö', '~*~ Reverse ON/OFF on all columns Ù', '~\~ Toggle current item (switch types only)', '~Space~ Toggle macro-preview mode', '~^Space~ Toggle Key-Off loop within macro-preview mode', '~^F2~ Save instrument bank w/ all macros to file', '~Esc~ Leave Instrument Macro Editor window', '', '~(*) [Alt] 1..4~ Set solo operator', ' ~[Alt][Shift] 1..4~ Toggle operator ON/OFF', ' ~[Alt] 0~ Reset', '', '@topic:macro_editor_(av)', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `APREGGiO/ViBRATO MACRO EDiTOR WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~PgUp,PgDown~ Move up/down 16 lines', '~Tab (Enter)~ Jump to next field in order', '~[Shift] Tab~ Jump to previous field in order', '~[Shift] ,~ Synchronous navigation within tables', '~[Ctrl] ,'#26'~ Switch between macro tables', '~[Ctrl][Shift] ,'#26'~ Navigate to start/end of macro table', '~^PgUp,^PgDown~ Change current arpeggio/vibrato table', '~[Ctrl] "[","]"~ Change current instrument', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~[Alt]{Shift} 1..4,0~ Set operators for instrument preview ~(*)~', '~^C~ Copy line in table (whole table respectively)', '~[Shift] ^C~ Copy column in table', '~^V~ Paste object from clipboard', '~Backspace~ Clear current item in table', '~[Shift] Backspace~ Clear line in table', '~+,-~ Adjust value at cursor / current item in table', '~^Home,^End~ Quick-adjust table length', '~[Shift] ^Home,^End~ Quick-adjust loop begin position', '~[Shift] ^PgUp,^PgDown~ Quick-adjust loop length', '~Space~ Toggle macro-preview mode', '~^Space~ Toggle Key-Off loop within macro-preview mode', '~[Shift] Esc~ Apply table indexes to current instrument', '~Esc~ Leave Arpeggio/Vibrato Macro Editor window', '', '~(*) [Alt] 1..4~ Set solo operator', ' ~[Alt][Shift] 1..4~ Toggle operator ON/OFF', ' ~[Alt] 0~ Reset', '', '@topic:macro_browser', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT MACRO BROWSER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~[Shift] ,~ Move up/down in macro table', '~[Shift] ,'#26'~ Move left/right in macro table', '~[Shift] PgUp,PgDown~ Move page up/down in macro table', '~[Shift] Home,End~ Move to the start/end of macro table', '~[Ctrl] Home,End~ Move to the start/end of line in macro table', '~Enter~ Load selected macro data', '~^Enter~ `(opt.)` Load all macro data from bank', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~MBoard keys ~ Preview instrument with selected macro data', '~Tab~ `(opt.)` Switch to Arpeggio/Vibrato Macro Browser window', '~Esc~ Leave Instrument Macro Browser window', '', '@topic:macro_browser_av', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `ARPEGGiO/ViBRATO MACRO BROWSER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,PgUp,PgDown,~', '~Home,End~ Cursor navigation', '~[Shift] ,'#26'~ Move left/right in arpeggio table ¿', '~[Shift] PgUp,PgDown~ Move page left/right in arpeggio table ö', '~[Ctrl] ,'#26'~ Move left/right in vibrato table ö refer to', '~^PgUp,^PgDown~ Move page left/right in vibrato table ø ~(*)~', '~[Shift]{Alt} Space~ Toggle arpeggio table selection ~(**)~ ö', '~[Ctrl] {Alt} Space~ Toggle vibrato table selection ~(**)~ Ù', '~[Shift] Home,End~ Navigate to start/end of arpeggio table', '~^Home,^End~ Navigate to start/end of vibrato table', '~[Ctrl] "[","]"~ Change current instrument', '~[Ctrl][Shift] "[","]"~ Change macro speed', '~MBoard keys ~ Preview instrument with selected macro data', '~Enter~ Load selected macro data', '~^Enter~ `(opt.)` Load all macro data from bank', '~Esc~ Leave Arpeggio/Vibrato Macro Browser window', '', '~(*)~ Key combination with ~Ctrl+Shift~ applies action to both tables', '~(**)~ ~Alt~ key invokes no arpeggio resp. vibrato table (index value reset)', '', '@topic:debug_info', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `DEBUG iNFO WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,PgUp,PgDown,~', '~Home,End~ Change current track', '~Tab~ Toggle details', '~Backspace~ Toggle pattern repeat', '~Space~ Enter Debug mode / Proceed step', '~^Space~ Exit Debug mode', '~[Ctrl] Home,End~ Skip to previous/next pattern', '~+,-~ Same as above; play pattern from start', '~^Enter~ Play next pattern according to order', '~[Ctrl] ,'#26'~ Rewind/Fast-Forward current pattern', '~[Alt] 1..9,0~ Toggle track channel ON/OFF (~Shift~ toggles 1`X`)', '~[Alt] S~ Set all OFF except current track (solo)', '~[Alt] R~ Reset flags on all tracks', '~*~ Reverse ON/OFF on all tracks', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:remap_dialog', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `REMAP iNSTRUMENT WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~PgUp,PgDown~ Move up/down 16 instruments', '~Tab~ Jump to next selection', '~[Shift] Tab~ Jump to previous selection', '~MBoard keys ~ Preview instrument', '~Enter~ Remap', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:rearrange_dialog', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `REARRANGE TRACKS WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~Tab~ Jump to next selection', '~[Shift] Tab~ Jump to previous selection', '~^PgUp,^PgDown~ Shift track at cursor up/down in the track list', '~[Shift] ^PgUp,^PgDown~ Rotate track list from cursor upside/downside', '~Enter~ Rearrange', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:replace_dialog', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `REPLACE WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',Home,End~ Cursor navigation', '~Tab~ Jump to next selection', '~[Shift] Tab~ Jump to previous selection', '~^K~ Insert Key-Off in note column', '~^N~ Mark "new" field to clear found item', '~^W~ Swap "to find" and "replace" mask content', '~Delete,Backspace~ Delete current/previous character', '~^Backspace~ Delete "to find" or "replace" mask content', '~[Shift] ^Backspace~ Delete content of both masks', '~Enter~ Replace', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:song_variables', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `SONG VARiABLES WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26'~ Cursor navigation', '~[Alt]
~ Jump to section', '~Tab (Enter)~ Jump to next variable field', '~[Shift] Tab~ Jump to previous variable field', '~Space~ Select item', '~^Enter~ Setup rows per beat for BPM calculation', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:file_browser', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `FiLE BROWSER KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26'~', '~PgUp,PgDown,Home,End~ Cursor navigation', {$IFDEF UNIX} '~/~ Navigate to root directory', {$ELSE} '~\~ Navigate to drive root', {$ENDIF} '~Backspace~ Navigate to parent directory', '~[Shift] Backspace~ Navigate to program home directory', '~MBoard keys ~ Preview instrument (instrument files only)', '~Enter~ Choose file under cursor / read instrument bank', '~Esc~ Leave without choosing file', '', '@topic:message_board', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `MESSAGE BOARD WiNDOW KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,,,'#26',^PgUp,^PgDown,~', '~Home,End,^Home,^End~ Cursor navigation', '~PgUp,PgDown~ Move backwards/forwards over text', '~[Ctrl] ,'#26'~ Move word left/right', '~Backspace,Delete~ Delete character left/right', '~^Backspace,^T~ Delete word left/right', '~^K~ Delete characters to end', '~^Y~ Delete current line', '~Tab~ Indent current line', '~^Space~ Insert row for text at cursor', '~[Shift] ^Backspace~ Delete row for text at cursor', '~Insert~ Toggle input and overwrite mode', '~Enter~ Wrap line of text', '~Esc~ Return to Pattern Editor or Pattern Order', '', '@topic:input_field', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNPUT FiELD KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~,'#26',Home,End~ Cursor navigation', '~[Ctrl] ,'#26'~ Move word left/right', '~Backspace,Delete~ Delete character left/right', '~^Backspace,^T~ Delete word left/right', '~^K~ Delete characters to end', '~^Y~ Delete string', '~Insert~ Toggle input and overwrite mode', '~+,-~ Increment/decrement decimal or hexadecimal value', '', '@topic:midiboard', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `MiDiBOARD KEY REFERENCE` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '', ' C# D# F# G# A# C# D# F# G# A# C# D#', '', ' ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ', ' ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ', ' ÞÛÛ ~S~ÞÛ ~D~ÞÛÛÞÛÛ ~G~ÞÛ ~H~ÞÛ ~J~ÞÛÛÞÛÛ ~2~ÞÛ ~3~ÞÛÛÞÛÛ ~5~ÞÛ ~6~ÞÛ ~7~ÞÛÛÞÛÛ ~9~ÞÛ ~0~ÞÛÛ', ' ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ', ' ÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛ ÞÛÛÞÛÛ ÞÛ ÞÛÛ', ' ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ', ' ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ', ' ÞÝ~Z~ÞÞÝ~X~ÞÞÝ~C~ÞÞÝ~V~ÞÞÝ~B~ÞÞÝ~N~ÞÞÝ~M~ÞÞÝ~Q~ÞÞÝ~W~ÞÞÝ~E~ÞÞÝ~R~ÞÞÝ~T~ÞÞÝ~Y~ÞÞÝ~U~ÞÞÝ~I~ÞÞÝ~O~ÞÞÝ~P~Þ', ' ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ', ' ÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛÞÛÛÛ', '', ' C D E F G A B C D E F G A B C D E', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `WHiLE TRACKER iS iN MiDiBOARD MODE` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´', '³ ~MBoard key~ copies note in note field, plays it, and advances song ³', '³ to next row. If used with ~Left-Shift~ key and line marking toggled ON, ³', '³ it advances song to next highlighted row. ³', '³ If used with ~Right-Shift~ key, it makes a fixed note. ³', '³ ~Space~ plays row and advances song by one row. ³', '³ ~@@` inserts Key-Off, releases playing note and advances to next row. ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', '@topic:instrument_registers', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `iNSTRUMENT REGiSTERS` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '~Attack rate~', 'Indicates how fast the sound volume goes to maximum.', '1=slow, 15=fast. 0 means no attack phase.', '', '~Decay rate~', 'Indicates how fast the sound goes from maximum level to sustain level.', '1=slow, 15=fast. 0 means no decay phase.', '', '~Sustain level~', 'Indicates the sustain level.', '1=loudest, 15=softest. 0 means no sustain phase.', '', '~Release rate~', 'Indicates how fast the sound goes from sustain level to zero level.', '1=slow, 15=fast. 0 means no release phase.', '', '~Output level~', 'Ranges from 0 to 63, indicates the attenuation according to the', 'envelope generator output. In Additive synthesis, varying', 'the output level of any operator varies the volume of its corresponding', 'channel. In FM synthesis, varying the output level of carrier varies', 'the volume of its corresponding channel, but varying the output of', 'the modulator will change the frequency spectrum produced by the carrier.', '', '~Waveform select~', 'Specifies the output waveform type.', 'The first is closest to pure sine wave, the last is most distorted.', '', '`[0] SiNE`', '', ' ', ' ³', ' ³ __ __', ' ³ / \ / \', ' ³ / \ / \', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³ \ / \ /', ' ³ \ / \ /', ' ³ ', ' ³ 1/2 1 3/2 2 pi', '', '', '`[1] HALF-SiNE`', '', ' ', ' ³', ' ³ __ __', ' ³ / \ / \', ' ³ / \ / \', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³', ' ³ 1/2 1 3/2 2 pi', ' ³', ' ³', '', '', '`[2] ABS-SiNE`', '', ' ', ' ³', ' ³ __ __ __ __', ' ³ / \ / \ / \ / \', ' ³ / \ / \ / \ / \', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³', ' ³ 1/2 1 3/2 2 pi', ' ³', ' ³', '', '', '`[3] PULSE-SiNE`', '', ' ', ' ³', ' ³ _ _ _ _', ' ³ / | / | / | / |', ' ³/ | / | / | / |', ' ÄÅÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄ', ' ³', ' ³ 1/4 1/2 3/4 1 5/4 3/2 7/4 2 pi', ' ³', ' ³', '', '', '`[4] SiNE, EVEN PERiODS ONLY (EPO)`', '', ' ', ' ³', ' ³', ' ³ /\ /\', ' ³/ \ / \', ' ÄÅÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄ', ' ³ \ / \ /', ' ³ \_/ \_/', ' ³', ' ³ 1/4 1/2 3/4 1 5/4 3/2 7/4 2 pi', '', '', '`[5] ABS-SiNE, EVEN PERiODS ONLY (EPO)`', '', ' ', ' ³', ' ³', ' ³ /\ /\ /\ /\', ' ³/ \ / \ / \ / \', ' ÄÅÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄ', ' ³', ' ³ 1/4 1/2 3/4 1 5/4 3/2 7/4 2 pi', ' ³', ' ³', '', '', '`[6] SQUARE`', '', ' ', ' ³', ' ³', ' Ã-----------¿ Ú-----------¿', ' ñ ñ ñ ñ', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³ ñ ñ ñ ñ', ' ³ À-----------Ù À-----------Ù', ' ³', ' ³ 1/2 1 3/2 2 pi', '', '', '`[7] DERiVED SQUARE`', '', ' ', ' ³', ' ³', ' ñ\__ ñ\__', ' ñ ÄÄÄ__ ñ ÄÄ__', ' ÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄ', ' ³ ÄÄÄ___ ñ ÄÄ____ ñ', ' ³ \ñ \ñ', ' ³', ' ³ 1/2 1 3/2 2 pi', '', '', '~Key scaling level (KSL)~', 'When set, makes the sound softer at higher frequencies.', 'With musical instruments, volume decreases as pitch increases.', 'Level key scaling values are used to simulate this effect.', 'If any (not zero), the diminishing factor can be 1.5 dB/octave,', '3.0 dB/octave, or 6.0 dB/octave.', '', '~Panning~', 'Gives you ability of controlling output, going to left or right channel,', 'standing in the middle respectively.', 'The parameter corresponds either with carrier and modulator, therefore', 'it is listed only once (within the carrier slot).', '', '~Fine-tune~', 'This is not a hardware parameter.', 'Ranges from -127 to 127, it indicates the number of frequency units', 'shifted up or down for any note playing with the corresponding instrument.', 'The parameter corresponds either with carrier and modulator, therefore', 'it is listed only once (within the carrier slot).', '', '~Feedback strength~', 'Ranges from 0 to 7, it indicates the modulation depth', 'for the modulator slot FM feedback.', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿', '³ `FEEDBACK` º `[0]` ³ `[1]` ³ `[2]` ³ `[3]` ³ `[4]` ³ `[5]` ³ `[6]` ³ `[7]` ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄ´', '³ `MODULATiON` º 0 ³1/16 ³ 1/8 ³ 1/4 ³ 1/2 ³ 1 ³ 2 ³ 4 ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÙ', '', 'The parameter corresponds either with carrier and modulator, therefore', 'it is listed only once (within the carrier slot).', '', '~Connection type~', 'Frequency modulation means that the modulator slot modulates the carrier.', 'Additive synthesis means that both slots produce sound on their own.', '', '`[FM] FREQUENCY MODULATiON`', '', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³ ÉÍÍÍÍ»', ' P1 ÄÄ(+)Äĺ MO ÇÄÄÁÄÄ(+)Äĺ CA ÇÄÄ OUT', ' ÈÍÍÍͼ  ÈÍÍÍͼ', ' ³', '', ' P2', '', '`[ADDiTiVE SYNTHESiS] AM`', '', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³', ' P1 ÄÄ(+)Äĺ MO ÇÄÄÁÄÄÄÄ¿', ' ÈÍÍÍͼ ³', ' ', ' (+)ÄÄ OUT', ' ', ' ÉÍÍÍÍ» ³', ' P2 ÄÄÄÄÄÄÄĺ CA ÇÄÄÄÄÄÄÄÙ', ' ÈÍÍÍͼ', '', 'The parameter corresponds either with carrier and modulator, therefore', 'it is listed only once (within the carrier slot).', 'This parameter is also very important when making 4-op instruments,', 'because the combination of two instrument connections specifies', 'the connection of the 4-op instrument as shown below:', '', 'ÚÄÄÄÄÄÄÄÄÄÄÄÄÒÄÄÄÄÂÄÄÄÄÂÄÄÄÄÂÄÄÄÄ¿', '³ `SLOT` º M1 ³ C1 ³ M2 ³ C2 ³', 'ÃÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄ´', '³ `OPERATOR` º 1 ³ 2 ³ 3 ³ 4 ³', 'ÀÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÙ', '', '', '`[FM/FM]`', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³ ÉÍÍÍÍ» ÉÍÍÍÍ» ÉÍÍÍÍ»', ' P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄ(+)Äĺ C1 ÇÄÄ(+)Äĺ M2 ÇÄÄ(+)Äĺ C2 ÇÄÄ OUT', ' ÈÍÍÍͼ  ÈÍÍÍͼ  ÈÍÍÍͼ  ÈÍÍÍͼ', ' ³ ³ ³', '', ' P2 P3 P4', '', '`[FM/AM]` ~(*)~', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³ ÉÍÍÍÍ»', ' P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄ(+)Äĺ C1 ÇÄÄÄÄ¿', ' ÈÍÍÍͼ  ÈÍÍÍͼ ³', ' ³ ³', ' ', ' P2 (+)ÄÄ OUT', ' ', ' ³', ' ÉÍÍÍÍ» ÉÍÍÍÍ» ³', ' P3 ÄÄÄÄÄÄÄĺ M2 ÇÄÄÄÄÄ(+)Äĺ C2 ÇÄÄÄÄÙ', ' ÈÍÍÍͼ  ÈÍÍÍͼ', ' ³', '', ' P4', '', '`[AM/FM]` ~(*)~', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³', ' P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ÈÍÍÍͼ ³', ' ³', ' ³', ' ³', ' ÉÍÍÍÍ» ÉÍÍÍÍ» ÉÍÍÍÍ» ', ' P2 ÄÄÄÄÄÄÄĺ C1 ÇÄÄÄÄÄ(+)Äĺ M2 ÇÄÄ(+)Äĺ C2 ÇÄÄ(+)ÄÄ OUT', ' ÈÍÍÍͼ  ÈÍÍÍͼ  ÈÍÍÍͼ', ' ³ ³', '', ' P3 P4', '', '`[AM/AM]`', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ³ ³', '  ÉÍÍÍÍ» ³', ' P1 ÄÄ(+)Äĺ M1 ÇÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', ' ÈÍÍÍͼ ³', ' ³', ' ³', ' ³', ' ÉÍÍÍÍ» ÉÍÍÍÍ» ', ' P2 ÄÄÄÄÄÄÄÄĺ C1 ÇÄÄÄÄÄ(+)Äĺ M2 ÇÄÄ(+)ÄÄ OUT', ' ÈÍÍÍͼ  ÈÍÍÍͼ ', ' ³ ³', ' ³', ' P3 ³', ' ÉÍÍÍÍ» ³', ' P4 ÄÄÄÄÄÄÄĺ C2 ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', ' ÈÍÍÍͼ', '', '', '~(*)~ `REMARK ABOUT  CONNECTiONS FM/AM AND AM/FM`', 'Please note, that since order of  channels is (hardware-wise) õ and ô,', 'these two instrument connections are swapped.', 'The preview diagrams in the Instrument Editor window show actual order,', 'but here this information is kept in conformity with the official', 'Yamaha YMF262 data specification to prevent further confusion.', '', '', '~Tremolo (Amplitude modulation)~', 'When set, turns tremolo (volume vibrato) ON for the corresponding slot.', 'The repetition rate is 3.7®, the depth is optional (1dB/4.8dB).', '', '~Vibrato~', 'When set, turns frequency vibrato ON for the corresponding slot.', 'The repetition rate is 6.1®, the depth is optional (7%/14%).', '', '~Key scale rate (KSR)~', 'When set, makes the sound shorter at higher frequencies.', 'With normal musical instruments, the attack and decay rate becomes faster', 'as the pitch increases. The key scale rate controls simulation of', 'this effect. An offset (rof) is added to the individual attack, decay,', 'and release rates depending on the following formula:', '', 'actual_rate = (rate  4) + rof', '', 'The "rof" values for corresponding "rate" value and KSR state are shown', 'in the following table:', '', 'ÚÄÄÄÄÄÄÄÄÒÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿', '³ `%rate%` º 0 ³ 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ³ 8 ³ 9 ³ A ³ B ³ C ³ D ³ E ³ F ³', 'ÆÍÍÍÍÍÍÍÍÎÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍÍØÍÍ͵', '³ `[OFF]` º 0 ³ 0 ³ 0 ³ 0 ³ 1 ³ 1 ³ 1 ³ 1 ³ 2 ³ 2 ³ 2 ³ 2 ³ 3 ³ 3 ³ 3 ³ 3 ³', 'ÃÄÄÄÄÄÄÄÄ×ÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄÅÄÄÄ´', '³ `[ON]` º 0 ³ 1 ³ 2 ³ 3 ³ 4 ³ 5 ³ 6 ³ 7 ³ 8 ³ 9 ³ A ³ B ³ C ³ D ³ E ³ F ³', 'ÀÄÄÄÄÄÄÄÄÐÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ', '', '~Sustain (Envelope generator type)~', 'When set, the sustain level of the voice is maintained until released.', 'When clear, the sound begins to decay immediately after hitting', 'the sustain phase.', '', '`[OFF]` /\ DR', ' / \', ' / ...\...SL', ' AR / \', ' / \ RR', ' / \', ' _ _/ \_ _ _', ' .', ' :', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ', ' ÄÄÄÙ KEY ON', '', '', '`[ON]` /\ DR', ' / \ SL', ' / \ _ _ _ _ _', ' AR / \', ' / : \ RR', ' / : \', ' _ _/ : \_ _ _', ' . :', ' : :', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ KEY OFF', ' ÄÄÄÙ KEY ON ÀÄÄÄÄÄÄÄÄÄÄÄÄ', '', '', '~Frequency data multiplier~', 'Sets the multiplier for the frequency data specified by block and', 'F-number. This multiplier is applied to the FM carrier or modulation', 'frequencies. The multiplication factor and corresonding harmonic types are', 'shown in the following table:', '', 'ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿', '³ `MULT.` ³ `` ³ `HARMONiC` ³', 'ÆÍÍÍÍÍÍÍØÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͵', '³ `[0]` ³ 0.5 ³ 1 octave below ³', '³ `[1]` ³ 1 ³ at the voice''s specified frequency ³', '³ `[2]` ³ 2 ³ 1 octave above ³', '³ `[3]` ³ 3 ³ 1 octave and a 5th above ³', '³ `[4]` ³ 4 ³ 2 octaves above ³', '³ `[5]` ³ 5 ³ 2 octaves and a Major 3rd above ³', '³ `[6]` ³ 6 ³ 2 octaves and a 5th above ³', '³ `[7]` ³ 7 ³ 2 octaves and a Minor 7th above ³', '³ `[8]` ³ 8 ³ 3 octaves above ³', '³ `[9]` ³ 9 ³ 3 octaves and a Major 2nd above ³', '³ `[A]` ³ 10 ³ 3 octaves and a Major 3rd above ³', '³ `[B]` ³ 10 ³ ... ³', '³ `[C]` ³ 12 ³ 3 octaves and a 5th above ³', '³ `[D]` ³ 12 ³ ... ³', '³ `[E]` ³ 15 ³ 3 octaves and a Major 7th above ³', '³ `[F]` ³ 15 ³ ... ³', 'ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ', '', '@topic:effects_page1', 'ÍËÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍËÍ', ' º `SUPPORTED EFFECTS` º', 'ÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ', '`0`xy ÄÄ ARPEGGiO xy=1st_tone|2nd_tone [1-F]', '`1`xx ÄÄ FREQUENCY SLiDE UP xx=speed_of_slide [1-FF]', '`2`xx ÄÄ FREQUENCY SLiDE DOWN xx=speed_of_slide [1-FF]', '`3`xx ÄÄ TONE PORTAMENTO xx=speed_of_slide [1-FF] ~C~', '`4`xy ÄÄ ViBRATO xy=speed|depth [1-F] ~C~', '`5`xy ÄÄ ~3xx~ & VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`6`xy ÄÄ ~4xy~ & VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`7`xx ÄÄ FiNE FREQUENCY SLiDE UP xx=speed_of_slide [1-FF]', '`8`xx ÄÄ FiNE FREQUENCY SLiDE DOWN xx=speed_of_slide [1-FF]', '`9`xx ÄÄ SET MODULATOR VOLUME xx=volume_level [0-3F]', '`A`xy ÄÄ VOLUME SLiDE xy=up_speed|down_speed [1-F]', '`B`xx ÄÄ POSiTiON JUMP xx=position_in_order [0-7F]', '`C`xx ÄÄ SET iNSTRUMENT VOLUME xx=volume_level [0-3F]', '`D`xx ÄÄ PATTERN BREAK xx=line_in_next_pattern [0-FF]', '`E`xx ÄÄ SET TEMPO xx=bpm_in_® [1-FF]', '`F`xx ÄÄ SET SPEED xx=frames_per_row [1-FF]', '`G`xy ÄÄ ~3xx~ & FiNE VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`H`xy ÄÄ ~4xy~ & FiNE VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`I`xx ÄÄ SET CARRiER VOLUME xx=volume_level [0-3F]', '`J`xy ÄÄ SET WAVEFORM xy=carrier|modulator [0-7,F=NiL]', '@topic:effects_page2', '`K`xy ÄÄ FiNE VOLUME SLiDE xy=up_speed|down_speed [1-F]', '`L`xx ÄÄ RETRiG NOTE xx=interval [1-FF]', '`M`xy ÄÄ TREMOLO xy=speed|depth [1-F] ~C~', '`N`xy ÄÄ TREMOR xy=on_time|off_time [1-F]', '`O`xy ÄÄ ~0xy~ & VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`P`xy ÄÄ ~0xy~ & FiNE VOLUME SLiDE xy=up_speed|down_speed [1-F] ~C~', '`Q`xy ÄÄ MULTi RETRiG NOTE xy=interval|vol_change [1-F]', '', '`Q`x? `0` = None `8` = Unused', ' `1` = -1 `9` = +1', ' `2` = -2 `A` = +2', ' `3` = -4 `B` = +4', ' `4` = -8 `C` = +8', ' `5` = -16 `D` = +16', ' `6` = 2/3 `E` = 3/2', ' `7` = 1/2 `F` = 2', '', '`R`xy ÄÄ ~1xx~ ¿ ¿', '`S`xy ÄÄ ~2xx~ ö & ö', '`T`xy ÄÄ ~7xx~ ø VOLUME SLiDE ö', '`U`xy ÄÄ ~8xx~ Ù ö', '`V`xy ÄÄ ~1xx~ ¿ ø xy=up_speed|down_speed [1-F] ~C~', '`W`xy ÄÄ ~2xx~ ö & ö', '`X`xy ÄÄ ~7xx~ ø FiNE VOLUME SLiDE ö', '`Y`xy ÄÄ ~8xx~ Ù Ù', '', '@topic:effects_page3', '`Z`?? `0`x SET TREMOLO DEPTH x=1dB/4.8dB [0-1] ~I~', ' `1`x SET ViBRATO DEPTH x=7%/14% [0-1] ~I~', ' `2`x SET ATTACK RATE ¿ x=attack_rate [0-F] ~I~', ' `3`x SET DECAY RATE ö MOD. x=decay_rate [0-F] ~I~', ' `4`x SET SUSTAiN LEVEL ø x=sustain_level [0-F] ~I~', ' `5`x SET RELEASE RATE Ù x=release_rate [0-F] ~I~', ' `6`x SET ATTACK RATE ¿ x=attack_rate [0-F] ~I~', ' `7`x SET DECAY RATE ö CAR. x=decay_rate [0-F] ~I~', ' `8`x SET SUSTAiN LEVEL ø x=sustain_level [0-F] ~I~', ' `9`x SET RELEASE RATE Ù x=release_rate [0-F] ~I~', ' `A`x SET FEEDBACK STRENGTH x=feedback_strength [0-7] ~I~', ' `B`x SET PANNiNG POSiTiON x=panning_position [0-2] ~I~', ' `C`x PATTERN LOOP x=parameter [0-F]', ' `D`x RECURSiVE PATTERN LOOP x=parameter [0-F]', ' `E`x EXTENDED COMMANDS (1)', ' `F`x EXTENDED COMMANDS (2)', '', '`ZB`? `0` = Center', ' `1` = Left', ' `2` = Right', '`ZC`?', '`ZD`? `0` = Set loopback point', ' x = Loop ~x~ times', '', '@topic:effects_page4', '`ZE`? `0`/`1` DiSABLE/ENABLE MACRO KEY-OFF LOOP', ' `2`/`3` DiSABLE/ENABLE RESTART ENVELOPE WiTH TONE PORTAMENTO', ' `4` PERFORM RESTART ENVELOPE', ' `5`/`6` DiSABLE/ENABLE '#4#3' TRACK VOLUME LOCK', ' `7` PERFORM ~BPM SLiDE~ USiNG `~>~`~xx~ AND `~<~`~xx~ COMMANDS', '', '`ZF`? `0` RELEASE SUSTAiNiNG SOUND', ' `1` RESET iNSTRUMENT VOLUME', ' `2`/`3` LOCK/UNLOCK TRACK VOLUME', ' `4`/`5` LOCK/UNLOCK VOLUME PEAK', ' `6` TOGGLE MODULATOR VOLUME SLiDES', ' `7` TOGGLE CARRiER VOLUME SLiDES', ' `8` TOGGLE DEFAULT VOLUME SLiDES', ' `9`/`A` LOCK/UNLOCK TRACK PANNiNG', ' `B` ViBRATO OFF', ' `C` TREMOLO OFF', ' `D` FORCE FiNE ViBRATO', ' FORCE FiNE GLOBAL FREQ. SLiDE', ' `E` FORCE FiNE TREMOLO', ' FORCE EXTRA FiNE GLOBAL FREQ. SLiDE', ' `F` FORCE NO RESTART FOR MACRO TABLES', '', '@topic:effects_page5', '`#`?? `0`x SET CONNECTiON TYPE x=FM/AM [0-1] ~I~', ' `1`x SET MULTiPLiER ¿ x=multiplier [0-F] ~I~', ' `2`x SET KSL ö x=scaling_level [0-3] ~I~', ' `3`x SET TREMOLO ö MOD. x=off/on [0-1] ~I~', ' `4`x SET ViBRATO ø x=off/on [0-1] ~I~', ' `5`x SET KSR ö x=off/on [0-1] ~I~', ' `6`x SET SUSTAiN Ù x=off/on [0-1] ~I~', ' `7`x SET MULTiPLiER ¿ x=multiplier [0-F] ~I~', ' `8`x SET KSL ö x=scaling_level [0-3] ~I~', ' `9`x SET TREMOLO ö CAR. x=off/on [0-1] ~I~', ' `A`x SET ViBRATO ø x=off/on [0-1] ~I~', ' `B`x SET KSR ö x=off/on [0-1] ~I~', ' `C`x SET SUSTAiN Ù x=off/on [0-1] ~I~', '', '@topic:effects_page6', '`&`?? `0`x PATTERN DELAY (FRAMES) x=interval [1-F]', ' `1`x PATTERN DELAY (ROWS) x=interval [1-F]', ' `2`x NOTE DELAY x=interval [1-F]', ' `3`x NOTE CUT x=interval [1-F]', ' `4`x FiNE-TUNE UP x=freq_shift [1-F]', ' `5`x FiNE-TUNE DOWN x=freq_shift [1-F]', ' `6`x GLOBAL VOLUME SLiDE UP x=speed_of_slide [1-F]', ' `7`x GLOBAL VOLUME SLiDE DOWN x=speed_of_slide [1-F]', ' `8`x FiNE ~&6x~ x=speed_of_slide [1-F]', ' `9`x FiNE ~&7x~ x=speed_of_slide [1-F]', ' `A`x EXTRA FiNE ~&6x~ x=speed_of_slide [1-F]', ' `B`x EXTRA FiNE ~&7x~ x=speed_of_slide [1-F]', ' `C`x EXTRA FiNE VSLiDE UP x=speed_of_slide [1-F]', ' `D`x EXTRA FiNE VSLiDE DOWN x=speed_of_slide [1-F]', ' `E`x EXTRA FiNE FSLiDE UP x=speed_of_slide [1-F]', ' `F`x EXTRA FiNE FSLiDE DOWN x=speed_of_slide [1-F]', '', '@topic:effects_page7', '`$`xy ÄÄ EXTRA FiNE ARPEGGiO xy=1st_tone|2nd_tone [1-F]', '`@@~xy ÄÄ EXTRA FiNE ViBRATO xy=speed|depth [1-F] ~C~', '`^`xy ÄÄ EXTRA FiNE TREMOLO xy=speed|depth [1-F] ~C~', '`!`xx ÄÄ SWAP ARPEGGiO TABLE xx=table_number [0-FF]', '`@`xx ÄÄ SWAP ViBRATO TABLE xx=table_number [0-FF]', '`=`xx ÄÄ FORCE iNSTRUMENT VOLUME xx=volume_level [0-3F]', '`%`xx ÄÄ SET GLOBAL VOLUME xx=volume_level [0-3F]', '`>`xx ÄÄ GLOBAL FREQ. SLiDE UP xx=speed_of_slide [1-FF]', '`<`xx ÄÄ GLOBAL FREQ. SLiDE DOWN xx=speed_of_slide [1-FF]', '`@@`xx ÄÄ SET CUSTOM SPEED TABLE xx=parameter [0-FF]', '', '`@@`?? `00` Reset default speed table', ' `01`-`FF` Calculate custom speed table with parameters', ' `table size`, `maximum value` and `processing speed factor`', '', ' ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ¿', ' ³ PARAMETER ³ `SiZE` ³ `MAX.` ³ `FACTOR` ³', ' ÆÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍØÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍ͵', ' ³ `[01]`..`[EF]` ³ 32 ³ ~01~..~EF~ ³ '#7'1 ³', ' ³ `[F0]`..`[F3]` ³ ~32~ ³ FF ³ ~'#7'1~..~'#7'4~ ³', ' ³ `[F4]`..`[F7]` ³ ~64~ ³ FF ³ ~'#7'1~..~'#7'4~ ³', ' ³ `[F8]`..`[FB]` ³ ~128~ ³ FF ³ ~'#7'1~..~'#7'4~ ³', ' ³ `[FC]`..`[FF]` ³ ~256~ ³ FF ³ ~'#7'1~..~'#7'4~ ³', ' ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÙ', '', '`FURTHER NOTES:`', '', '1) Effects marked as ~C~ in the above list of commands can be continued', ' in subsequent lines by setting the parameter value to 0.', '', '2) Effects marked as ~I~ in the above list of commands do apply', ' to currently played instrument only.', '', 'For detailed information on effect commands, see the ~adtrack2.doc~ file.', '', '', ' ÄÂÄ ÄÄ', {$IFDEF GO32V2} ' /´DLiB³R/´CK3R ³³ G3', {$ELSE} ' /´DLiB³R/´CK3R ³³ SDL', {$ENDIF} ' ³ ³ ÄÄ', ' '+at2ver, '', '', '`Get the latest version from:`', 'http://www.adlibtracker.net', '', '`Contact information:`', 'E-MAiL subz3ro.altair@gmail.com', 'iCQ# 58622796', '', '`Credits:`', {$IFDEF GO32V2} 'Florian Klaempfl and others [Free Pascal Compiler 2.6.4]', 'Karoly Balogh [GO32V2 Timer Services Unit 1.1.0]', 'Haruhiko Okomura & Haruyasu Yoshizaki [LZH algorithm]', 'Markus Oberhumer, Laszlo Molnar & John Reiser [UPX 3.91d]', {$ELSE} 'Florian Klaempfl and others [Free Pascal Compiler 2.6.4]', 'Simple DirectMedia Layer [SDL 1.2.15]', 'Daniel F. Moisset [SDL4Freepascal-1.2.0.0]', 'Alexey Khokholov [NukedOPL3 1.6]', 'Haruhiko Okomura & Haruyasu Yoshizaki [LZH algorithm]', 'Markus Oberhumer, Laszlo Molnar & John Reiser [UPX 3.91w]', {$ENDIF} '', '`Honest ''thank you'' to the following people:`', 'Slawomir Bubel (Malfunction/Altair), Daniel Illgen (insane/Altair),', 'Mikkel Hastrup (encore), Florian Jung (Windfisch), Dmitry Smagin,', 'David Cohen (Diode Milliampere), Nick Balega,', 'Cecill Etheredge (ijsf), Sven Renner (NeuralNET),', 'Tyler Montbriand (Corona688), Janwillem Jagersma, PissMasterPlus,', 'and Mr. Maan M. Hamze :-)', '', '`Greetz fly to the following people:`', 'Dragan Espenschied (drx/Bodenstandig 2000), Carl Peczynski (OxygenStar),', 'Hubert Lamontagne (Madbrain), Jason Karl Warren (Televicious), kvee,', 'Vojta Nedved (nula), and all members of AT2 user group on Facebook'); procedure HELP(topic: String); procedure ShowStartMessage; implementation uses StrUtils, AdT2unit,AdT2sys,AdT2keyb,AdT2data, TxtScrIO,StringIO,DialogIO,ParserIO; const key_comment_B = ' C D E F G A B C D E F G A B C D E'; key_comment_H = ' C D E F G A H C D E F G A H C D E'; const shift_f5_1 = '~[Shift] F5~ @F5 with Trace'; shift_f8_1 = '~[Shift] F8~ @F8 with Trace'; shift_f9_1 = '~[Shift] F9~ @F9 with Trace'; alt_f8_1 = '~[Alt] F8~ @F8 à without synchronization'; const shift_f5_2 = '~[Shift] F5~ @F5 with no Trace'; shift_f8_2 = '~[Shift] F8~ @F8 with no Trace'; shift_f9_2 = '~[Shift] F9~ @F9 with no Trace'; alt_f8_2 = '~[Alt] F8~ @F8 à with synchronization'; procedure HELP(topic: String); var spec_attr_table: array[1..255] of Byte; temps: String; page,temp,fkey: Word; temp2: Byte; xstart,ystart,ypos,page_len: Byte; mpos: Byte; mchr: Char; new_atr1, new_atr2, new_atr3: Byte; temp_pos_atr1: Byte; temp_pos_atr2: Byte; procedure ListCStr(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3: Byte); begin temp_pos_atr1 := Pos('@@attr:',str); temp_pos_atr2 := Pos('@@spec_attr:',str); If (Pos('~@@',str) <> 0) then begin mpos := Pos('~@@',str); mchr := str[mpos+3]; Delete(str,mpos,4); Insert(' ',str,mpos); ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), atr1,atr2,atr3); ShowStr(dest,x+mpos-1,y,mchr,atr2); end else If (Pos('`@@',str) <> 0) then begin mpos := Pos('`@@',str); mchr := str[mpos+3]; Delete(str,mpos,4); Insert(' ',str,mpos); ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), atr1,atr2,atr3); ShowStr(dest,x+mpos-1,y,mchr,atr3); end else If (temp_pos_atr1 <> 0) and SameName('@@attr:??,??,??@@',Copy(str,temp_pos_atr1,17)) then begin new_atr1 := Str2num(Copy(str,temp_pos_atr1+7,2),16); If (new_atr1 = 0) then new_atr1 := atr1; new_atr2 := Str2num(Copy(str,temp_pos_atr1+10,2),16); If (new_atr2 = 0) then new_atr2 := atr2; new_atr3 := Str2num(Copy(str,temp_pos_atr1+13,2),16); If (new_atr3 = 0) then new_atr3 := atr3; Delete(str,temp_pos_atr1,17); ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), new_atr1,new_atr2,new_atr3); end else If (temp_pos_atr2 <> 0) and SameName('@@spec_attr:??@@',Copy(str,temp_pos_atr2,16)) then begin temp2 := Str2num(Copy(str,temp_pos_atr2+12,2),16); If (temp2 = 0) or (spec_attr_table[temp2] = 0) then new_atr3 := atr3 else new_atr3 := spec_attr_table[temp2]; Delete(str,temp_pos_atr2,16); ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), atr1,atr2,new_atr3); end else ShowC3Str(dest,x,y, ExpStrR(str,74+Length(str)-C3StrLen(str),' '), atr1,atr2,atr3); end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2TEXT.PAS:Help'; {$ENDIF} ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; // assign special attribute values FillChar(spec_attr_table,SizeOf(spec_attr_table),0); spec_attr_table[1] := main_behavior SHL 4 AND $0f0; spec_attr_table[2] := main_hi_stat_line SHL 4 AND $0f0; HideCursor; page_len := work_MaxLn-5; centered_frame(xstart,ystart,77,page_len+2,' HELP ', help_background+help_border, help_background+help_title, frame_double); page := 1; While (page <= HELP_LINES-page_len) and ((Copy(help_data[page],1,6) <> '@topic') or (Copy(help_data[page],8,Length(help_data[page])-7) <> topic)) do Inc(page); If (page < 1) then page := 1; If (page > HELP_LINES-page_len) then page := HELP_LINES-page_len; Repeat If (page > 1) then temps := '' else temps := '-'; If (page < HELP_LINES-page_len) then temps := temps+'' else temps := temps+'-'; ShowCStr(screen_ptr,xstart+1+74-Length(temps),ystart+page_len+2, '[~'+temps+'~]', help_background+help_border, help_background+help_indicators); ypos := ystart+1; temp := page; While (ypos <= ystart+page_len+1) and (temp <= HELP_LINES) do begin If (Copy(help_data[temp],1,6) <> '@topic') and (Copy(help_data[temp],1,6) <> '@input') then begin If (Copy(help_data[temp],1,3) <> ' º ') then ListCStr(screen_ptr,xstart+2,ypos, help_data[temp], help_background+help_text, help_background+help_keys, help_background+help_hi_text) else ListCStr(screen_ptr,xstart+2,ypos, help_data[temp], help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'key_comment') then begin If NOT use_H_for_B then ListCStr(screen_ptr,xstart+2,ypos, key_comment_B, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, key_comment_H, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'shift_f5') then begin If NOT trace_by_default then ListCStr(screen_ptr,xstart+2,ypos, shift_f5_1, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, shift_f5_2, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'shift_f8') then begin If NOT trace_by_default then ListCStr(screen_ptr,xstart+2,ypos, shift_f8_1, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, shift_f8_2, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'shift_f9') then begin If NOT trace_by_default then ListCStr(screen_ptr,xstart+2,ypos, shift_f9_1, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, shift_f9_2, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end else If (Copy(help_data[temp],8, Length(help_data[temp])-7) = 'alt_f8') then begin If NOT nosync_by_default then ListCStr(screen_ptr,xstart+2,ypos, alt_f8_1, help_background+help_text, help_background+help_keys, help_background+help_topic) else ListCStr(screen_ptr,xstart+2,ypos, alt_f8_2, help_background+help_text, help_background+help_keys, help_background+help_topic); Inc(ypos); end; Inc(temp); end; fkey := getkey; Case fkey of kUP: begin If (page > 1) then Dec(page); If (Copy(help_data[page-1],1,6) = '@topic') and (page > 1) then Dec(page); end; kDOWN: begin If (Copy(help_data[page],1,6) = '@topic') and (page < HELP_LINES-page_len) then Inc(page); If (page < HELP_LINES-page_len) then Inc(page); end; kPgUP: begin If (page > page_len) then Dec(page,page_len) else page := 1; If (Copy(help_data[page-1],1,6) = '@topic') and (page > 1) then Dec(page); end; kPgDOWN: begin If (Copy(help_data[page],1,6) = '@topic') and (page < HELP_LINES-page_len) then Inc(page); If (page+page_len <= HELP_LINES-page_len) then Inc(page,page_len) else page := HELP_LINES-page_len; end; kHOME: page := 1; kEND: page := HELP_LINES-page_len; end; // draw_screen; until (fkey = kENTER) or (fkey = kESC) or _force_program_quit; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+77+2; move_to_screen_area[4] := ystart+page_len+1; move2screen; end; {$IFDEF GO32V2} procedure C3WriteLn(str: String; atr1,atr2,atr3: Byte); begin ShowC3Str(screen_ptr,WhereX,WhereY, str, atr1,atr2,atr3); WriteLn; end; {$ELSE} procedure C3WriteLn(posX,posY: Byte; str: String; atr1,atr2,atr3: Byte); begin ShowC3Str(screen_ptr,posX,posY, str, atr1,atr2,atr3); end; {$ENDIF} procedure ShowStartMessage; begin {$IFDEF GO32V2} WriteLn; WriteLn(_ADT2_TITLE_STRING_,' coded by subz3ro/Altair'); WriteLn(' ',at2ver,' ',at2date,' ',at2link,''); WriteLn; {$ENDIF} end; end. adlibtracker2-2.4.24/adt2extn.pas0000644000000000000000000110776213411003760015261 0ustar rootroot// 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 AdT2extn; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface const remap_mtype: Byte = 1; remap_ins1: Byte = 1; remap_ins2: Byte = 1; remap_selection: Byte = 1; rearrange_selection: Byte = 1; replace_selection: Byte = 1; replace_prompt: Boolean = FALSE; replace_data: Record event_to_find: Record note: String[3]; inst: String[2]; fx_1: String[3]; fx_2: String[3]; end; new_event: Record note: String[3]; inst: String[2]; fx_1: String[3]; fx_2: String[3]; end; end = ( event_to_find: (note: '???'; inst: '??'; fx_1: '???'; fx_2: '???'); new_event: (note: '???'; inst: '??'; fx_1: '???'; fx_2: '???')); var fkey: Word; var progress_xstart,progress_ystart: Byte; progress_num_steps: Byte; progress_step: Byte; progress_value: Dword; progress_old_value,progress_new_value: Byte; var tracing_block_pattern, tracing_block_xend, tracing_block_yend: Byte; const copypos1: Byte = 1; copypos2: Byte = 1; copypos3: Byte = 1; copypos4: Byte = 1; clearpos: Byte = 1; pattern_list__page: Byte = 1; pattern2use: Byte = BYTE(NOT 0); type tTRANSPOSE_TYPE = (ttTransposeUp,ttTransposeDown, ttTransposeCurrentIns,ttTransposeAllIns); function _patts_marked: Byte; procedure nul_volume_bars; procedure transpose_custom_area(type1,type2: tTRANSPOSE_TYPE; patt0,patt1,track0,track1,line0,line1: Byte; factor: Byte); procedure TRANSPOSE; procedure REMAP; procedure REARRANGE; procedure REPLACE; procedure POSITIONS_reset; procedure DEBUG_INFO; procedure LINE_MARKING_SETUP; procedure OCTAVE_CONTROL; procedure SONG_VARIABLES; procedure FILE_save(ext: String); function FILE_open(masks: String; loadBankPossible: Boolean): Byte; procedure NUKE; procedure MESSAGE_BOARD; procedure QUIT_request; procedure show_progress(value: Longint); overload; procedure show_progress(value,refresh_dif: Longint); overload; implementation uses {$IFNDEF UNIX} CRT, {$ENDIF} {$IFNDEF GO32V2} SDL_Timer, {$ENDIF} StrUtils, AdT2opl3,AdT2sys,AdT2keyb,AdT2unit,AdT2ext2,AdT2ext3,AdT2ext4,AdT2ext5,AdT2text,AdT2pack, StringIO,DialogIO,ParserIO,TxtScrIO,MenuLib1,MenuLib2; function _patts_marked: Byte; var temp, result: Byte; begin result := 0; For temp := 0 to $7f do If (songdata.pattern_names[temp][1] = #16) then Inc(result); _patts_marked := result; end; procedure nul_volume_bars; var chan: Byte; begin For chan := chan_pos to chan_pos+MAX_TRACKS-1 do If channel_flag[chan] then show_str(08+(chan-PRED(chan_pos)-1)*15,MAX_PATTERN_ROWS+11, ExpStrR('',14,#205), pattern_bckg+pattern_border); end; const transp_menu2: Boolean = FALSE; transp_pos1: Byte = 1; transp_pos2: Byte = 1; procedure transpose_custom_area(type1,type2: tTRANSPOSE_TYPE; patt0,patt1,track0,track1,line0,line1: Byte; factor: Byte); var skip_all,erase_all: Boolean; _1st_choice: Byte; _break,_continue: Boolean; chunk: tCHUNK; temp,temp1,temp2,temp3: Byte; status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:transpose_custom_area'; {$ENDIF} status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; PATTERN_position_preview(BYTE_NULL,BYTE_NULL,BYTE_NULL,0); _1st_choice := BYTE_NULL; _break := FALSE; _continue := TRUE; Case type1 of ttTransposeUp: For temp3 := patt0 to patt1 do begin For temp2 := track0 to track1 do begin For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If NOT (type2 = ttTransposeCurrentIns) then begin If NOT (chunk.note+factor <= 12*8+1) and NOT (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' TRANSPOSE ',1); _1st_choice := temp; If (dl_environment.keystroke <> kESC) and (_1st_choice <> 5) then begin _break := TRUE; BREAK; end else begin _break := TRUE; _continue := FALSE; BREAK; end; end; end else If NOT (chunk.note < 12*8+1) and NOT (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' TRANSPOSE ',1); _1st_choice := temp; If (dl_environment.keystroke <> kESC) and (_1st_choice <> 5) then begin _break := TRUE; BREAK; end else begin _break := TRUE; _continue := FALSE; BREAK; end; end; end; If _break then BREAK; end; If _break then BREAK; end; ttTransposeDown: For temp3 := patt0 to patt1 do begin For temp2 := track0 to track1 do begin For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If NOT (type2 = ttTransposeCurrentIns) then begin If NOT (chunk.note >= factor+1) and NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' TRANSPOSE ',1); _1st_choice := temp; If (dl_environment.keystroke <> kESC) and (_1st_choice <> 5) then begin _break := TRUE; BREAK; end else begin _break := TRUE; _continue := FALSE; BREAK; end; end; end else If NOT (chunk.note >= factor+1) and NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' TRANSPOSE ',1); _1st_choice := temp; If (dl_environment.keystroke <> kESC) and (_1st_choice <> 5) then begin _break := TRUE; BREAK; end else begin _break := TRUE; _continue := FALSE; BREAK; end; end; end; If _break then BREAK; end; If _break then BREAK; end; end; _break := FALSE; skip_all := FALSE; erase_all := FALSE; If _continue then Case type1 of ttTransposeUp: For temp3 := patt0 to patt1 do begin For temp2 := track0 to track1 do begin For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If NOT (type2 = ttTransposeCurrentIns) then begin If NOT (chunk.note+factor <= 12*8+1) and NOT (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin If (_1st_choice <> BYTE_NULL) then begin Case _1st_choice of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (_1st_choice = 2) then erase_all := TRUE; end; 3, 4: If (_1st_choice = 4) then skip_all := TRUE; end; put_chunk(temp3,temp1,temp2,chunk); _1st_choice := BYTE_NULL; CONTINUE; end; If skip_all then CONTINUE; If erase_all then begin chunk.note := 0; chunk.instr_def := 0; put_chunk(temp3,temp1,temp2,chunk); CONTINUE; end; PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' TRANSPOSE ',1); If (dl_environment.keystroke <> kESC) then begin Case temp of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (temp = 2) then erase_all := TRUE; end; 3, 4: If (temp = 4) then skip_all := TRUE; 5: begin _break := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin Inc(chunk.note,factor); put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note < 12*8+1) and NOT (chunk.note in [fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin If (_1st_choice <> BYTE_NULL) then begin Case _1st_choice of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (_1st_choice = 2) then erase_all := TRUE; end; 3, 4: If (_1st_choice = 4) then skip_all := TRUE; end; put_chunk(temp3,temp1,temp2,chunk); _1st_choice := BYTE_NULL; CONTINUE; end; If skip_all then CONTINUE; If erase_all then begin chunk.note := 0; chunk.instr_def := 0; put_chunk(temp3,temp1,temp2,chunk); CONTINUE; end; PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' TRANSPOSE ',1); If (dl_environment.keystroke <> kESC) then begin Case temp of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (temp = 2) then erase_all := TRUE; end; 3, 4: If (temp = 4) then skip_all := TRUE; 5: begin _break := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin Inc(chunk.note,factor); put_chunk(temp3,temp1,temp2,chunk); end; end; If _break then BREAK; end; If _break then BREAK; end; ttTransposeDown: For temp3 := patt0 to patt1 do begin For temp2 := track0 to track1 do begin For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If NOT (type2 = ttTransposeCurrentIns) then begin If NOT (chunk.note >= factor+1) and NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin If (_1st_choice <> BYTE_NULL) then begin Case _1st_choice of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (_1st_choice = 2) then erase_all := TRUE; end; 3, 4: If (_1st_choice = 4) then skip_all := TRUE; end; put_chunk(temp3,temp1,temp2,chunk); _1st_choice := BYTE_NULL; CONTINUE; end; If skip_all then CONTINUE; If erase_all then begin chunk.note := 0; chunk.instr_def := 0; put_chunk(temp3,temp1,temp2,chunk); CONTINUE; end; PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' TRANSPOSE ',1); If (dl_environment.keystroke <> kESC) then begin Case temp of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (temp = 2) then erase_all := TRUE; end; 3, 4: If (temp = 4) then skip_all := TRUE; 5: begin _break := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) then begin Dec(chunk.note,factor); put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note >= factor+1) and NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin If (_1st_choice <> BYTE_NULL) then begin Case _1st_choice of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (_1st_choice = 2) then erase_all := TRUE; end; 3, 4: If (_1st_choice = 4) then skip_all := TRUE; end; put_chunk(temp3,temp1,temp2,chunk); _1st_choice := BYTE_NULL; CONTINUE; end; If skip_all then CONTINUE; If erase_all then begin chunk.note := 0; chunk.instr_def := 0; put_chunk(temp3,temp1,temp2,chunk); CONTINUE; end; PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'NOTE OVERFLOW$', '~E~RASE$ERASE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' TRANSPOSE ',1); If (dl_environment.keystroke <> kESC) then begin Case temp of 1, 2: begin chunk.note := 0; chunk.instr_def := 0; If (temp = 2) then erase_all := TRUE; end; 3, 4: If (temp = 4) then skip_all := TRUE; 5: begin _break := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end else If NOT (chunk.note in [0,fixed_note_flag+1..fixed_note_flag+12*8+1,BYTE_NULL]) and (chunk.instr_def = current_inst) then begin Dec(chunk.note,factor); put_chunk(temp3,temp1,temp2,chunk); end; end; If _break then BREAK; end; If _break then BREAK; end; end; PATTERN_position_preview(BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; procedure transpose__control_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:transpose__control_proc'; {$ENDIF} If (mn_environment.curr_pos in [1..8]) then begin If (mn_environment.curr_pos in [1..4]) then begin transp_menu_str1[2] := Copy(transp_menu_str1[2],1,18)+transp_mnu_str5[1]; transp_menu_str1[3] := Copy(transp_menu_str1[3],1,18)+transp_mnu_str5[2]; transp_menu_str1[5] := Copy(transp_menu_str1[5],1,37)+transp_mnu_str5[18]; transp_menu_str1[6] := Copy(transp_menu_str1[6],1,18)+transp_mnu_str5[3]; transp_menu_str1[7] := Copy(transp_menu_str1[7],1,18)+transp_mnu_str5[4]; end else begin transp_menu_str1[2] := Copy(transp_menu_str1[2],1,18)+transp_mnu_str5[5]; transp_menu_str1[3] := Copy(transp_menu_str1[3],1,18)+transp_mnu_str5[6]; transp_menu_str1[5] := Copy(transp_menu_str1[5],1,37)+transp_mnu_str5[18]; transp_menu_str1[6] := Copy(transp_menu_str1[6],1,18)+transp_mnu_str5[7]; transp_menu_str1[7] := Copy(transp_menu_str1[7],1,18)+transp_mnu_str5[8]; end; If NOT transp_menu2 then transp_menu_str1[4] := Copy(transp_menu_str1[4],1,37)+transp_mnu_str5[10] else transp_menu_str1[4] := Copy(transp_menu_str1[4],1,37)+transp_mnu_str5[11]; end else begin transp_menu_str1[2] := Copy(transp_menu_str1[2],1,18)+transp_mnu_str5[5]; transp_menu_str1[3] := Copy(transp_menu_str1[3],1,18)+transp_mnu_str5[9]; transp_menu_str1[5] := Copy(transp_menu_str1[5],1,37)+transp_mnu_str5[19]; transp_menu_str1[6] := Copy(transp_menu_str1[6],1,18)+transp_mnu_str5[3]; transp_menu_str1[7] := Copy(transp_menu_str1[7],1,18)+transp_mnu_str5[4]; If NOT transp_menu2 then transp_menu_str1[4] := Copy(transp_menu_str1[4],1,37)+transp_mnu_str5[12] else transp_menu_str1[4] := Copy(transp_menu_str1[4],1,37)+transp_mnu_str5[13]; end; If (mn_environment.curr_pos in [10..17]) then begin If (mn_environment.curr_pos in [10..13]) then begin transp_menu_str1[11] := Copy(transp_menu_str1[11],1,18)+transp_mnu_str5[1]; transp_menu_str1[12] := Copy(transp_menu_str1[12],1,18)+transp_mnu_str5[2]; transp_menu_str1[14] := Copy(transp_menu_str1[14],1,37)+transp_mnu_str5[18]; transp_menu_str1[15] := Copy(transp_menu_str1[15],1,18)+transp_mnu_str5[3]; transp_menu_str1[16] := Copy(transp_menu_str1[16],1,18)+transp_mnu_str5[4]; end else begin transp_menu_str1[11] := Copy(transp_menu_str1[11],1,18)+transp_mnu_str5[5]; transp_menu_str1[12] := Copy(transp_menu_str1[12],1,18)+transp_mnu_str5[6]; transp_menu_str1[14] := Copy(transp_menu_str1[14],1,37)+transp_mnu_str5[18]; transp_menu_str1[15] := Copy(transp_menu_str1[15],1,18)+transp_mnu_str5[7]; transp_menu_str1[16] := Copy(transp_menu_str1[16],1,18)+transp_mnu_str5[8]; end; If NOT transp_menu2 then transp_menu_str1[13] := Copy(transp_menu_str1[13],1,37)+transp_mnu_str5[14] else transp_menu_str1[13] := Copy(transp_menu_str1[13],1,37)+transp_mnu_str5[15]; end else If NOT (transp_menu2 and NOT marking) then begin transp_menu_str1[11] := Copy(transp_menu_str1[11],1,18)+transp_mnu_str5[5]; transp_menu_str1[12] := Copy(transp_menu_str1[12],1,18)+transp_mnu_str5[9]; transp_menu_str1[14] := Copy(transp_menu_str1[14],1,37)+transp_mnu_str5[19]; transp_menu_str1[15] := Copy(transp_menu_str1[15],1,18)+transp_mnu_str5[3]; transp_menu_str1[16] := Copy(transp_menu_str1[16],1,18)+transp_mnu_str5[4]; If NOT transp_menu2 then transp_menu_str1[13] := Copy(transp_menu_str1[13],1,37)+transp_mnu_str5[16] else transp_menu_str1[13] := Copy(transp_menu_str1[13],1,37)+transp_mnu_str5[17]; end; mn_environment.do_refresh := TRUE; mn_environment.refresh; end; procedure TRANSPOSE; var patt0,patt1,track0,track1,line0,line1: Byte; patterns: Byte; old_text_attr: Byte; const factor: array[1..17] of Byte = (1,12,1,12,1,12,1,12,BYTE_NULL, 1,12,1,12,1,12,1,12); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:TRANSPOSE'; {$ENDIF} old_text_attr := mn_setting.text_attr; mn_setting.text_attr := dialog_background+dialog_text; mn_setting.cycle_moves := TRUE; mn_setting.fixed_len := 14; mn_setting.terminate_keys[3] := kTAB; mn_environment.ext_proc := transpose__control_proc; count_patterns(patterns); Repeat If transp_menu2 then begin mn_environment.context := ' TAB '#196#16' PATTERN/SONG '; transp_menu_str1[4] := transp_menu_str4[3]; If marking then begin Move(transp_menu_str2,transp_menu_str1[10],SizeOf(transp_menu_str2)); transp_menu_str1[13] := transp_menu_str4[4]; end else Move(transp_menu_str3,transp_menu_str1[10],SizeOf(transp_menu_str3)); end else begin mn_environment.context := ' TAB '#196#16' TRACK/BLOCK '; Move(transp_menu_str2,transp_menu_str1[10],SizeOf(transp_menu_str2)); transp_menu_str1[4] := transp_menu_str4[1]; transp_menu_str1[13] := transp_menu_str4[2]; end; transpos := Menu(transp_menu_str1,01,01,transpos,50,17,17,' TRANSPOSE '); If transp_menu2 then transp_pos1 := transpos else transp_pos2 := transpos; If (mn_environment.keystroke = kTAB) then begin transp_menu2 := NOT transp_menu2; If transp_menu2 then transpos := transp_pos1 else transpos := transp_pos2; keyboard_reset_buffer; end; If (mn_environment.keystroke <> kESC) and (mn_environment.keystroke <> kTAB) then begin If transp_menu2 or (transpos < 9) then begin patt0 := pattern_patt; patt1 := patt0; end else begin patt0 := 0; patt1 := patterns; end; If NOT transp_menu2 then begin line0 := 0; line1 := PRED(songdata.patt_len); track0 := 1; track1 := songdata.nm_tracks; end else If (transpos < 9) then begin line0 := 0; line1 := PRED(songdata.patt_len); track0 := count_channel(pattern_hpos); track1 := track0; end else begin If tracing then begin patt0 := tracing_block_pattern; patt1 := patt0; end; line0 := block_y0; line1 := block_y1; track0 := block_x0; track1 := block_x1; end; Case transpos of 1,2, 5,6, 10..11, 14..15: If (transpos in [1..4,10..13]) then transpose_custom_area(ttTransposeUp, ttTransposeCurrentIns, patt0,patt1,track0,track1,line0,line1, factor[transpos]) else transpose_custom_area(ttTransposeUp, ttTransposeAllIns, patt0,patt1,track0,track1,line0,line1, factor[transpos]); 3,4, 7,8, 12..13, 16..17: If (transpos in [1..4,10..13]) then transpose_custom_area(ttTransposeDown, ttTransposeCurrentIns, patt0,patt1,track0,track1,line0,line1, factor[transpos]) else transpose_custom_area(ttTransposeDown, ttTransposeAllIns, patt0,patt1,track0,track1,line0,line1, factor[transpos]); end; end; until (mn_environment.keystroke <> kTAB); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); mn_setting.fixed_len := 0; mn_setting.terminate_keys[3] := 0; mn_environment.context := ''; mn_environment.ext_proc := NIL; mn_setting.text_attr := old_text_attr; end; function cstr2str(str: String): String; var temp: Byte; begin For temp := 1 to Length(str) do If (str[temp] = '~') then Delete(str,temp,1); cstr2str := str; end; var _remap_pos, _remap_inst_page_len, _remap_xstart, _remap_ystart: Byte; procedure _remap_refresh_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_remap_refresh_proc'; {$ENDIF} If (_remap_pos = 1) then ShowStr(centered_frame_vdest,_remap_xstart+8,_remap_ystart+1,'CURRENT iNSTRUMENT ('+ byte2hex(MenuLib1_mn_environment.curr_pos)+')', dialog_background+dialog_hi_text) else ShowStr(centered_frame_vdest,_remap_xstart+8,_remap_ystart+1,'CURRENT iNSTRUMENT ('+ byte2hex(MenuLib1_mn_environment.curr_pos)+')', dialog_background+dialog_text); If (_remap_pos = 2) then ShowStr(centered_frame_vdest,_remap_xstart+44,_remap_ystart+1,'NEW iNSTRUMENT ('+ byte2hex(MenuLib2_mn_environment.curr_pos)+')', dialog_background+dialog_hi_text) else ShowStr(centered_frame_vdest,_remap_xstart+44,_remap_ystart+1,'NEW iNSTRUMENT ('+ byte2hex(MenuLib2_mn_environment.curr_pos)+')', dialog_background+dialog_text); If (_remap_pos = 3) then ShowStr(centered_frame_vdest,_remap_xstart+18,_remap_ystart+_remap_inst_page_len+4,' PATTERN ', dialog_hi_text SHL 4) else If (remap_selection = 1) then ShowStr(centered_frame_vdest,_remap_xstart+18,_remap_ystart+_remap_inst_page_len+4,' PATTERN ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_remap_xstart+18,_remap_ystart+_remap_inst_page_len+4,' PATTERN ', dialog_background+dialog_text); If (_remap_pos = 4) then ShowStr(centered_frame_vdest,_remap_xstart+29,_remap_ystart+_remap_inst_page_len+4,' SONG ', dialog_hi_text SHL 4) else If (remap_selection = 2) then ShowStr(centered_frame_vdest,_remap_xstart+29,_remap_ystart+_remap_inst_page_len+4,' SONG ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_remap_xstart+29,_remap_ystart+_remap_inst_page_len+4,' SONG ', dialog_background+dialog_text); If (_remap_pos = 5) then ShowStr(centered_frame_vdest,_remap_xstart+37,_remap_ystart+_remap_inst_page_len+4,' TRACK ', dialog_hi_text SHL 4) else If (remap_selection = 3) then ShowStr(centered_frame_vdest,_remap_xstart+37,_remap_ystart+_remap_inst_page_len+4,' TRACK ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_remap_xstart+37,_remap_ystart+_remap_inst_page_len+4,' TRACK ', dialog_background+dialog_text); If (_remap_pos = 6) then ShowStr(centered_frame_vdest,_remap_xstart+46,_remap_ystart+_remap_inst_page_len+4,' BLOCK ', dialog_hi_text SHL 4) else If (remap_selection = 4) then ShowStr(centered_frame_vdest,_remap_xstart+46,_remap_ystart+_remap_inst_page_len+4,' BLOCK ', dialog_sel_itm_bck+dialog_sel_itm) else If marking then ShowStr(centered_frame_vdest,_remap_xstart+46,_remap_ystart+_remap_inst_page_len+4,' BLOCK ', dialog_background+dialog_text) else ShowStr(centered_frame_vdest,_remap_xstart+46,_remap_ystart+_remap_inst_page_len+4,' BLOCK ', dialog_background+dialog_item_dis); end; procedure REMAP_instr_control_proc; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REMAP_instr_control_proc'; {$ENDIF} _remap_refresh_proc; If (remap_mtype = 1) then INSTRUMENT_test(MenuLib1_mn_environment.curr_pos,BYTE_NULL,count_channel(pattern_hpos), MenuLib1_mn_environment.keystroke,TRUE) else INSTRUMENT_test(MenuLib2_mn_environment.curr_pos,BYTE_NULL,count_channel(pattern_hpos), MenuLib2_mn_environment.keystroke,TRUE); end; procedure REMAP; var status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; var chunk: tCHUNK; temp,temp1,temp2,temp3: Byte; patt0,patt1,track0,track1,line0,line1: Byte; fkey: Word; patterns: Byte; qflag: Boolean; procedure reset_screen; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REMAP:reset_screen'; {$ENDIF} MenuLib1_mn_environment.ext_proc := NIL; MenuLib2_mn_environment.ext_proc := NIL; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := _remap_xstart; move_to_screen_area[2] := _remap_ystart; move_to_screen_area[3] := _remap_xstart+71+2; move_to_screen_area[4] := _remap_ystart+_remap_inst_page_len+5+1; move2screen; end; procedure override_frame(dest: tSCREEN_MEM_PTR; x,y: Byte; frame: String; attr: Byte); {$IFNDEF CPU64} procedure override_vscrollbar(dest: tSCREEN_MEM_PTR; x,y: Byte; len: Byte; attr: Byte); begin asm mov al,MaxCol dec al xor ah,ah xor ebx,ebx mov bl,2 mul bl mov bx,ax mov edi,dword ptr [dest] mov al,x mov ah,y push eax push ebx mov al,MaxCol xor ah,ah xor ebx,ebx mov bl,y dec bl mul bl mov bl,x dec bl add eax,ebx mov edx,eax shl edx,1 pop ebx pop eax xor ecx,ecx mov cl,len jecxz @@2 add edi,edx mov al,attr @@1: inc edi stosb add edi,ebx loop @@1 @@2: end; end; {$ELSE} procedure override_vscrollbar(dest: tSCREEN_MEM_PTR; x,y: Byte; len: Byte; attr: Byte); var row: Byte; begin If (len <> 0) then For row := PRED(y) to PRED(y)+len do dest^[SUCC((row*MaxCol+PRED(x))*2)] := attr; end; {$ENDIF} begin ShowStr(dest,x,y,frame[1]+ExpStrL('',32,frame[2])+frame[3],attr); ShowVStr(dest,x,y+1,ExpStrL('',MAX_PATTERN_ROWS,frame[4]),attr); ShowStr(dest,x,y+MAX_PATTERN_ROWS+1,frame[6]+ExpStrL('',32,frame[7])+frame[8],attr); override_vscrollbar(dest,x+33,y+1,MAX_PATTERN_ROWS,attr); end; var temp_instr_names: array[1..255] of String[32]; label _jmp1; begin { REMAP } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REMAP'; {$ENDIF} If (remap_selection = 4) and NOT marking then remap_selection := 1; _remap_pos := 1; _remap_inst_page_len := MAX_PATTERN_ROWS; qflag := FALSE; MenuLib1_mn_setting.menu_attr := dialog_background+dialog_text; MenuLib2_mn_setting.menu_attr := dialog_background+dialog_text; _jmp1: If _force_program_quit then EXIT; For temp := 1 to 255 do temp_instr_names[temp] := ' '+Copy(cstr2str(songdata.instr_names[temp]),2,31); ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; count_patterns(patterns); ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(_remap_xstart,_remap_ystart,71,_remap_inst_page_len+5,' REMAP iNSTRUMENT ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); MenuLib1_mn_environment.curr_pos := remap_ins1; MenuLib2_mn_environment.curr_pos := remap_ins2; MenuLib1_mn_environment.v_dest := ptr_temp_screen; MenuLib2_mn_environment.v_dest := ptr_temp_screen; MenuLib1_mn_environment.ext_proc := REMAP_instr_control_proc; MenuLib2_mn_environment.ext_proc := REMAP_instr_control_proc; MenuLib1_mn_environment.unpolite := FALSE; MenuLib1_mn_environment.preview := TRUE; remap_ins1 := MenuLib1_Menu(temp_instr_names,_remap_xstart+2,_remap_ystart+2, remap_ins1,32,_remap_inst_page_len,255,''); MenuLib2_mn_environment.unpolite := FALSE; MenuLib2_mn_environment.preview := TRUE; remap_ins2 := MenuLib2_Menu(temp_instr_names,_remap_xstart+36,_remap_ystart+2, remap_ins2,32,_remap_inst_page_len,255,''); If (_remap_pos = 1) then override_frame(centered_frame_vdest,_remap_xstart+2,_remap_ystart+2, frame_double, dialog_background+dialog_hi_text) else override_frame(centered_frame_vdest,_remap_xstart+2,_remap_ystart+2, frame_single, dialog_background+dialog_text); If (_remap_pos = 2) then override_frame(centered_frame_vdest,_remap_xstart+36,_remap_ystart+2, frame_double,dialog_background+dialog_hi_text) else override_frame(centered_frame_vdest,_remap_xstart+36,_remap_ystart+2, frame_single, dialog_background+dialog_text); _remap_refresh_proc; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := _remap_xstart; move_to_screen_area[2] := _remap_ystart; move_to_screen_area[3] := _remap_xstart+71+2; move_to_screen_area[4] := _remap_ystart+_remap_inst_page_len+5+1; move2screen_alt; centered_frame_vdest := screen_ptr; MenuLib1_mn_environment.v_dest := screen_ptr; MenuLib2_mn_environment.v_dest := screen_ptr; If NOT _force_program_quit then Repeat If (_remap_pos = 1) then begin override_frame(screen_ptr,_remap_xstart+2,_remap_ystart+2, frame_double, dialog_background+dialog_hi_text); MenuLib1_mn_setting.menu_attr := dialog_background+dialog_hi_text; end else begin override_frame(screen_ptr,_remap_xstart+2,_remap_ystart+2, frame_single, dialog_background+dialog_text); MenuLib1_mn_setting.menu_attr := dialog_background+dialog_text; end; If (_remap_pos = 2) then begin override_frame(screen_ptr,_remap_xstart+36,_remap_ystart+2, frame_double, dialog_background+dialog_hi_text); MenuLib2_mn_setting.menu_attr := dialog_background+dialog_hi_text; end else begin override_frame(screen_ptr,_remap_xstart+36,_remap_ystart+2, frame_single, dialog_background+dialog_text); MenuLib2_mn_setting.menu_attr := dialog_background+dialog_text; end; Case _remap_pos of 1: begin remap_ins1 := MenuLib1_Menu(temp_instr_names,_remap_xstart+2,_remap_ystart+2, remap_ins1,32,_remap_inst_page_len,255,''); Case MenuLib1_mn_environment.keystroke of kShTAB,kLEFT: _remap_pos := 2+remap_selection; kRIGHT,kTAB: _remap_pos := 2; kESC: qflag := TRUE; kENTER: begin _remap_pos := 2+remap_selection; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 2: begin remap_ins2 := MenuLib2_Menu(temp_instr_names,_remap_xstart+36,_remap_ystart+2, remap_ins2,32,_remap_inst_page_len,255,''); Case MenuLib2_mn_environment.keystroke of kLEFT,kShTAB: _remap_pos := 1; kTAB,kRIGHT: _remap_pos := 2+remap_selection; kESC: qflag := TRUE; kENTER: begin _remap_pos := 2+remap_selection; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 3: begin fkey := getkey; Case fkey of kHOME: _remap_pos := 3; kEND,kLEFT: If marking then _remap_pos := 6 else _remap_pos := 5; kRIGHT: _remap_pos := 4; kTAB,kDOWN: _remap_pos := 1; kShTAB,kUP: _remap_pos := 2; kENTER: qflag := TRUE; kESC: begin _remap_pos := 1; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 4: begin fkey := getkey; Case fkey of kHOME: _remap_pos := 3; kEND: If marking then _remap_pos := 6 else _remap_pos := 5; kLEFT: _remap_pos := 3; kRIGHT: _remap_pos := 5; kTAB,kDOWN: _remap_pos := 1; kShTAB,kUP: _remap_pos := 2; kENTER: qflag := TRUE; kESC: begin _remap_pos := 1; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 5: begin fkey := getkey; Case fkey of kHOME: _remap_pos := 3; kEND: If marking then _remap_pos := 6 else _remap_pos := 5; kLEFT: _remap_pos := 4; kRIGHT: If marking then _remap_pos := 6 else _remap_pos := 3; kTAB,kDOWN: _remap_pos := 1; kShTAB,KUP: _remap_pos := 2; kENTER: qflag := TRUE; kESC: begin _remap_pos := 1; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; 6: begin fkey := getkey; Case fkey of kHOME: _remap_pos := 3; kEND: _remap_pos := 6; kLEFT: _remap_pos := 5; kRIGHT: _remap_pos := 3; kTAB,kDOWN: _remap_pos := 1; kShTAB,kUP: _remap_pos := 2; kENTER: qflag := TRUE; kESC: begin _remap_pos := 1; qflag := TRUE; end; kCtrlO: begin reset_screen; OCTAVE_CONTROL; GOTO _jmp1; end; kF1: begin reset_screen; HELP('remap_dialog'); GOTO _jmp1; end; end; end; end; If (_remap_pos < 3) then remap_mtype := _remap_pos else remap_selection := _remap_pos-2; _remap_refresh_proc; // draw_screen; until qflag; MenuLib1_mn_environment.ext_proc := NIL; MenuLib2_mn_environment.ext_proc := NIL; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := _remap_xstart; move_to_screen_area[2] := _remap_ystart; move_to_screen_area[3] := _remap_xstart+71+2; move_to_screen_area[4] := _remap_ystart+_remap_inst_page_len+5+1; move2screen; If qflag and (_remap_pos > 2) then begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; Case _remap_pos-2 of 1: begin patt0 := pattern_patt; patt1 := patt0; track0 := 1; track1 := songdata.nm_tracks; line0 := 0; line1 := PRED(songdata.patt_len); end; 2: begin patt0 := 0; patt1 := patterns; track0 := 1; track1 := songdata.nm_tracks; line0 := 0; line1 := PRED(songdata.patt_len); end; 3: begin patt0 := pattern_patt; patt1 := patt0; track0 := count_channel(pattern_hpos); track1 := track0; line0 := 0; line1 := PRED(songdata.patt_len); end; 4: begin patt0 := pattern_patt; patt1 := patt0; track0 := block_x0; track1 := block_x1; line0 := block_y0; line1 := block_y1; end; end; For temp3 := patt0 to patt1 do For temp2 := track0 to track1 do For temp1 := line0 to line1 do begin get_chunk(temp3,temp1,temp2,chunk); If (chunk.instr_def = remap_ins1) then begin chunk.instr_def := remap_ins2; put_chunk(temp3,temp1,temp2,chunk); end; end; replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; const _rearrange_track_pos: Byte = 1; _rearrange_pos: Byte = 1; _rearrange_tracklist_idx: array[1..20] of Byte = ( 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20); var _rearrange_xstart, _rearrange_ystart, _rearrange_nm_tracks: Byte; _rearrange_tracklist: array[1..18] of String[4]; procedure _rearrange_refresh_proc; var idx: Byte; attr: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_rearrange_refresh_proc'; {$ENDIF} If (_rearrange_pos <> 1) then attr := dialog_sel_itm_bck+dialog_sel_itm else attr := dialog_hi_text SHL 4; For idx := 1 to _rearrange_nm_tracks do If (idx = _rearrange_track_pos) then ShowCStr(centered_frame_vdest,_rearrange_xstart+1,_rearrange_ystart+idx, '~ '+ExpStrL(Num2str(idx,10),2,' ')+' ~'#16+_rearrange_tracklist[idx]+#17, attr, dialog_background+dialog_contxt_dis2) else ShowCStr(centered_frame_vdest,_rearrange_xstart+1,_rearrange_ystart+idx, '~ '+ExpStrL(Num2str(idx,10),2,' ')+' ~'+_rearrange_tracklist[idx]+' ', mn_setting.text_attr, dialog_background+dialog_contxt_dis2); If (_rearrange_pos = 2) then ShowStr(centered_frame_vdest,_rearrange_xstart+2,_rearrange_ystart+_rearrange_nm_tracks+2,' PATTERN ', dialog_hi_text SHL 4) else If (rearrange_selection = 1) then ShowStr(centered_frame_vdest,_rearrange_xstart+2,_rearrange_ystart+_rearrange_nm_tracks+2,' PATTERN ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_rearrange_xstart+2,_rearrange_ystart+_rearrange_nm_tracks+2,' PATTERN ', dialog_background+dialog_text); If (_rearrange_pos = 3) then ShowStr(centered_frame_vdest,_rearrange_xstart+13,_rearrange_ystart+_rearrange_nm_tracks+2,' SONG ', dialog_hi_text SHL 4) else If (rearrange_selection = 2) then ShowStr(centered_frame_vdest,_rearrange_xstart+13,_rearrange_ystart+_rearrange_nm_tracks+2,' SONG ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,_rearrange_xstart+13,_rearrange_ystart+_rearrange_nm_tracks+2,' SONG ', dialog_background+dialog_text); end; procedure REARRANGE; var status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; var temp,temp1,temp2,temp3: Byte; temps: String; patt0,patt1: Byte; fkey: Word; patterns: Byte; qflag,reset_flag: Boolean; temp_pattern: array[1..20] of array[0..$0ff] of tCHUNK; procedure reset_screen; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REARRANGE:reset_screen'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := _rearrange_xstart; move_to_screen_area[2] := _rearrange_ystart; move_to_screen_area[3] := _rearrange_xstart+20+2; move_to_screen_area[4] := _rearrange_ystart+_rearrange_nm_tracks+3+1; move2screen; end; label _jmp1; begin { REARRANGE } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REARRANGE'; {$ENDIF} If (_rearrange_track_pos > songdata.nm_tracks) then _rearrange_track_pos := 1; If (rearrange_selection = 4) and NOT marking then rearrange_selection := 1; _rearrange_pos := 1; qflag := FALSE; If percussion_mode then _rearrange_nm_tracks := max(songdata.nm_tracks,15) else _rearrange_nm_tracks := songdata.nm_tracks; reset_flag := FALSE; For temp := 1 to _rearrange_nm_tracks do If (_rearrange_tracklist_idx[temp] > _rearrange_nm_tracks) then begin reset_flag := TRUE; BREAK; end; If reset_flag then begin For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[temp] := temp; _rearrange_track_pos := 1; end; For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist[temp] := ' '+ExpStrL(Num2str(_rearrange_tracklist_idx[temp],10),2,' ')+' '; _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; count_patterns(patterns); ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(_rearrange_xstart,_rearrange_ystart,20,_rearrange_nm_tracks+3,' REARRANGE TRACKS ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); ShowStr(centered_frame_vdest,_rearrange_xstart+1,_rearrange_ystart+_rearrange_nm_tracks+1, ExpStrL('',19,#196), dialog_background+dialog_contxt_dis2); _rearrange_refresh_proc; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := _rearrange_xstart; move_to_screen_area[2] := _rearrange_ystart; move_to_screen_area[3] := _rearrange_xstart+20+2; move_to_screen_area[4] := _rearrange_ystart+_rearrange_nm_tracks+3+1; move2screen_alt; centered_frame_vdest := screen_ptr; If NOT _force_program_quit then Repeat Case _rearrange_pos of 1: begin fkey := getkey; Case fkey of kUP: If (_rearrange_track_pos > 1) then Dec(_rearrange_track_pos) else _rearrange_track_pos := _rearrange_nm_tracks; kDOWN: If (_rearrange_track_pos < _rearrange_nm_tracks) then Inc(_rearrange_track_pos) else _rearrange_track_pos := 1; kPgUP,kHOME: _rearrange_track_pos := 1; kPgDOWN,kEND: _rearrange_track_pos := _rearrange_nm_tracks; kCtPgUP: If (_rearrange_nm_tracks > 1) then If shift_pressed then begin temps := _rearrange_tracklist[1]; For temp := 1 to _rearrange_track_pos do _rearrange_tracklist[temp] := _rearrange_tracklist[temp+1]; _rearrange_tracklist[_rearrange_track_pos] := temps; end else If (_rearrange_track_pos > 1) then begin temps := _rearrange_tracklist[_rearrange_track_pos-1]; _rearrange_tracklist[_rearrange_track_pos-1] := _rearrange_tracklist[_rearrange_track_pos]; _rearrange_tracklist[_rearrange_track_pos] := temps; Dec(_rearrange_track_pos); end; kCtPgDN: If (_rearrange_track_pos < _rearrange_nm_tracks) then If shift_pressed then begin temps := _rearrange_tracklist[_rearrange_nm_tracks]; For temp := _rearrange_nm_tracks downto _rearrange_track_pos+1 do _rearrange_tracklist[temp] := _rearrange_tracklist[temp-1]; _rearrange_tracklist[_rearrange_track_pos] := temps; end else begin temps := _rearrange_tracklist[_rearrange_track_pos+1]; _rearrange_tracklist[_rearrange_track_pos+1] := _rearrange_tracklist[_rearrange_track_pos]; _rearrange_tracklist[_rearrange_track_pos] := temps; Inc(_rearrange_track_pos); end; kLEFT,kRIGHT,kTAB,kShTAB: _rearrange_pos := 1+rearrange_selection; kESC: qflag := TRUE; kENTER: begin _rearrange_pos := 1+rearrange_selection; qflag := TRUE; end; kF1: begin reset_screen; HELP('rearrange_dialog'); GOTO _jmp1; end; end; end; 2: begin fkey := getkey; Case fkey of kHOME: _rearrange_pos := 2; kEND,kLEFT: _rearrange_pos := 3; kRIGHT: _rearrange_pos := 3; kUP,kDOWN,kTAB,kShTAB: _rearrange_pos := 1; kENTER: qflag := TRUE; kESC: begin _rearrange_pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('rearrange_dialog'); GOTO _jmp1; end; end; end; 3: begin fkey := getkey; Case fkey of kHOME: _rearrange_pos := 2; kEND: _rearrange_pos := 3; kLEFT: _rearrange_pos := 2; kRIGHT: _rearrange_pos := 2; kUP,kDOWN,kTAB,kShTAB: _rearrange_pos := 1; kENTER: qflag := TRUE; kESC: begin _rearrange_pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('rearrange_dialog'); GOTO _jmp1; end; end; end; end; If (_rearrange_pos > 1) then rearrange_selection := _rearrange_pos-1; If (fkey <> kESC) then _rearrange_refresh_proc; // draw_screen; until qflag; reset_screen; For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[temp] := Str2num(CutStr(_rearrange_tracklist[temp]),10); If qflag and (_rearrange_pos > 1) then begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; _rearrange_track_pos := 1; Case rearrange_selection of 1: begin patt0 := pattern_patt; patt1 := patt0; end; 2: begin patt0 := 0; patt1 := patterns; end; end; For temp3 := patt0 to patt1 do begin For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to _rearrange_nm_tracks do get_chunk(temp3,temp2,_rearrange_tracklist_idx[temp1],temp_pattern[temp1][temp2]); For temp2 := 0 to PRED(songdata.patt_len) do For temp1 := 1 to _rearrange_nm_tracks do put_chunk(temp3,temp2,temp1,temp_pattern[temp1][temp2]); end; For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[temp] := temp; replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; procedure REPLACE; type tCharSet = Set of Char; const _charset: array[1..11] of tCharSet = ( [], ['#','-'], ['1'..'9'], ['0'..'9','A'..'F'], ['0'..'9','A'..'F'], ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<'], ['0'..'9','A'..'F'], ['0'..'9','A'..'F'], ['0'..'9','A'..'Z','&','%','!','@','=','#','$','~','^','`','>','<'], ['0'..'9','A'..'F'], ['0'..'9','A'..'F']); const _on_off: array[0..1] of Char = ' '#251; var status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; var chunk,old_chunk: tCHUNK; temp,temp1,temp2,temp3: Byte; patt0,patt1,track0,track1,line0,line1: Byte; pos: Byte; fkey: Word; xstart,ystart: Byte; patterns: Byte; qflag: Boolean; procedure refresh; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REPLACE:refresh'; {$ENDIF} If (pos in [1..11]) then ShowStr(centered_frame_vdest,xstart+2,ystart+1, 'NOTE,iNSTRUMENT,FX N'#249'1/N'#249'2 TO FiND', dialog_background+dialog_hi_text) else ShowStr(centered_frame_vdest,xstart+2,ystart+1, 'NOTE,iNSTRUMENT,FX N'#249'1/N'#249'2 TO FiND', dialog_background+dialog_text); If (pos in [12..22]) then ShowStr(centered_frame_vdest,xstart+2,ystart+4, 'NEW NOTE,iNSTRUMENT,FX N'#249'1/N'#249'2', dialog_background+dialog_hi_text) else ShowStr(centered_frame_vdest,xstart+2,ystart+4, 'NEW NOTE,iNSTRUMENT,FX N'#249'1/N'#249'2', dialog_background+dialog_text); ShowCStr2(centered_frame_vdest,xstart+2,ystart+2, '"'+FilterStr(replace_data.event_to_find.note,'?',#250)+'" '+ '"'+FilterStr(replace_data.event_to_find.inst,'?',#250)+'" '+ '"'+FilterStr(replace_data.event_to_find.fx_1,'?',#250)+'" '+ '"'+FilterStr(replace_data.event_to_find.fx_2,'?',#250)+'"', dialog_background+dialog_text, dialog_input_bckg+dialog_input); ShowCStr2(centered_frame_vdest,xstart+2,ystart+5, '"'+FilterStr(replace_data.new_event.note,'?',#250)+'" '+ '"'+FilterStr(replace_data.new_event.inst,'?',#250)+'" '+ '"'+FilterStr(replace_data.new_event.fx_1,'?',#250)+'" '+ '"'+FilterStr(replace_data.new_event.fx_2,'?',#250)+'"', dialog_background+dialog_text, dialog_input_bckg+dialog_input); If (pos = 27) then ShowC3Str(centered_frame_vdest,xstart+2,ystart+7, '~[~`'+_on_off[BYTE(replace_prompt)]+'`~]~ PROMPT ON REPLACE', dialog_background+dialog_hi_text, dialog_background+dialog_text, dialog_background+dialog_item) else ShowCStr(centered_frame_vdest,xstart+2,ystart+7, '[~'+_on_off[BYTE(replace_prompt)]+'~] PROMPT ON REPLACE', dialog_background+dialog_text, dialog_background+dialog_item); If (pos = 23) then ShowStr(centered_frame_vdest,xstart+2,ystart+9,' PATTERN ', dialog_hi_text SHL 4) else If (replace_selection = 1) then ShowStr(centered_frame_vdest,xstart+2,ystart+9,' PATTERN ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,xstart+2,ystart+9,' PATTERN ', dialog_background+dialog_text); If (pos = 24) then ShowStr(centered_frame_vdest,xstart+13,ystart+9,' SONG ', dialog_hi_text SHL 4) else If (replace_selection = 2) then ShowStr(centered_frame_vdest,xstart+13,ystart+9,' SONG ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,xstart+13,ystart+9,' SONG ', dialog_background+dialog_text); If (pos = 25) then ShowStr(centered_frame_vdest,xstart+21,ystart+9,' TRACK ', dialog_hi_text SHL 4) else If (replace_selection = 3) then ShowStr(centered_frame_vdest,xstart+21,ystart+9,' TRACK ', dialog_sel_itm_bck+dialog_sel_itm) else ShowStr(centered_frame_vdest,xstart+21,ystart+9,' TRACK ', dialog_background+dialog_text); If (pos = 26) then ShowStr(centered_frame_vdest,xstart+30,ystart+9,' BLOCK ', dialog_hi_text SHL 4) else If (replace_selection = 4) then ShowStr(centered_frame_vdest,xstart+30,ystart+9,' BLOCK ', dialog_sel_itm_bck+dialog_sel_itm) else If marking then ShowStr(centered_frame_vdest,xstart+30,ystart+9,' BLOCK ', dialog_background+dialog_text) else ShowStr(centered_frame_vdest,xstart+30,ystart+9,' BLOCK ', dialog_background+dialog_item_dis); end; procedure reset_screen; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REPLACE:reset_screen'; {$ENDIF} HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+38+2; move_to_screen_area[4] := ystart+10+1; move2screen; end; function _find_note(layout: String; old_note: Byte): BYTE; var temp: Byte; found_flag: Boolean; begin If (layout = note_keyoff_str[pattern_layout]) then _find_note := BYTE_NULL else begin found_flag := FALSE; For temp := 0 to 12*8+1 do If SameName(note_layout[temp],layout) then begin found_flag := TRUE; BREAK; end; If found_flag then _find_note := temp else _find_note := old_note; end; end; {$IFNDEF CPU64} function _find_fx(fx_str: Char): Byte; var result: Byte; begin asm lea edi,[fx_digits] mov ebx,edi mov al,fx_str mov ecx,NM_FX_DIGITS repnz scasb sub edi,ebx mov eax,edi dec eax mov result,al end; _find_fx := result; end; {$ELSE} function _find_fx(fx_str: Char): Byte; var result: Byte; begin result := SYSTEM.Pos(fx_str,fx_digits); If (result <> 0) then _find_fx := PRED(result) else _find_fx := PRED(NM_FX_DIGITS); end; {$ENDIF} function _wildcard_str(wildcard,str: String): String; var temp: Byte; begin For temp := 1 to Length(wildcard) do If (wildcard[temp] = '?') then wildcard[temp] := str[temp]; _wildcard_str := wildcard; end; var _1st_choice,_replace_all, _cancel,_valid_note: Boolean; chr: Char; temp_note: Byte; temps: String; event_to_find: Record note: String[3]; inst: String[2]; fx_1: String[3]; fx_2: String[3]; end; new_event: Record note: String[3]; inst: String[2]; fx_1: String[3]; fx_2: String[3]; end; label _jmp1; begin { REPLACE } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:REPLACE'; {$ENDIF} If (replace_selection = 4) and NOT marking then replace_selection := 1; pos := min(get_bank_position('?replace_window?pos',-1),1); qflag := FALSE; _charset[1] := ['A',UpCase(b_note),'C'..'G']; _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; count_patterns(patterns); ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,38,10,' REPLACE ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+38+2; move_to_screen_area[4] := ystart+10+1; refresh; ShowStr(centered_frame_vdest,xstart+1,ystart+8, ExpStrL('',38-1,#20), dialog_background+dialog_context_dis); move2screen_alt; centered_frame_vdest := screen_ptr; If NOT _force_program_quit then Repeat If (pos in [1..22,27]) then ThinCursor else HideCursor; Case pos of 1..11: begin GotoXY(xstart+1+pos6[pos],ystart+2); fkey := getkey; Case fkey of kTAB, kDOWN: begin add_bank_position('?replace_window?posfx',-1,pos); Inc(pos,11); end; kShTAB, kUP: begin add_bank_position('?replace_window?posfx',-1,pos); pos := 22+replace_selection; end; kLEFT: If (pos > 1) then Dec(pos) else begin add_bank_position('?replace_window?posfx',-1,pos); pos := 22+replace_selection; end; kRIGHT: Inc(pos); kHOME: pos := 1; kEND: pos := 11; kESC: qflag := TRUE; kENTER: begin pos := 22+replace_selection; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; kCtrlK: If (pos in [1,2,3]) then begin replace_data.event_to_find.note := note_keyoff_str[pattern_layout]; pos := 4; end; else If (UpCase(CHAR(LO(fkey))) in _charset[pos]) or (fkey = kBkSPC) or (fkey = kDELETE) then begin Case fkey of kDELETE: chr := #250; kBkSPC: begin chr := #250; If (pos > 1) then Dec(pos); end; else chr := UpCase(CHAR(LO(fkey))); end; If (replace_data.event_to_find.note = note_keyoff_str[pattern_layout]) and (pos in [1,2,3]) then replace_data.event_to_find.note := #250#250#250; With replace_data.event_to_find do Case pos of 1: begin note[1] := chr; If (note[1] in ['E',UpCase(b_note)]) and (note[2] = '#') then note[2] := '-'; If (note[1] <> 'C') and (note[3] = '9') then note[3] := '8'; end; 2: If NOT ((note[1] in ['E',UpCase(b_note)]) and (chr = '#')) then note[2] := chr else note[2] := '-'; 3: If NOT ((note[1] <> 'C') and (chr = '9')) then note[3] := chr; 4: inst[1] := chr; 5: inst[2] := chr; 6: fx_1[1] := chr; 7: fx_1[2] := chr; 8: fx_1[3] := chr; 9: fx_2[1] := chr; 10: fx_2[2] := chr; 11: fx_2[3] := chr; end; Case fkey of kDELETE: ; kBkSPC: ; else If (pos < 22) then Inc(pos); end; end; end; end; 12..22: begin GotoXY(xstart+1+pos6[pos-11],ystart+5); fkey := getkey; Case fkey of kTAB, kDOWN: begin add_bank_position('?replace_window?posfx',-1,pos-11); pos := 27; end; kShTAB, kUP: begin add_bank_position('?replace_window?posfx',-1,pos-11); Dec(pos,11); end; kLEFT: Dec(pos); kRIGHT: If (pos < 22) then Inc(pos) else pos := 27; kHOME: pos := 12; kEND: pos := 22; kESC: qflag := TRUE; kENTER: begin pos := 22+replace_selection; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; kCtrlN: Case pos-11 of 1,2,3: begin replace_data.new_event.note := #7#7#7; pos := 11+4; end; 4,5: begin replace_data.new_event.inst := '00'; pos := 11+6; end; 6,7,8: begin replace_data.new_event.fx_1 := '000'; pos := 11+9; end; 9,10,11: begin replace_data.new_event.fx_2 := '000'; pos := 27; end; end; kCtrlK: If (pos-11 in [1,2,3]) then begin replace_data.new_event.note := note_keyoff_str[pattern_layout]; pos := 11+4; end; else If (UpCase(CHAR(LO(fkey))) in _charset[pos-11]) or (fkey = kBkSPC) or (fkey = kDELETE) then begin Case fkey of kDELETE: chr := #250; kBkSPC: begin chr := #250; Dec(pos); end; else chr := UpCase(CHAR(LO(fkey))); end; If ((replace_data.new_event.note = note_keyoff_str[pattern_layout]) or (replace_data.new_event.note = #7#7#7)) and (pos-11 in [1,2,3]) then replace_data.new_event.note := #250#250#250; With replace_data.new_event do Case pos-11 of 1: begin note[1] := chr; If (note[1] in ['E',UpCase(b_note)]) and (note[2] = '#') then note[2] := '-'; If (note[1] <> 'C') and (note[3] = '9') then note[3] := '8'; end; 2: If NOT ((note[1] in ['E',UpCase(b_note)]) and (chr = '#')) then note[2] := chr else note[2] := '-'; 3: If NOT ((note[1] <> 'C') and (chr = '9')) then note[3] := chr; 4: inst[1] := chr; 5: inst[2] := chr; 6: fx_1[1] := chr; 7: fx_1[2] := chr; 8: fx_1[3] := chr; 9: fx_2[1] := chr; 10: fx_2[2] := chr; 11: fx_2[3] := chr; end; Case fkey of kDELETE: ; kBkSPC: ; else If (pos < 22) then Inc(pos); end; end; end; end; 27: begin GotoXY(xstart+3,ystart+7); fkey := getkey; Case fkey of kUP,kShTAB: pos := get_bank_position('?replace_window?posfx',-1)+11; kLEFT: pos := 22; kTAB,kRIGHT,kDOWN: pos := 22+replace_selection; kENTER: qflag := TRUE; kSPACE: replace_prompt := NOT replace_prompt; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; 23: begin fkey := getkey; Case fkey of kTAB,kDOWN: pos := get_bank_position('?replace_window?posfx',-1); kShTAB,kUP: pos := 27; kHOME: pos := 23; kEND,kLEFT: If marking then pos := 26 else pos := 25; kRIGHT: pos := 24; kENTER: qflag := TRUE; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; 24: begin fkey := getkey; Case fkey of kTAB,kDOWN: pos := get_bank_position('?replace_window?posfx',-1); kShTAB,kUP: pos := 27; kHOME: pos := 23; kEND: If marking then pos := 26 else pos := 25; kLEFT: pos := 23; kRIGHT: pos := 25; kENTER: qflag := TRUE; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; 25: begin fkey := getkey; Case fkey of kTAB,kDOWN: pos := get_bank_position('?replace_window?posfx',-1); kShTAB,kUP: pos := 27; kHOME: pos := 23; kEND: If marking then pos := 26 else pos := 25; kLEFT: pos := 24; kRIGHT: If marking then pos := 26 else pos := 23; kENTER: qflag := TRUE; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; 26: begin fkey := getkey; Case fkey of kTAB,kDOWN: pos := get_bank_position('?replace_window?posfx',-1); kShTAB,kUP: pos := 27; kHOME: pos := 23; kEND: pos := 26; kLEFT: pos := 25; kRIGHT: pos := 23; kENTER: qflag := TRUE; kESC: begin pos := 1; qflag := TRUE; end; kF1: begin reset_screen; HELP('replace_dialog'); GOTO _jmp1; end; end; end; end; Case fkey of kCtrlW: begin temps := replace_data.event_to_find.note; replace_data.event_to_find.note := replace_data.new_event.note; replace_data.new_event.note := temps; temps := replace_data.event_to_find.inst; replace_data.event_to_find.inst := replace_data.new_event.inst; replace_data.new_event.inst := temps; temps := replace_data.event_to_find.fx_1; replace_data.event_to_find.fx_1 := replace_data.new_event.fx_1; replace_data.new_event.fx_1 := temps; temps := replace_data.event_to_find.fx_2; replace_data.event_to_find.fx_2 := replace_data.new_event.fx_2; replace_data.new_event.fx_2 := temps; end; kCtBkSp: begin If (pos < 12) or shift_pressed then begin replace_data.event_to_find.note := #250#250#250; replace_data.event_to_find.inst := #250#250; replace_data.event_to_find.fx_1 := #250#250#250; replace_data.event_to_find.fx_2 := #250#250#250; end; If (pos >= 12) or shift_pressed then begin replace_data.new_event.note := #250#250#250; replace_data.new_event.inst := #250#250; replace_data.new_event.fx_1 := #250#250#250; replace_data.new_event.fx_2 := #250#250#250; end; end; end; If (pos in [23..26]) then replace_selection := pos-22; refresh; // draw_screen; If NOT qflag then add_bank_position('?replace_window?pos',-1,pos); until qflag; HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+38+2; move_to_screen_area[4] := ystart+10+1; move2screen; If qflag and (pos > 22) then begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; PATTERN_position_preview(BYTE_NULL,BYTE_NULL,BYTE_NULL,0); event_to_find.note := FilterStr(replace_data.event_to_find.note,#250,'?'); event_to_find.inst := FilterStr(replace_data.event_to_find.inst,#250,'?'); event_to_find.fx_1 := FilterStr(replace_data.event_to_find.fx_1,#250,'?'); event_to_find.fx_2 := FilterStr(replace_data.event_to_find.fx_2,#250,'?'); new_event.note := FilterStr(replace_data.new_event.note,#250,'?'); new_event.inst := FilterStr(replace_data.new_event.inst,#250,'?'); new_event.fx_1 := FilterStr(replace_data.new_event.fx_1,#250,'?'); new_event.fx_2 := FilterStr(replace_data.new_event.fx_2,#250,'?'); Case replace_selection of 1: begin patt0 := pattern_patt; patt1 := patt0; track0 := 1; track1 := songdata.nm_tracks; line0 := 0; line1 := PRED(songdata.patt_len); end; 2: begin patt0 := 0; patt1 := patterns; track0 := 1; track1 := songdata.nm_tracks; line0 := 0; line1 := PRED(songdata.patt_len); end; 3: begin patt0 := pattern_patt; patt1 := patt0; track0 := count_channel(pattern_hpos); track1 := track0; line0 := 0; line1 := PRED(songdata.patt_len); end; 4: begin patt0 := pattern_patt; patt1 := patt0; track0 := block_x0; track1 := block_x1; line0 := block_y0; line1 := block_y1; end; end; _replace_all := FALSE; _cancel := FALSE; _1st_choice := TRUE; For temp3 := patt0 to patt1 do For temp2 := track0 to track1 do For temp1 := line0 to line1 do If NOT _cancel then begin get_chunk(temp3,temp1,temp2,chunk); old_chunk := chunk; If SameName(event_to_find.inst,byte2hex(old_chunk.instr_def)) and SameName(event_to_find.fx_1,fx_digits[old_chunk.effect_def]+byte2hex(old_chunk.effect)) and SameName(event_to_find.fx_2,fx_digits[old_chunk.effect_def2]+byte2hex(old_chunk.effect2)) then begin _valid_note := FALSE; Case old_chunk.note of 0, 1..12*8+1: If SameName(event_to_find.note,note_layout[old_chunk.note]) then begin temp_note := _find_note(_wildcard_str(new_event.note,note_layout[old_chunk.note]),old_chunk.note); _valid_note := TRUE; end; fixed_note_flag+ 1.. fixed_note_flag+ 12*8+1: If SameName(event_to_find.note,note_layout[old_chunk.note-fixed_note_flag]) then begin If NOT (FilterStr(replace_data.new_event.note,'?',#250) = note_keyoff_str[pattern_layout]) then temp_note := fixed_note_flag+_find_note(_wildcard_str(new_event.note,note_layout[old_chunk.note-fixed_note_flag]),old_chunk.note) else temp_note := _find_note(new_event.note,old_chunk.note); _valid_note := TRUE; end; BYTE_NULL: If (replace_data.event_to_find.note = note_keyoff_str[pattern_layout]) then begin temp_note := _find_note(new_event.note,old_chunk.note); _valid_note := TRUE; end; end; If _valid_note and (new_event.note <> '???') then If (new_event.note <> #7#7#7) then chunk.note := temp_note else chunk.note := 0; If _valid_note and (new_event.inst <> '??') then chunk.instr_def := Str2num(_wildcard_str(new_event.inst,byte2hex(old_chunk.instr_def)),16); If _valid_note and (new_event.fx_1 <> '???') then begin chunk.effect_def := _find_fx(_wildcard_str(new_event.fx_1[1],fx_digits[old_chunk.effect_def])[1]); chunk.effect := Str2num(_wildcard_str(new_event.fx_1[2]+new_event.fx_1[3],byte2hex(old_chunk.effect)),16); end; If _valid_note and (new_event.fx_2 <> '???') then begin chunk.effect_def2 := _find_fx(_wildcard_str(new_event.fx_2[1],fx_digits[old_chunk.effect_def2])[1]); chunk.effect2 := Str2num(_wildcard_str(new_event.fx_2[2]+new_event.fx_2[3],byte2hex(old_chunk.effect2)),16); end; end; If NOT Compare(chunk,old_chunk,SizeOf(chunk)) then begin If replace_prompt and NOT _replace_all then begin PATTERN_position_preview(temp3,temp1,temp2,1); keyboard_reset_buffer; If _1st_choice then temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'FOUND OCCURENCE$', '~R~EPLACE$REPLACE ~A~LL$~S~KiP$S~K~iP ALL$~C~ANCEL$', ' REPLACE ',1) else temp := Dialog('PATTERN #'+byte2hex(temp3)+', '+ 'LiNE #' +byte2hex(temp1)+', '+ 'TRACK #' +Num2str(temp2,10)+'$'+ 'FOUND OCCURENCE$', '~R~EPLACE$REPLACE ~A~LL$~S~KiP$S~K~iP ALL$CANCEL$', ' REPLACE ',1); If (dl_environment.keystroke <> kESC) then begin _1st_choice := FALSE; If (temp = 2) then _replace_all := TRUE else If (temp = 3) then CONTINUE else If (temp in [4,5]) then begin _cancel := TRUE; BREAK; end; end else If NOT _1st_choice then CONTINUE else begin _cancel := TRUE; BREAK; end; end; put_chunk(temp3,temp1,temp2,chunk); end; end; PATTERN_position_preview(BYTE_NULL,BYTE_NULL,BYTE_NULL,BYTE_NULL); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; procedure POSITIONS_reset; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:POSITIONS_reset'; {$ENDIF} pattord_page := 0; pattord_hpos := 1; pattord_vpos := 1; instrum_page := 1; pattern_page := 0; pattern_hpos := 1; If (songdata.pattern_order[0] > $7f) then pattern_patt := 0 else pattern_patt := songdata.pattern_order[0]; chan_pos := 1; PATTERN_ORDER_page_refresh(0); PATTERN_page_refresh(0); end; const _perc_char: array[1..5] of Char = #160#161#162#163#164; _panning: array[0..3] of String = (#21#22,#21'`'#22'`','`'#21'`'#22,'`'#21#22'`'); _connection: array[0..1] of String = ('FM','AM'); _off_on: array[1..4,0..1] of Char = (#250'T',#250'V',#250'K',#250'S'); _win_title: array[Boolean] of String = (' DEBUG iNFO ',''); _contxt_str: String = ' LSHiFT/RSHiFT '#196#16' TOGGLE DETAiLS '; procedure DEBUG_INFO; const NOFX = ' '; function effect_str(effect_def,effect,effect_def2: Byte): String; begin Case effect_def of ef_Arpeggio: If (effect <> 0) then effect_str := 'Arpeggio' else effect_str := NOFX; ef_VolSlide: If (effect DIV 16 <> 0) then effect_str := 'VolSld'#24' ' else effect_str := 'VolSld'#25' '; ef_VolSlideFine: If (effect DIV 16 <> 0) then effect_str := 'VolSld'#18' ' else effect_str := 'VolSld'#23' '; ef_TPortamVolSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#13'VSl'#24'' else effect_str := 'Por'#13'VSl'#25; ef_VibratoVolSlide: If (effect DIV 16 <> 0) then effect_str := 'VibrVSl'#24'' else effect_str := 'VibrVSl'#25; ef_TPortamVSlideFine: If (effect DIV 16 <> 0) then effect_str := 'Por'#13'VSl'#18'' else effect_str := 'Por'#13'VSl'#23; ef_VibratoVSlideFine: If (effect DIV 16 <> 0) then effect_str := 'VibrVSl'#18'' else effect_str := 'VibrVSl'#23; ef_ArpggVSlide: If (effect DIV 16 <> 0) then effect_str := 'ArpgVSl'#24'' else effect_str := 'ArpgVSl'#25; ef_ArpggVSlideFine: If (effect DIV 16 <> 0) then effect_str := 'ArpgVSl'#18'' else effect_str := 'ArpgVSl'#23; ef_SetWaveform: If NOT (effect MOD 16 in [0..7]) then effect_str := 'SetW'#26'Car' else If NOT (effect DIV 16 in [0..7]) then effect_str := 'SetW'#26'Mod' else effect_str := 'SetWform'; ef_FSlideUpVSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#24'VSl'#24'' else effect_str := 'Por'#24'VSl'#25; ef_FSlUpVSlF: If (effect DIV 16 <> 0) then effect_str := 'Por'#24'VSl'#18'' else effect_str := 'Por'#24'VSl'#23; ef_FSlideDownVSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#25'VSl'#24'' else effect_str := 'Por'#25'VSl'#25; ef_FSlDownVSlF: If (effect DIV 16 <> 0) then effect_str := 'Por'#25'VSl'#18'' else effect_str := 'Por'#25'VSl'#23; ef_FSlUpFineVSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#18'VSl'#24'' else effect_str := 'Por'#18'VSl'#25; ef_FSlUpFineVSlF: If (effect DIV 16 <> 0) then effect_str := 'Por'#18'VSl'#18'' else effect_str := 'Por'#18'VSl'#23; ef_FSlDownFineVSlide: If (effect DIV 16 <> 0) then effect_str := 'Por'#23'VSl'#24'' else effect_str := 'Por'#23'VSl'#25; ef_FSlDownFineVSlF: If (effect DIV 16 <> 0) then effect_str := 'Por'#23'VSl'#18'' else effect_str := 'Por'#23'VSl'#23; ef_FSlideUp: effect_str := 'Porta'#24' '; ef_FSlideDown: effect_str := 'Porta'#25' '; ef_TonePortamento: effect_str := 'Porta'#13' '; ef_Vibrato: effect_str := 'Vibrato '; ef_FSlideUpFine: effect_str := 'Porta'#18' '; ef_FSlideDownFine: effect_str := 'Porta'#23' '; ef_SetCarrierVol: effect_str := 'SetCVol '; ef_SetModulatorVol: effect_str := 'SetMVol '; ef_PositionJump: effect_str := 'PosJump '; ef_SetInsVolume: effect_str := 'SetVol '; ef_PatternBreak: effect_str := 'PatBreak'; ef_SetTempo: effect_str := 'SetTempo'; ef_SetSpeed: effect_str := 'SetSpeed'; ef_RetrigNote: effect_str := 'Retrig'#13' '; ef_MultiRetrigNote: effect_str := 'MulRetr'#13; ef_Tremolo: effect_str := 'Tremolo '; ef_Tremor: effect_str := 'Tremor '; ef_SetGlobalVolume: effect_str := 'SetGlVol'; ef_ForceInsVolume: effect_str := 'ForceVol'; ef_Extended: Case effect DIV 16 of ef_ex_SetTremDepth: effect_str := 'SetTremD'; ef_ex_SetVibDepth: effect_str := 'SetVibrD'; ef_ex_SetAttckRateM: effect_str := '[A]DSR'#26'M'; ef_ex_SetDecayRateM: effect_str := 'A[D]SR'#26'M'; ef_ex_SetSustnLevelM: effect_str := 'AD[S]R'#26'M'; ef_ex_SetRelRateM: effect_str := 'ADS[R]'#26'M'; ef_ex_SetAttckRateC: effect_str := '[A]DSR'#26'C'; ef_ex_SetDecayRateC: effect_str := 'A[D]SR'#26'C'; ef_ex_SetSustnLevelC: effect_str := 'AD[S]R'#26'C'; ef_ex_SetRelRateC: effect_str := 'ADS[R]'#26'C'; ef_ex_SetFeedback: effect_str := 'SetFeedb'; ef_ex_PatternLoop: effect_str := 'PatLoop '; ef_ex_PatternLoopRec: effect_str := 'PatLoopR'; ef_ex_SetPanningPos: Case effect MOD 16 of 0: effect_str := 'SetPan'#26'C'; 1: effect_str := 'SetPan'#26'L'; 2: effect_str := 'SetPan'#26'R'; end; ef_ex_ExtendedCmd: Case effect MOD 16 of ef_ex_cmd_MKOffLoopDi: effect_str := #12'LoopOff'; ef_ex_cmd_MKOffLoopEn: effect_str := #12'LoopOn '; ef_ex_cmd_TPortaFKdis: effect_str := 'Porta'#13'K-'; ef_ex_cmd_TPortaFKenb: effect_str := 'Porta'#13'K+'; ef_ex_cmd_RestartEnv: effect_str := 'RstrtEnv'; ef_ex_cmd_4opVlockOff: effect_str := 'VLock'#4#3'-'; ef_ex_cmd_4opVlockOn: effect_str := 'VLock'#4#3'+'; ef_ex_cmd_ForceBpmSld: effect_str := 'BpmSlide'; end; ef_ex_ExtendedCmd2: Case effect MOD 16 of ef_ex_cmd2_RSS: effect_str := 'RelSS '; ef_ex_cmd2_ResetVol: effect_str := 'ResetVol'; ef_ex_cmd2_LockVol: effect_str := 'VolLock+'; ef_ex_cmd2_UnlockVol: effect_str := 'VolLock-'; ef_ex_cmd2_LockVP: effect_str := 'LockVP+ '; ef_ex_cmd2_UnlockVP: effect_str := 'LockVP- '; ef_ex_cmd2_VSlide_car: effect_str := 'VSld'#26'Car'; ef_ex_cmd2_VSlide_mod: effect_str := 'VSld'#26'Mod'; ef_ex_cmd2_VSlide_def: effect_str := 'VSld'#26'Def'; ef_ex_cmd2_LockPan: effect_str := 'PanLock+'; ef_ex_cmd2_UnlockPan: effect_str := 'PanLock-'; ef_ex_cmd2_VibrOff: effect_str := 'VibrOff '; ef_ex_cmd2_TremOff: effect_str := 'TremOff '; ef_ex_cmd2_FVib_FGFS: If NOT (effect_def2 in [ef_GlobalFSlideUp,ef_GlobalFSlideDown]) then effect_str := 'VibrFine' else effect_str := 'GlPortaF'; ef_ex_cmd2_FTrm_XFGFS: If NOT (effect_def2 in [ef_GlobalFSlideUp,ef_GlobalFSlideDown]) then effect_str := 'TremFine' else effect_str := 'GlPortXF'; ef_ex_cmd2_NoRestart: effect_str := 'ArpVibNR'; else effect_str := NOFX; end; else effect_str := NOFX; end; ef_Extended2: Case effect DIV 16 of ef_ex2_PatDelayFrame: effect_str := 'PatDelF '; ef_ex2_PatDelayRow: effect_str := 'PatDelR '; ef_ex2_NoteDelay: effect_str := 'Delay'#13' '; ef_ex2_NoteCut: effect_str := 'Cut'#13' '; ef_ex2_GlVolSlideUp: effect_str := 'GlVolSl'#24; ef_ex2_GlVolSlideDn: effect_str := 'GlVolSl'#25; ef_ex2_GlVolSlideUpF: effect_str := 'GlVolSl'#18; ef_ex2_GlVolSlideDnF: effect_str := 'GlVolSl'#23; ef_ex2_FineTuneUp: effect_str := 'FTune'#24' '; ef_ex2_FineTuneDown: effect_str := 'FTune'#25' '; ef_ex2_GlVolSldUpXF: effect_str := 'GVolSl'#12#18; ef_ex2_GlVolSldDnXF: effect_str := 'GVolSl'#12#23; ef_ex2_VolSlideUpXF: effect_str := 'VolSld'#12#18; ef_ex2_VolSlideDnXF: effect_str := 'VolSld'#12#23; ef_ex2_FreqSlideUpXF: effect_str := 'Porta'#12#18' '; ef_ex2_FreqSlideDnXF: effect_str := 'Porta'#12#23' '; end; ef_SwapArpeggio: effect_str := 'ArpT'#26+byte2hex(effect)+' '; ef_SwapVibrato: effect_str := 'VibT'#26+byte2hex(effect)+' '; ef_Extended3: Case effect DIV 16 of ef_ex3_SetConnection: If (effect MOD 16 = 0) then effect_str := 'Conct'#26'FM' else effect_str := 'Conct'#26'AM'; ef_ex3_SetMultipM: effect_str := 'Multip'#26'M'; ef_ex3_SetKslM: effect_str := 'KSL'#26'M '; ef_ex3_SetTremoloM: effect_str := 'Trem'#26'M '; ef_ex3_SetVibratoM: effect_str := 'Vibr'#26'M '; ef_ex3_SetKsrM: effect_str := 'KSR'#26'M '; ef_ex3_SetSustainM: effect_str := 'Sustn'#26'M '; ef_ex3_SetMultipC: effect_str := 'Multip'#26'C'; ef_ex3_SetKslC: effect_str := 'KSL'#26'C '; ef_ex3_SetTremoloC: effect_str := 'Trem'#26'C '; ef_ex3_SetVibratoC: effect_str := 'Vibr'#26'C '; ef_ex3_SetKsrC: effect_str := 'KSR'#26'C '; ef_ex3_SetSustainC: effect_str := 'Sustn'#26'C '; end; ef_ExtraFineArpeggio: effect_str := 'Arpggio'#12; ef_ExtraFineVibrato: effect_str := 'Vibrato'#12; ef_ExtraFineTremolo: effect_str := 'Tremolo'#12; ef_SetCustomSpeedTab: effect_str := 'SetCusST'; ef_GlobalFSlideUp: effect_str := 'GlPorta'#24; ef_GlobalFSlideDown: effect_str := 'GlPorta'#25; else effect_str := NOFX; end; end; function note_str(note,chan: Byte): String; begin If (note < 100) then note_str := note_layout[note]+' ' else If (note AND $7f <> 0) then note_str := note_layout[note AND $7f]+#12 else note_str := note_layout[0]+' '; end; function cstr2str(str: String): String; var temp: Byte; begin For temp := 1 to Length(str) do If (str[temp] = '~') then Delete(str,temp,1); cstr2str := str; end; function last_chan_pos: Byte; begin If (songdata.nm_tracks > MAX_TRACKS) then last_chan_pos := max(16,songdata.nm_tracks-MAX_TRACKS+1) else last_chan_pos := 1; end; function last_hpos: Byte; begin last_hpos := max(_pattedit_lastpos,songdata.nm_tracks*(_pattedit_lastpos DIV MAX_TRACKS)); end; function _macro_str(str: String; null_byte: Byte): String; begin If (null_byte <> 0) then _macro_str := str else _macro_str := ExpStrL('',C3StrLen(str),' '); end; function _freq_slide_str(value: Shortint): String; begin If (value = 0) then _freq_slide_str := '`'#10'`' else If (value > 0) then _freq_slide_str := #24 else _freq_slide_str := #25; end; const IDLE = $0fff; FINISHED = $0ffff; note_keyoff_str: array[Boolean] of String = ('`'#12'`',#12); function _macro_pos_str_fm(pos,len: Word; keyoff_pos,duration: Byte; retrig_note: Byte; freq_slide: Smallint): String; begin If (pos <= 255) then _macro_pos_str_fm := byte2hex(pos)+'/'+byte2hex(len)+':'+byte2hex(duration)+' '+macro_retrig_str[retrig_note]+ _freq_slide_str(freq_slide)+note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)]+'`'#251'`' else If (pos = IDLE) then _macro_pos_str_fm := #250#250#12#250#250':'#250#250' ' else _macro_pos_str_fm := byte2hex(len)+'/'+byte2hex(len)+':'+byte2hex(duration)+' '+macro_retrig_str[retrig_note]+ _freq_slide_str(freq_slide)+note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)]+#251; end; function _macro_pos_str_av(pos,len: Word; keyoff_pos: Byte; slide_str: String): String; begin If (pos <= 255) then _macro_pos_str_av := byte2hex(pos)+'/'+byte2hex(len)+' '+slide_str+ note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)] else If (pos = IDLE) then _macro_pos_str_av := #250#250#12#250#250' '+slide_str+ note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)] else _macro_pos_str_av := byte2hex(len)+'/'+byte2hex(len)+' '+slide_str+ note_keyoff_str[(pos >= keyoff_pos) and (keyoff_pos > 0)]; end; var temp,temp2,atr1,atr2,atr3,atr4,xstart,ystart: Byte; temps,temps2,temps3: String; old_debugging,old_replay_forbidden: Boolean; old_play_status: tPLAY_STATUS; _ctrl_alt_flag, _reset_state: Boolean; _win_attr: array[Boolean] of Byte; _details_flag,_macro_details_flag: Boolean; fkey: Word; bckg_attr,current_track: Byte; label _jmp1; begin { DEBUG_INFO } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:DEBUG_INFO'; {$ENDIF} _ctrl_alt_flag := ctrl_pressed AND alt_pressed; _win_attr[FALSE] := debug_info_bckg+debug_info_border2; _win_attr[TRUE] := debug_info_bckg+debug_info_border; _reset_state := FALSE; If NOT _ctrl_alt_flag then begin temp := get_bank_position('?debug_info?details_flag',-1); Case temp of 0: begin _details_flag := FALSE; _macro_details_flag := FALSE; end; 1: begin _details_flag := TRUE; _macro_details_flag := FALSE; end; 2: begin _details_flag := TRUE; _macro_details_flag := TRUE; end; end; end; _jmp1: ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; centered_frame(xstart,ystart,83,songdata.nm_tracks+6, _win_title[_ctrl_alt_flag],_win_attr[_ctrl_alt_flag], debug_info_bckg+debug_info_title, frame_double); Repeat If _ctrl_alt_flag then begin _details_flag := shift_pressed; _macro_details_flag := NOT left_shift_pressed and right_shift_pressed; end; If _ctrl_alt_flag then If NOT _details_flag then ShowStr(screen_ptr,xstart+83-Length(_contxt_str),ystart+songdata.nm_tracks+6, _contxt_str, debug_info_bckg+debug_info_topic) else ShowStr(screen_ptr,xstart+83-Length(_contxt_str),ystart+songdata.nm_tracks+6, ExpStrL('',Length(_contxt_str),#205), debug_info_bckg+debug_info_border); If space_pressed and (play_status <> isStopped) then If NOT _ctrl_alt_flag and ctrl_pressed and NOT alt_pressed and NOT shift_pressed then begin debugging := FALSE; _reset_state := FALSE; end else If NOT _reset_state then begin _reset_state := TRUE; old_debugging := debugging; old_play_status := play_status; old_replay_forbidden := replay_forbidden; debugging := TRUE; play_status := isPlaying; replay_forbidden := FALSE; STATUS_LINE_refresh; end; If NOT _details_flag then begin ShowCStr(screen_ptr,xstart+2,ystart+1, debug_win_str1[1], debug_info_bckg+debug_info_topic,debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+2, debug_win_str1[2], debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+songdata.nm_tracks+3, debug_win_str1[3], debug_info_bckg+debug_info_border); If NOT _ctrl_alt_flag then ShowCStr(screen_ptr,xstart+76,ystart+songdata.nm_tracks+6,' [~1/3~] ', _win_attr[_ctrl_alt_flag], debug_info_bckg+debug_info_topic); end else If NOT _macro_details_flag then begin ShowCStr(screen_ptr,xstart+2,ystart+1, debug_win_str2[1], debug_info_bckg+debug_info_topic,debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+2, debug_win_str2[2], debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+songdata.nm_tracks+3, debug_win_str2[3], debug_info_bckg+debug_info_border); If NOT _ctrl_alt_flag then ShowCStr(screen_ptr,xstart+76,ystart+songdata.nm_tracks+6,' [~2/3~] ', _win_attr[_ctrl_alt_flag], debug_info_bckg+debug_info_topic); end else begin ShowCStr(screen_ptr,xstart+2,ystart+1, debug_win_str3[1], debug_info_bckg+debug_info_topic,debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+2, debug_win_str3[2], debug_info_bckg+debug_info_border); ShowStr(screen_ptr,xstart+2,ystart+songdata.nm_tracks+3, debug_win_str3[3], debug_info_bckg+debug_info_border); If NOT _ctrl_alt_flag then ShowCStr(screen_ptr,xstart+76,ystart+songdata.nm_tracks+6,' [~3/3~] ', _win_attr[_ctrl_alt_flag], debug_info_bckg+debug_info_topic); end; If NOT play_single_patt and NOT replay_forbidden and repeat_pattern then temps := '~'#19'~' else temps := #19; If NOT play_single_patt then ShowCStr(screen_ptr, xstart+2,ystart+songdata.nm_tracks+4, '~ORDER/PATTERN/ROW~ '+byte2hex(current_order)+'/'+ byte2hex(current_pattern)+'/'+ byte2hex(current_line), debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt) else ShowCStr(screen_ptr, xstart+2,ystart+songdata.nm_tracks+4, '~ORDER/PATTERN/ROW~ --/'+ byte2hex(current_pattern)+'/'+ byte2hex(current_line), debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); ShowCStr(screen_ptr, xstart+30,ystart+songdata.nm_tracks+4, temps, debug_info_bckg+debug_info_txt_hid, debug_info_bckg+debug_info_txt); If (tempo < 100) then If (tempo = 18) and timer_fix then temps := num2str(tempo,10)+#5+#174 else temps := num2str(tempo,10)+#174 else temps := num2str(tempo,10)+#174; If (_macro_speedup = 1) then temps2 := temps else begin temp := calc_max_speedup(tempo); If (_macro_speedup <= temp) then temps2 := Num2str(tempo*_macro_speedup,10)+#174 else temps2 := Num2str(tempo*temp,10)+#174; end; ShowCStr(screen_ptr, xstart+2,ystart+songdata.nm_tracks+5, '~SPEED/TEMPO/MACROS~ '+byte2hex(speed)+'/'+ ExpStrR(temps+'/'+temps2,9,' '), debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); Case current_tremolo_depth of 0: temps := '1dB'; 1: temps := '4.8dB'; end; Case current_vibrato_depth of 0: temps2 := '7% '; 1: temps2 := '14% '; end; ShowCStr(screen_ptr, xstart+36,ystart+songdata.nm_tracks+4, '~TREMOLO/ViBRATO DEPTH~ '+ temps+'/'+temps2, debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); ShowCStr(screen_ptr, xstart+36,ystart+songdata.nm_tracks+5, '~GLOBAL VOLUME~ '+ ExpStrR(Num2str(global_volume,16),2,'0'), debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); temps := ' '+ ExpStrL(Num2str(song_timer DIV 60,10),2,'0')+':'+ ExpStrL(Num2str(song_timer MOD 60,10),2,'0')+'.'+ CHR(48+song_timer_tenths DIV 10)+' '; If (play_status <> isStopped) then temps := '~'+temps+'~'; ShowCStr(screen_ptr, xstart+74,ystart+songdata.nm_tracks+4, temps, debug_info_bckg+debug_info_txt, debug_info_bckg+debug_info_hi_txt); temps := Bpm2str(calc_realtime_bpm_speed(tempo,speed,mark_line))+' BPM'; If (IRQ_freq_shift+playback_speed_shift > 0) then temps := temps+' [+'+Num2str(IRQ_freq_shift+playback_speed_shift,10)+#174']' else If (IRQ_freq_shift+playback_speed_shift < 0) then temps := temps+' [-'+Num2str(Abs(IRQ_freq_shift+playback_speed_shift),10)+#174']'; ShowStr(screen_ptr, xstart+62,ystart+songdata.nm_tracks+5, ExpStrL(temps,20,' '), debug_info_bckg+debug_info_bpm); current_track := count_channel(pattern_hpos); For temp := 1 to songdata.nm_tracks do begin If NOT _ctrl_alt_flag and (temp = current_track) then bckg_attr := debug_info_bckg2 else bckg_attr := debug_info_bckg; If channel_flag[temp] then If event_new[temp] then atr1 := bckg_attr+debug_info_hi_txt else atr1 := bckg_attr+debug_info_txt else atr1 := bckg_attr+debug_info_txt_hid; If channel_flag[temp] then If event_new[temp] then atr2 := bckg_attr+debug_info_hi_txt else atr2 := bckg_attr+debug_info_txt else atr2 := bckg_attr+debug_info_txt_hid; If channel_flag[temp] then If event_new[temp] then atr3 := bckg_attr+debug_info_hi_car else atr3 := bckg_attr+debug_info_car else atr3 := bckg_attr+debug_info_txt_hid; If channel_flag[temp] then If event_new[temp] then atr4 := bckg_attr+debug_info_hi_mod else atr4 := bckg_attr+debug_info_mod else atr4 := bckg_attr+debug_info_txt_hid; If percussion_mode and (temp in [16..20]) then temps := _perc_char[temp-15] else Case temp of 1: If (songdata.flag_4op OR 1 = songdata.flag_4op) then temps := #172 else temps := ' '; 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then temps := #173 else temps := ' '; 3: If (songdata.flag_4op OR 2 = songdata.flag_4op) then temps := #172 else temps := ' '; 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then temps := #173 else temps := ' '; 5: If (songdata.flag_4op OR 4 = songdata.flag_4op) then temps := #172 else temps := ' '; 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then temps := #173 else temps := ' '; 10: If (songdata.flag_4op OR 8 = songdata.flag_4op) then temps := #172 else temps := ' '; 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then temps := #173 else temps := ' '; 12: If (songdata.flag_4op OR $10 = songdata.flag_4op) then temps := #172 else temps := ' '; 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then temps := #173 else temps := ' '; 14: If (songdata.flag_4op OR $20 = songdata.flag_4op) then temps := #172 else temps := ' '; 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then temps := #173 else temps := ' '; else temps := ' '; end; ShowStr(screen_ptr,xstart+1,ystart+temp+2, temps, bckg_attr+debug_info_perc); ShowCStr(screen_ptr,xstart+2,ystart+temp+2, ExpStrL(Num2str(temp,10),2,' '), atr1, bckg_attr+debug_info_txt_hid); If NOT _details_flag then If (event_table[temp].instr_def in [1..255]) then begin temps := ExpStrR(cstr2str(Copy(songdata.instr_names[event_table[temp].instr_def],2,30)),30,' '); Delete(temps,7,1); Insert('~'#247'~',temps,7); end else temps := ExpStrR(' ~'#247'~',30+2,' ') else If (event_table[temp].instr_def in [1..255]) then temps := 'i'+byte2hex(event_table[temp].instr_def) else temps := ExpStrR('',3,' '); If (play_status = isStopped) and NOT debugging then temp2 := 3 else temp2 := panning_table[temp]; Case (songdata.lock_flags[temp] SHR 2 AND 3) of 0: temps2 := #250#24#25; 1: temps2 := 'C'#24#25; 2: temps2 := 'M'#24#25; 3: temps2 := '&'#24#25; end; If (songdata.lock_flags[temp] SHR 2 AND 3 = 0) or ((play_status = isStopped) and NOT debugging) then temps2 := '`'+temps2+'`'; If lockvol and (songdata.lock_flags[temp] OR $10 = songdata.lock_flags[temp]) then temps2 := temps2+'~'#179'~V+' else temps2 := temps2+'~'#179'~`V+`'; If lockVP and (songdata.lock_flags[temp] OR $20 = songdata.lock_flags[temp]) then temps2 := temps2+'~'#179'~P+' else temps2 := temps2+'~'#179'~`P+`'; If NOT (is_4op_chan(temp) and (temp in _4op_tracks_hi)) then temps3 := ExpStrL(Num2str(freqtable2[temp],16),4,'0') else temps3 := ' '; If NOT _details_flag then begin If pan_lock[temp] then ShowC3Str(screen_ptr,xstart+4,ystart+temp+2, '~'#179'~'+_panning[temp2]+'~'#179'~', atr2, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid) else ShowC3Str(screen_ptr,xstart+4,ystart+temp+2, '~'#179'~'+_panning[temp2]+'~'#179'~', atr3, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid); ShowC3Str(screen_ptr,xstart+8,ystart+temp+2, temps2+'~'#179'~', atr2, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid); ShowCStr(screen_ptr,xstart+18,ystart+temp+2, temps+'~'#179'~'+ note_str(event_table[temp].note,temp)+'~'#179'~'+ effect_str(event_table[temp].effect_def, event_table[temp].effect, event_table[temp].effect_def2)+'~'#179'~'+ effect_str(event_table[temp].effect_def2, event_table[temp].effect2, event_table[temp].effect_def)+'~'#179'~'+ temps3+'~'#179'~', atr1, bckg_attr+debug_info_border); If NOT (percussion_mode and (temp in [17..20])) then ShowCStr(screen_ptr,xstart+77,ystart+temp+2, ExpStrL(Num2str(carrier_vol[temp],16),2,'0')+'~'#179'~', atr3, bckg_attr+debug_info_border) else ShowCStr(screen_ptr,xstart+77,ystart+temp+2, ExpStrL(Num2str(carrier_vol[temp],16),2,'0')+'~'#179'~', bckg_attr+bckg_attr SHR 4, bckg_attr+debug_info_border); end else begin If pan_lock[temp] then ShowC3Str(screen_ptr,xstart+4,ystart+temp+2, '~'#179'~'+_panning[temp2]+'~'#179'~', atr2, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid) else ShowC3Str(screen_ptr,xstart+4,ystart+temp+2, '~'#179'~'+_panning[temp2]+'~'#179'~', atr3, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid); If NOT _macro_details_flag then begin ShowCStr(screen_ptr,xstart+8,ystart+temp+2, temps+'~'#179'~'+ note_str(event_table[temp].note,temp)+'~'#179'~'+ effect_str(event_table[temp].effect_def, event_table[temp].effect, event_table[temp].effect_def2)+'~'#179'~'+ effect_str(event_table[temp].effect_def2, event_table[temp].effect2, event_table[temp].effect_def)+'~'#179'~'+ temps3+'~'#179'~', atr1,bckg_attr+debug_info_border); If NOT (percussion_mode and (temp in [17..20])) then ShowStr(screen_ptr,xstart+40,ystart+temp+2, _connection[fmpar_table[temp].connect]+' '+ Num2str(fmpar_table[temp].feedb,16)+' ', atr1) else ShowStr(screen_ptr,xstart+40,ystart+temp+2, ExpStrL('',5,' '), atr1); If NOT (percussion_mode and (temp in [17..20])) then ShowCStr(screen_ptr,xstart+45,ystart+temp+2, Num2str(fmpar_table[temp].adsrw_car.attck,16)+ Num2str(fmpar_table[temp].adsrw_car.dec,16)+ Num2str(fmpar_table[temp].adsrw_car.sustn,16)+ Num2str(fmpar_table[temp].adsrw_car.rel,16)+' '+ Num2str(fmpar_table[temp].adsrw_car.wform,16)+' '+ Num2str(fmpar_table[temp].kslC,16)+' '+ Num2str(fmpar_table[temp].multipC,16)+' '+ _off_on[1,fmpar_table[temp].tremC]+ _off_on[2,fmpar_table[temp].vibrC]+ _off_on[3,fmpar_table[temp].ksrC]+ _off_on[4,fmpar_table[temp].sustC]+'~'#179'~', atr3, bckg_attr+debug_info_border) else ShowCStr(screen_ptr,xstart+45,ystart+temp+2, Num2str(fmpar_table[temp].adsrw_car.attck,16)+ Num2str(fmpar_table[temp].adsrw_car.dec,16)+ Num2str(fmpar_table[temp].adsrw_car.sustn,16)+ Num2str(fmpar_table[temp].adsrw_car.rel,16)+' '+ Num2str(fmpar_table[temp].adsrw_car.wform,16)+' '+ Num2str(fmpar_table[temp].kslC,16)+' '+ Num2str(fmpar_table[temp].multipC,16)+' '+ _off_on[1,fmpar_table[temp].tremC]+ _off_on[2,fmpar_table[temp].vibrC]+ _off_on[3,fmpar_table[temp].ksrC]+ _off_on[4,fmpar_table[temp].sustC]+'~'#179'~', bckg_attr+bckg_attr SHR 4, bckg_attr+debug_info_border); ShowCStr(screen_ptr,xstart+61,ystart+temp+2, Num2str(fmpar_table[temp].adsrw_mod.attck,16)+ Num2str(fmpar_table[temp].adsrw_mod.dec,16)+ Num2str(fmpar_table[temp].adsrw_mod.sustn,16)+ Num2str(fmpar_table[temp].adsrw_mod.rel,16)+' '+ Num2str(fmpar_table[temp].adsrw_mod.wform,16)+' '+ Num2str(fmpar_table[temp].kslM,16)+' '+ Num2str(fmpar_table[temp].multipM,16)+' '+ _off_on[1,fmpar_table[temp].tremM]+ _off_on[2,fmpar_table[temp].vibrM]+ _off_on[3,fmpar_table[temp].ksrM]+ _off_on[4,fmpar_table[temp].sustM]+'~'#179'~', atr4, bckg_attr+debug_info_border); end else begin ShowCStr(screen_ptr,xstart+8,ystart+temp+2, temps+'~'#179'~'+ note_str(event_table[temp].note,temp)+'~'#179'~'+ effect_str(event_table[temp].effect_def, event_table[temp].effect, event_table[temp].effect_def2)+'~'#179'~'+ effect_str(event_table[temp].effect_def2, event_table[temp].effect2, event_table[temp].effect_def)+'~'#179'~', atr1,bckg_attr+debug_info_border); ShowC3Str(screen_ptr,xstart+35,ystart+temp+2, _macro_str(_macro_pos_str_fm(macro_table[temp].fmreg_pos, songdata.instr_macros[macro_table[temp].fmreg_table].length, songdata.instr_macros[macro_table[temp].fmreg_table].keyoff_pos, songdata.instr_macros[macro_table[temp].fmreg_table].data[macro_table[temp].fmreg_pos].duration, songdata.instr_macros[macro_table[temp].fmreg_table].data[macro_table[temp].fmreg_pos].fm_data.FEEDBACK_FM SHR 5, songdata.instr_macros[macro_table[temp].fmreg_table].data[macro_table[temp].fmreg_pos].freq_slide), songdata.instr_macros[macro_table[temp].fmreg_table].length)+'~'#179'~'+ _macro_str(byte2hex(macro_table[temp].arpg_table)+#246+ _macro_pos_str_av(macro_table[temp].arpg_pos, songdata.macro_table[macro_table[temp].arpg_table].arpeggio.length, songdata.macro_table[macro_table[temp].arpg_table].arpeggio.keyoff_pos, ''), macro_table[temp].arpg_table)+'~'#179'~'+ _macro_str(byte2hex(macro_table[temp].vib_table)+#246+ _macro_pos_str_av(macro_table[temp].vib_pos, songdata.macro_table[macro_table[temp].vib_table].vibrato.length, songdata.macro_table[macro_table[temp].vib_table].vibrato.keyoff_pos, _freq_slide_str(songdata.macro_table[macro_table[temp].vib_table].vibrato.data[macro_table[temp].vib_pos])), macro_table[temp].vib_table)+'~'#179'~'+ temps3+'~'#179'~', atr1, bckg_attr+debug_info_border, bckg_attr+debug_info_txt_hid); end; If NOT (percussion_mode and (temp in [17..20])) then ShowCStr(screen_ptr,xstart+77,ystart+temp+2, ExpStrL(Num2str(carrier_vol[temp],16),2,'0')+'~'#179'~', atr3, bckg_attr+debug_info_border) else ShowCStr(screen_ptr,xstart+77,ystart+temp+2, ExpStrL(Num2str(carrier_vol[temp],16),2,'0')+'~'#179'~', bckg_attr+bckg_attr SHR 4, bckg_attr+debug_info_border); end; ShowCStr(screen_ptr,xstart+80,ystart+temp+2, ExpStrL(Num2str(modulator_vol[temp],16),2,'0')+' ', atr4,bckg_attr+debug_info_border); end; fkey := WORD_NULL; If _ctrl_alt_flag then If keypressed then keyboard_reset_buffer else else If keypressed then fkey := getkey; If scankey($39) { SPACE } then If (play_status = isStopped) then If (calc_pattern_pos(pattern_patt) <> BYTE_NULL) then begin fade_out_playback(FALSE); calibrate_player(calc_pattern_pos(pattern_patt), pattern_page,TRUE,TRUE); If (play_status <> isStopped) then begin debugging := TRUE; play_status := isPlaying; replay_forbidden := FALSE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); tracing := TRUE; end; end else If (calc_pattern_pos(pattern_patt) = BYTE_NULL) then begin fade_out_playback(FALSE); play_single_patt := TRUE; no_sync_playing := TRUE; start_pattern := pattern_patt; start_line := pattern_page; start_playing; debugging := TRUE; tracing := TRUE; end else else If NOT tracing then begin debugging := TRUE; tracing := TRUE; end; Case fkey of kCtLEFT: If NOT debugging and (play_status = isPlaying) then rewind := TRUE; kCtRGHT: If NOT debugging and (play_status = isPlaying) then fast_forward := TRUE; kTAB: If NOT _details_flag then _details_flag := TRUE else If NOT _macro_details_flag then _macro_details_flag := TRUE else begin _details_flag := FALSE; _macro_details_flag := FALSE; end; kBkSPC: If NOT replay_forbidden then repeat_pattern := NOT repeat_pattern; kPgUP, kHOME: begin chan_pos := 1; pattern_hpos := 1; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kPgDOWN, kEND: begin chan_pos := last_chan_pos; pattern_hpos := last_hpos; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kUP: If (chan_pos > 1) then begin Dec(chan_pos); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (pattern_hpos > _pattedit_lastpos DIV MAX_TRACKS) then begin Dec(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kDOWN: If (chan_pos < last_chan_pos) then begin Inc(chan_pos); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end else If (pattern_hpos <= last_hpos-_pattedit_lastpos DIV MAX_TRACKS) then begin Inc(pattern_hpos,_pattedit_lastpos DIV MAX_TRACKS); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); end; kCHmins, kNPmins, kCtHOME: If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp > 0) and NOT (songdata.pattern_order[temp-1] < $80) do begin Dec(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp > 0) then begin Dec(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (fkey = kCtHOME) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCHplus, kNPplus, kCtEND: If NOT play_single_patt then begin temp := current_order; temp2 := current_line; While (temp < $7f) and (songdata.pattern_order[SUCC(temp)] > $80) do begin Inc(temp); {$IFDEF GO32V2} keyboard_reset_buffer_alt; {$ENDIF} end; If (temp < $7f) then begin Inc(temp); If (songdata.pattern_order[temp] < $80) then begin fade_out_playback(FALSE); If (fkey = kCtEND) then calibrate_player(temp,temp2,TRUE,FALSE) else calibrate_player(temp,0,TRUE,FALSE); end; end; end; kCtENTR: If play_single_patt then begin current_line := 0; PATTERN_ORDER_page_refresh(0); PATTERN_page_refresh(0); end else begin no_status_refresh := TRUE; fade_out_playback(FALSE); If (current_order < $7f) and (play_status <> isStopped) then If (songdata.pattern_order[SUCC(current_order)] < $80) then calibrate_player(SUCC(current_order),0,FALSE,FALSE) else If (calc_following_order(SUCC(current_order)) <> -1) then calibrate_player(calc_following_order(SUCC(current_order)),0,FALSE,FALSE) else else If (calc_following_order(0) <> -1) then calibrate_player(calc_following_order(0),0,FALSE,FALSE); no_status_refresh := FALSE; end; kAstrsk, kNPastr: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} For temp := 1 to songdata.nm_tracks do begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltS: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} begin For temp := 1 to songdata.nm_tracks do channel_flag[temp] := FALSE; For temp := 1 to songdata.nm_tracks do If (temp = count_channel(pattern_hpos)) then begin channel_flag[temp] := TRUE; If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then channel_flag[SUCC(temp)] := TRUE else channel_flag[PRED(temp)] := TRUE; end; For temp := 1 to songdata.nm_tracks do If NOT channel_flag[temp] then reset_chan_data(temp); end; kAltR: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} FillChar(channel_flag,songdata.nm_tracks,BYTE(TRUE)); kAlt1.. kAlt9: {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} begin If shift_pressed then temp := HI(fkey)-$77+10 else temp := HI(fkey)-$77; If (temp <= songdata.nm_tracks) then begin channel_flag[temp] := NOT channel_flag[temp]; If NOT channel_flag[temp] then reset_chan_data(temp); If is_4op_chan(temp) then If (temp in _4op_tracks_hi) then begin channel_flag[SUCC(temp)] := channel_flag[temp]; If NOT channel_flag[SUCC(temp)] then reset_chan_data(SUCC(temp)); end else If (temp in _4op_tracks_lo) then begin channel_flag[PRED(temp)] := channel_flag[temp]; If NOT channel_flag[PRED(temp)] then reset_chan_data(PRED(temp)); end; end; end; kAlt0: {$IFNDEF GO32V2} If (opl3_channel_recording_mode and (play_status <> isStopped)) then fkey := WORD_NULL else {$ENDIF} If (shift_pressed and (songdata.nm_tracks > 9)) or (songdata.nm_tracks = 10) then begin channel_flag[10] := NOT channel_flag[10]; If NOT channel_flag[10] then reset_chan_data(10); fkey := WORD_NULL; end; end; {$IFDEF GO32V2} realtime_gfx_poll_proc; keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (NOT _ctrl_alt_flag and ((fkey = kESC) or (fkey = kF1) or (fkey = kAlt0))) or (_ctrl_alt_flag and NOT (ctrl_pressed and alt_pressed)) or _force_program_quit; If NOT _ctrl_alt_flag then keyboard_reset_buffer; If NOT ((fkey = kF1) or (fkey = kAlt0)) and _reset_state then begin debugging := old_debugging; play_status := old_play_status; replay_forbidden := old_replay_forbidden; end; If NOT _ctrl_alt_flag then add_bank_position('?debug_info?details_flag',-1,ORD(_details_flag)+ORD(_macro_details_flag)); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+83+2; move_to_screen_area[4] := ystart+songdata.nm_tracks+6+1; move2screen; If (fkey = kF1) then begin realtime_gfx_poll_proc; no_step_debugging := TRUE; HELP('debug_info'); draw_screen; keyboard_reset_buffer; no_step_debugging := FALSE; IF NOT _force_program_quit then GOTO _jmp1; end; If (fkey = kAlt0) then {$IFNDEF GO32V2} If NOT (opl3_channel_recording_mode and (play_status <> isStopped)) then {$ENDIF} begin realtime_gfx_poll_proc; no_step_debugging := TRUE; If NOT percussion_mode then temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$1~6~$1~7~$1~8~$1~9~$2~0~$' else temps := '1~0~$1~1~$1~2~$1~3~$1~4~$1~5~$16 ~B~D$17 ~S~D$18 ~T~T$19 T~C~$20 ~H~H$'; temps := FlipStr(temps); For temp := 10 to 20 do If (temp > songdata.nm_tracks) then begin Delete(temps,Pos('~',temps),1); Delete(temps,Pos('~',temps),1); end; temps := FlipStr(temps); If (Pos('~',temps) <> 0) then begin chpos := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO TOGGLE TRACK ON/OFF$', temps, ' TRACK ON/OFF ',chpos); If (dl_environment.keystroke <> kESC) then begin channel_flag[9+chpos] := NOT channel_flag[9+chpos]; If NOT channel_flag[9+chpos] then reset_chan_data(9+chpos); If is_4op_chan(9+chpos) then If (9+chpos in [10,12,14]) then begin channel_flag[SUCC(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[SUCC(9+chpos)] then reset_chan_data(SUCC(9+chpos)); end else If (9+chpos in [11,13,15]) then begin channel_flag[PRED(9+chpos)] := channel_flag[9+chpos]; If NOT channel_flag[PRED(9+chpos)] then reset_chan_data(PRED(9+chpos)); end; end; end; draw_screen; keyboard_reset_buffer; no_step_debugging := FALSE; If NOT _force_program_quit then GOTO _jmp1; end; end; procedure _show_bpm_callback_LMS; begin ShowC3Str(screen_ptr,dl_environment.xpos+2,dl_environment.ypos+dl_environment.ysize, ExpC2StrL(' ~ '+Bpm2str(calc_bpm_speed(songdata.tempo,songdata.speed,dl_environment.cur_item))+' ~`BPM `', dl_environment.xsize-2,#205)+' ', dialog_background+dialog_border, dialog_def_bckg+dialog_input, dialog_def_bckg+dialog_input); end; procedure LINE_MARKING_SETUP; var old_bpm_proc: procedure; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:LINE_MARKING_SETUP'; {$ENDIF} old_bpm_proc := _show_bpm_realtime_proc; _show_bpm_realtime_proc := _show_bpm_callback_LMS; dl_setting.all_enabled := TRUE; mark_line := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS ~HOTKEY~ TO SETUP COUNTER$', '~1~$~2~$~3~$~4~$~5~$~6~$~7~$~8~$~9~$10$11$12$13$14$15$16$', ' LiNE MARKiNG SETUP (ROWS PER BEAT) ',mark_line); dl_setting.all_enabled := FALSE; _IRQFREQ_update_event := FALSE; _show_bpm_realtime_proc := old_bpm_proc; end; procedure OCTAVE_CONTROL; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:OCTAVE_CONTROL'; {$ENDIF} current_octave := Dialog('USE CURSOR KEYS OR DiRECTLY PRESS HOTKEY '+ 'TO CHANGE OCTAVE$', '~1~$~2~$~3~$~4~$~5~$~6~$~7~$~8~$', ' OCTAVE CONTROL ',current_octave); end; var _bpm_xstart: Byte; _bpm_ystart: Byte; const _song_variables_pos: Byte = 1; var bpm_str, bpm_inc_str,bpm_dec_str: String; is_num: Byte; procedure _show_bpm_callback_SV; begin Case _song_variables_pos of 3: begin is_num := Str2num(is_environment.cur_str,10); If is_num in [1..255] then bpm_str := ExpStrL(Bpm2str(calc_bpm_speed(is_num,songdata.speed,mark_line))+' BPM',9,' ') else bpm_str := ExpStrL(Bpm2str(calc_bpm_speed(songdata.tempo,songdata.speed,mark_line))+' BPM',9,' '); end; 4: begin is_num := Str2num(is_environment.cur_str,16); If is_num in [1..255] then bpm_str := ExpStrL(Bpm2str(calc_bpm_speed(songdata.tempo,is_num,mark_line))+' BPM',9,' ') else bpm_str := ExpStrL(Bpm2str(calc_bpm_speed(songdata.tempo,songdata.speed,mark_line))+' BPM',9,' '); end else bpm_str := ExpStrL(Bpm2str(calc_bpm_speed(songdata.tempo,songdata.speed,mark_line))+' BPM',9,' '); end; ShowStr(screen_ptr,_bpm_xstart,_bpm_ystart, bpm_str, dialog_background+dialog_misc_indic); end; procedure _show_current_bpm_with_hints; begin Case _song_variables_pos of 3: begin is_num := Str2num(is_environment.cur_str,10); If (is_num in [1..254]) then bpm_inc_str := '`(`~+~`)` '+ExpStrL(Bpm2str(calc_bpm_speed(is_num+1,songdata.speed,mark_line))+' `BPM`',11,' ') else bpm_inc_str := ExpStrL('',13,' '); If (is_num in [2..255]) then bpm_dec_str := '`(`~-~`)` '+ExpStrL(Bpm2str(calc_bpm_speed(is_num-1,songdata.speed,mark_line))+' `BPM`',11,' ') else bpm_dec_str := ExpStrL('',13,' '); end; 4: begin is_num := Str2num(is_environment.cur_str,16); If (is_num in [1..254]) then bpm_inc_str := '`(`~+~`)` '+ExpStrL(Bpm2str(calc_bpm_speed(songdata.tempo,is_num+1,mark_line))+' `BPM`',11,' ') else bpm_inc_str := ExpStrL('',13,' '); If (is_num in [2..255]) then bpm_dec_str := '`(`~-~`)` '+ExpStrL(Bpm2str(calc_bpm_speed(songdata.tempo,is_num-1,mark_line))+' `BPM`',11,' ') else bpm_dec_str := ExpStrL('',13,' '); end; end; ShowC3Str(screen_ptr,_bpm_xstart-4,_bpm_ystart+1, bpm_inc_str, dialog_background+dialog_context_dis, dialog_background+dialog_title, dialog_background+dialog_contxt_dis2); If (CutStr(bpm_inc_str) <> '') then ShowC3Str(screen_ptr,_bpm_xstart-4,_bpm_ystart+2, bpm_dec_str, dialog_background+dialog_context_dis, dialog_background+dialog_title, dialog_background+dialog_contxt_dis2) else begin ShowC3Str(screen_ptr,_bpm_xstart-4,_bpm_ystart+1, bpm_dec_str, dialog_background+dialog_context_dis, dialog_background+dialog_title, dialog_background+dialog_contxt_dis2); ShowC3Str(screen_ptr,_bpm_xstart-4,_bpm_ystart+2, bpm_inc_str, dialog_background+dialog_context_dis, dialog_background+dialog_title, dialog_background+dialog_contxt_dis2); end; end; procedure SONG_VARIABLES; const new_keys: array[1..29] of Word = (kF1,kESC,kENTER,kTAB,kShTAB,kUP,kDOWN,kCtENTR, kAltN,kAltE,kAltT,kAltS,kAltR,kAltD,kAltO,kAltI, kAltA,kAltL,kAltB,kAltH,kAltF,kAltX,kAltU,kAltK, kAltG,kAltM,kAltC,kAltV,kAltP); var old_keys: array[1..7] of Word; pos,pos_4op,temp,temp1,temp2,temp3: Byte; temps: String; xstart,ystart: Byte; attr: array[1..163] of Word; status_backup: Record replay_forbidden: Boolean; play_status: tPLAY_STATUS; end; const RANGE_PAN_LO = 18; RANGE_PAN_HI = 77; RANGE_PAN: Set of Byte = [RANGE_PAN_LO..RANGE_PAN_HI]; RANGE_4OP_LO = 78; RANGE_4OP_HI = 83; RANGE_4OP: Set of Byte = [RANGE_4OP_LO..RANGE_4OP_HI]; RANGE_LCK_LO = 84; RANGE_LCK_HI = 163; RANGE_LCK: Set of Byte = [RANGE_LCK_LO..RANGE_LCK_HI]; _on_off: array[0..1] of Char = #250#251; _4op_str: array[1..6] of String = ('1 '#241'2 ','3 '#241'4 ','5 '#241'6 ', '10'#241'11 ','12'#241'13 ','14'#241'15 '); _pan_pos: array[0..2] of Byte = (1,0,2); _left_pos_pan: array[1..60] of Byte = (2, 18,19, {1} 87, 21,22, {2} 91, 24,25, {3} 3, 27,28, {4} 5, 30,31, {5} 17, 33,34, {6} 107,36,37, {7} 78, 39,40, {8} 79, 42,43, {9} 80, 45,46, {10} 81, 48,49, {11} 82, 51,52, {12} 83, 54,55, {13} 12, 57,58, {14} 139,60,61, {15} 13, 63,64, {16} 14, 66,67, {17} 151,69,70, {18} 15, 72,73, {19} 16, 75,76); {20} _left_pos_lck: array[1..80] of Byte = (20,84, 85, 86, {1} 23,88, 89, 90, {2} 26,92, 93, 94, {3} 29,96, 97, 98, {4} 32,100,101,102, {5} 35,104,105,106, {6} 38,108,109,110, {7} 41,112,113,114, {8} 44,116,117,118, {9} 47,120,121,122, {10} 50,124,125,126, {11} 53,128,129,130, {12} 56,132,133,134, {13} 59,136,137,138, {14} 62,140,141,142, {15} 65,144,145,146, {16} 68,148,149,150, {17} 71,152,153,154, {18} 74,156,157,158, {19} 77,160,161,162); {20} _right_pos_pan: array[1..60] of Byte = (19,20,84, {1} 22,23,88, {2} 25,26,92, {3} 28,29,96, {4} 31,32,100, {5} 34,35,104, {6} 37,38,108, {7} 40,41,112, {8} 43,44,116, {9} 46,47,120, {10} 49,50,124, {11} 52,53,128, {12} 55,56,132, {13} 58,59,136, {14} 61,62,140, {15} 64,65,144, {16} 67,68,148, {17} 70,71,152, {18} 73,74,156, {19} 76,77,160); {20} _right_pos_lck: array[1..80] of Byte = (85, 86, 87, 0, {1} 89, 90, 91, 0, {2} 93, 94, 95, 0, {3} 97, 98, 99, 0, {4} 101,102,103,0, {5} 105,106,107,0, {6} 109,110,111,0, {7} 113,114,115,0, {8} 117,118,119,0, {9} 121,122,123,0, {10} 125,126,127,0, {11} 129,130,131,0, {12} 133,134,135,0, {13} 137,138,139,0, {14} 141,142,143,0, {15} 145,146,147,0, {16} 149,150,151,0, {17} 153,154,155,0, {18} 157,158,159,0, {19} 161,162,163,1); {20} _right_pos_lck_def: array[1..20-1] of Record variant1, variant2: Byte; end = ( (variant1: 21; variant2: 3), {1} (variant1: 24; variant2: 3), {2} (variant1: 3; variant2: 3), {3} (variant1: 4; variant2: 4), {4} (variant1: 17; variant2: 17), {5} (variant1: 36; variant2: 6), {6} (variant1: 6; variant2: 6), {7} (variant1: 7; variant2: 7), {8} (variant1: 8; variant2: 8), {9} (variant1: 81; variant2: 81), {10} (variant1: 82; variant2: 82), {11} (variant1: 9; variant2: 9), {12} (variant1: 10; variant2: 10), {13} (variant1: 60; variant2: 13), {14} (variant1: 13; variant2: 13), {15} (variant1: 14; variant2: 14), {16} (variant1: 69; variant2: 15), {17} (variant1: 15; variant2: 15), {18} (variant1: 16; variant2: 16)); {19} _left_pos_4op: array[1..6] of Byte = (6,7,8,0,0,11); _right_pos_4op: array[1..6] of Byte = (0,0,0,0,0,0); _up_pos_4op: array[1..6] of Byte = (0,78,79,80,81,82); _down_pos_4op: array[1..6] of Byte = (79,80,81,82,83,10); _right_pos_4op_def: array[1..6] of Record variant1, variant2: Byte; end = ( (variant1: 39; variant2: 7), (variant1: 42; variant2: 8), (variant1: 45; variant2: 81), (variant1: 48; variant2: 82), (variant1: 51; variant2: 9), (variant1: 54; variant2: 10)); _old_pos_pan: Byte = RANGE_PAN_LO+1; _old_pos_4op: Byte = RANGE_4OP_LO; _old_pos_lck: Byte = RANGE_LCK_LO; var old_bpm_proc: procedure; 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 _check_key_shortcuts; begin If (pos in RANGE_PAN) then begin _old_pos_pan := RANGE_PAN_LO+1+(pos-RANGE_PAN_LO) DIV 3*3; _old_pos_lck := RANGE_LCK_LO+(pos-RANGE_PAN_LO) DIV 3*4; end else If (pos in RANGE_4OP) then _old_pos_4op := pos else If (pos in RANGE_LCK) then begin _old_pos_pan := RANGE_PAN_LO+1+(pos-RANGE_LCK_LO) DIV 4*3; _old_pos_lck := RANGE_LCK_LO+(pos MOD 4)+(pos-RANGE_LCK_LO) DIV 4*4; end; Case is_environment.keystroke of kAltN: pos := 1; kAltE: pos := 2; kAltT: pos := 3; kAltS: pos := 4; kAltR: pos := 5; kAltD: pos := 17; kAltO: pos := 6; kAltI: pos := 7; kAltA: pos := 8; kAltL: If (tremolo_depth = 0) then pos := 9 else pos := 10; kAltB: If (vibrato_depth = 0) then pos := 11 else pos := 12; kAltH: pos := 13; kAltF: pos := 14; kAltX: pos := 15; kAltU: pos := 16; kAltK: begin If (_old_pos_4op in RANGE_4OP) then pos := _old_pos_4op else pos := RANGE_4OP_LO; pos_4op := 0; end; kAltG: If (_old_pos_pan in RANGE_PAN) then pos := _old_pos_pan else pos := RANGE_PAN_LO+1; kAltM: If (_old_pos_lck in RANGE_LCK) then pos := RANGE_LCK_LO+((_old_pos_lck-RANGE_LCK_LO) DIV 4)*4 else pos := RANGE_LCK_LO; kAltC: If (_old_pos_lck in RANGE_LCK) then pos := RANGE_LCK_LO+1+((_old_pos_lck-RANGE_LCK_LO) DIV 4)*4 else pos := RANGE_LCK_LO+1; kAltV: If (_old_pos_lck in RANGE_LCK) then pos := RANGE_LCK_LO+2+((_old_pos_lck-RANGE_LCK_LO) DIV 4)*4 else pos := RANGE_LCK_LO+2; kAltP: If (_old_pos_lck in RANGE_LCK) then pos := RANGE_LCK_LO+3+((_old_pos_lck-RANGE_LCK_LO) DIV 4)*4 else pos := RANGE_LCK_LO+3; end; end; label _jmp1,_end; begin { SONG_VARIABLES } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:SONG_VARIABLES'; {$ENDIF} songdata_crc := Update32(songdata,SizeOf(songdata),0); count_order(temp1); count_patterns(temp2); count_instruments(temp3); pos := min(get_bank_position('?song_variables_window?pos',-1),1); pos_4op := min(get_bank_position('?song_variables_window?pos_4op',-1),0); If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then begin songdata.macro_speedup := calc_max_speedup(songdata.tempo); If (play_status = isStopped) then macro_speedup := songdata.macro_speedup; end; _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,79,26,' SONG VARiABLES ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); centered_frame_vdest := screen_ptr; move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+79+2; move_to_screen_area[4] := ystart+26+1; move2screen_alt; move_to_screen_area[1] := xstart+1; move_to_screen_area[2] := ystart+1; move_to_screen_area[3] := xstart+78; move_to_screen_area[4] := ystart+25; _bpm_xstart := xstart+39; _bpm_ystart := ystart+7; old_bpm_proc := _show_bpm_realtime_proc; _show_bpm_realtime_proc := _show_bpm_callback_SV; ShowCStr(ptr_temp_screen,xstart+2,ystart+6, 'iNSTRUMENTS: ~'+Num2str(temp3,10)+'/255~ ', dialog_background+dialog_text, dialog_background+dialog_context_dis); ShowCStr(ptr_temp_screen,xstart+25,ystart+6, 'PATTERNS: ~'+Num2str(temp2,10)+'/'+Num2str(max_patterns,10)+'~ ', dialog_background+dialog_text, dialog_background+dialog_context_dis); ShowCStr(ptr_temp_screen,xstart+2,ystart+7, 'ORDER LiST ENTRiES: ~'+Num2str(temp1,10)+'/128~ ', dialog_background+dialog_text, dialog_background+dialog_context_dis); ShowStr(ptr_temp_screen,xstart+51,ystart+2, 'iNiTiAL LOCK SETTiNGS', dialog_background+dialog_context_dis); ShowStr(ptr_temp_screen,xstart+51,ystart+3, ExpStrL('',27,#154), dialog_background+dialog_context_dis); Move(is_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,is_setting.terminate_keys,SizeOf(new_keys)); songdata.songname := truncate_string(songdata.songname); songdata.composer := truncate_string(songdata.composer); If NOT _force_program_quit then Repeat If (songdata.nm_tracks < 11) then _left_pos_4op[4] := 80 else _left_pos_4op[4] := 123; If (songdata.nm_tracks < 12) then _left_pos_4op[5] := 81 else _left_pos_4op[5] := 127; For temp := 1 to 6 do If (songdata.nm_tracks < 8+temp-1) then _right_pos_4op[temp] := _right_pos_4op_def[temp].variant2 else _right_pos_4op[temp] := _right_pos_4op_def[temp].variant1; If (songdata.nm_tracks < 7) then _up_pos_4op[1] := 17 else _up_pos_4op[1] := 36; For temp := 1 to 19 do If (songdata.nm_tracks < temp+1) then _right_pos_lck[(temp-1)*4+4] := _right_pos_lck_def[temp].variant2 else _right_pos_lck[(temp-1)*4+4] := _right_pos_lck_def[temp].variant1; For temp2 := 1 to 18 do If (pos = temp2) then attr[temp2] := dialog_hi_text+(dialog_hi_text SHL 8) else attr[temp2] := dialog_text+(dialog_title SHL 8); If (pos = 4) then attr[5] := 0 else If (pos = 5) then attr[4] := 0 else attr[5] := 0; If (pos = 9) then attr[10] := 0 else If (pos = 10) then attr[9] := 0 else attr[10] := 0; If (pos = 11) then attr[12] := 0 else If (pos = 12) then attr[11] := 0 else attr[11] := 0; If (pos in RANGE_PAN) then attr[RANGE_PAN_LO] := dialog_hi_text+(dialog_hi_text SHL 8) else attr[RANGE_PAN_LO] := dialog_text+(dialog_title SHL 8); If (pos in RANGE_4OP) then attr[RANGE_4OP_LO] := dialog_hi_text+(dialog_hi_text SHL 8) else attr[RANGE_4OP_LO] := dialog_text+(dialog_title SHL 8); If (pos in RANGE_LCK) and (pos MOD 4 = 0) then attr[RANGE_LCK_LO] := dialog_hi_text+(dialog_hi_text SHL 8) else attr[RANGE_LCK_LO] := dialog_text+(dialog_title SHL 8); If (pos in RANGE_LCK) and (pos MOD 4 = 1) then attr[RANGE_LCK_LO+1] := dialog_hi_text+(dialog_hi_text SHL 8) else attr[RANGE_LCK_LO+1] := dialog_text+(dialog_title SHL 8); If (pos in RANGE_LCK) and (pos MOD 4 = 2) then attr[RANGE_LCK_LO+2] := dialog_hi_text+(dialog_hi_text SHL 8) else attr[RANGE_LCK_LO+2] := dialog_text+(dialog_title SHL 8); If (pos in RANGE_LCK) and (pos MOD 4 = 3) then attr[RANGE_LCK_LO+3] := dialog_hi_text+(dialog_hi_text SHL 8) else attr[RANGE_LCK_LO+3] := dialog_text+(dialog_title SHL 8); ShowCStr(ptr_temp_screen,xstart+34,ystart+12, #4#3' TRAC~K~S '#4#3'+', dialog_background+LO(attr[RANGE_4OP_LO]), dialog_background+HI(attr[RANGE_4OP_LO])); For temp := 1 to 6 do If (songdata.flag_4op OR (1 SHL PRED(temp)) = songdata.flag_4op) then ShowC3Str(ptr_temp_screen,xstart+34,ystart+13+temp-1, '[~'#251'~] '+_4op_str[temp]+'`[ ]`', dialog_background+dialog_text, dialog_background+dialog_item, dialog_background+dialog_text) else ShowC3Str(ptr_temp_screen,xstart+34,ystart+13+temp-1, '[~ ~] '+_4op_str[temp]+'`[ ]`', dialog_background+dialog_text, dialog_background+dialog_item, dialog_background+dialog_item_dis); ShowCStr(ptr_temp_screen,xstart+51,ystart+4, 'PANNiN~G~', dialog_background+LO(attr[RANGE_PAN_LO]), dialog_background+HI(attr[RANGE_PAN_LO])); ShowStr(ptr_temp_screen,xstart+51,ystart+5, #170' c '#171, dialog_background+LO(attr[18])); ShowVCStr(ptr_temp_screen,xstart+64,ystart+4, '~M~'#31, dialog_background+LO(attr[RANGE_LCK_LO]), dialog_background+HI(attr[RANGE_LCK_LO])); ShowVStr(ptr_temp_screen,xstart+65,ystart+4, #10, dialog_background+LO(attr[RANGE_LCK_LO])); ShowVCStr(ptr_temp_screen,xstart+68,ystart+4, '~C~'#31, dialog_background+LO(attr[RANGE_LCK_LO+1]), dialog_background+HI(attr[RANGE_LCK_LO+1])); ShowVStr(ptr_temp_screen,xstart+69,ystart+4, #10, dialog_background+LO(attr[RANGE_LCK_LO+1])); ShowVCStr(ptr_temp_screen,xstart+72,ystart+4, '~V~'#31, dialog_background+LO(attr[RANGE_LCK_LO+2]), dialog_background+HI(attr[RANGE_LCK_LO+2])); ShowVStr(ptr_temp_screen,xstart+73,ystart+4, '+', dialog_background+LO(attr[RANGE_LCK_LO+2])); ShowVCStr(ptr_temp_screen,xstart+76,ystart+4, '~P~'#31, dialog_background+LO(attr[RANGE_LCK_LO+3]), dialog_background+HI(attr[RANGE_LCK_LO+3])); ShowVStr(ptr_temp_screen,xstart+77,ystart+4, '+', dialog_background+LO(attr[RANGE_LCK_LO+3])); temps := ''; For temp := 1 to 6 do If (songdata.lock_flags[_4op_main_chan[temp]] OR $40 = songdata.lock_flags[_4op_main_chan[temp]]) or (songdata.lock_flags[PRED(_4op_main_chan[temp])] OR $40 = songdata.lock_flags[PRED(_4op_main_chan[temp])]) then temps := temps+#251 else temps := temps+' '; ShowVStr(ptr_temp_screen,xstart+46,ystart+13, temps, dialog_background++dialog_item); For temp := 1 to 20 do If (temp <= songdata.nm_tracks) then begin ShowCStr(ptr_temp_screen,xstart+51,ystart+6+temp-1, voice_pan_str[songdata.lock_flags[temp] AND 3], dialog_background+dialog_text, dialog_background+dialog_item); ShowCStr(ptr_temp_screen,xstart+60,ystart+6+temp-1, '~'+ExpStrL(Num2str(temp,10),2,' ')+'~ '+ _on_off[songdata.lock_flags[temp] SHR 3 AND 1]+' ~'#246'~ '+ _on_off[songdata.lock_flags[temp] SHR 2 AND 1]+' ~'#246'~ '+ _on_off[songdata.lock_flags[temp] SHR 4 AND 1]+' ~'#246'~ '+ _on_off[songdata.lock_flags[temp] SHR 5 AND 1], dialog_background+dialog_item, dialog_background+dialog_context_dis); end else ShowStr(ptr_temp_screen,xstart+51,ystart+6+temp-1, voice_pan_str[3]+' '+ExpStrL(Num2str(temp,10),2,' ')+ ' '#250' '#246' '#250' '#246' '#250' '#246' '#250, dialog_background+dialog_hid); temps := ''; For temp := 1 to songdata.nm_tracks do If percussion_mode and (temp in [16..20]) then temps := temps+_perc_char[temp-15] else Case temp of 1: If (songdata.flag_4op OR 1 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 2: If (songdata.flag_4op OR 1 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 3: If (songdata.flag_4op OR 2 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 4: If (songdata.flag_4op OR 2 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 5: If (songdata.flag_4op OR 4 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 6: If (songdata.flag_4op OR 4 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 10: If (songdata.flag_4op OR 8 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 11: If (songdata.flag_4op OR 8 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 12: If (songdata.flag_4op OR $10 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 13: If (songdata.flag_4op OR $10 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; 14: If (songdata.flag_4op OR $20 = songdata.flag_4op) then temps := temps+#172 else temps := temps+' '; 15: If (songdata.flag_4op OR $20 = songdata.flag_4op) then temps := temps+#173 else temps := temps+' '; else temps := temps+' '; end; ShowVStr(ptr_temp_screen,xstart+50,ystart+6, ExpStrR(temps,20,' '), dialog_background+dialog_misc_indic); ShowCStr(ptr_temp_screen,xstart+2,ystart+1, 'SONG~N~AME', dialog_background+LO(attr[1]), dialog_background+HI(attr[1])); ShowCStr(ptr_temp_screen,xstart+2,ystart+3, 'COMPOS~E~R', dialog_background+LO(attr[2]), dialog_background+HI(attr[2])); ShowCStr(ptr_temp_screen,xstart+2,ystart+9, 'SONG ~T~EMPO', dialog_background+LO(attr[3]), dialog_background+HI(attr[3])); ShowCStr(ptr_temp_screen,xstart+2,ystart+10, 'SONG ~S~PEED', dialog_background+LO(attr[4])+LO(attr[5]), dialog_background+HI(attr[4])+HI(attr[5])); ShowC3Str(ptr_temp_screen,xstart+26,ystart+10, '[ ] ~`R`ESET~', dialog_background+dialog_text, dialog_background+LO(attr[4])+LO(attr[5]), dialog_background+HI(attr[4])+HI(attr[5])); ShowC3Str(ptr_temp_screen,xstart+2,ystart+11, '~MACRO`D`EF.~ '#7, dialog_background+dialog_text, dialog_background+LO(attr[17]), dialog_background+HI(attr[17])); ShowCStr(ptr_temp_screen, xstart+31,ystart+7, 'RHYTHM: ~'+ExpStrL(Bpm2str(calc_bpm_speed(songdata.tempo,songdata.speed,mark_line))+' BPM',9,' '), dialog_background+dialog_text, dialog_background+dialog_misc_indic); If speed_update then ShowStr(ptr_temp_screen,xstart+27,ystart+10, #251, dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+27,ystart+10, ' ', dialog_background+dialog_item); ShowC3Str(ptr_temp_screen,xstart+2,ystart+13, '[ ] ~TRACK VOLUME L`O`CK~', dialog_background+dialog_text, dialog_background+LO(attr[6]), dialog_background+HI(attr[6])); ShowC3Str(ptr_temp_screen,xstart+2,ystart+14, '[ ] ~TRACK PANN`i`NG LOCK~', dialog_background+dialog_text, dialog_background+LO(attr[7]), dialog_background+HI(attr[7])); ShowC3Str(ptr_temp_screen,xstart+2,ystart+15, '[ ] ~VOLUME PE`A`K LOCK~', dialog_background+dialog_text, dialog_background+LO(attr[8]), dialog_background+HI(attr[8])); If lockvol then ShowStr(ptr_temp_screen,xstart+3,ystart+13,#251,dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+13,' ',dialog_background+dialog_item); If panlock then ShowStr(ptr_temp_screen,xstart+3,ystart+14,#251,dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+14,' ',dialog_background+dialog_item); If lockVP then ShowStr(ptr_temp_screen,xstart+3,ystart+15,#251,dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+15,' ',dialog_background+dialog_item); ShowCStr(ptr_temp_screen,xstart+2,ystart+17, 'TREMO~L~O DEPTH', dialog_background+LO(attr[9])+LO(attr[10]), dialog_background+HI(attr[9])+HI(attr[10])); ShowStr(ptr_temp_screen,xstart+2,ystart+18, '( ) 1 dB',dialog_background+dialog_text); ShowStr(ptr_temp_screen,xstart+2,ystart+19, '( ) 4.8 dB',dialog_background+dialog_text); If (tremolo_depth = 0) then ShowVStr(ptr_temp_screen,xstart+3,ystart+18,#11' ',dialog_background+dialog_item) else ShowVStr(ptr_temp_screen,xstart+3,ystart+18,' '#11,dialog_background+dialog_item); ShowCStr(ptr_temp_screen,xstart+18,ystart+17, 'Vi~B~RATO DEPTH', dialog_background+LO(attr[11])+LO(attr[12]), dialog_background+HI(attr[11])+HI(attr[12])); ShowStr(ptr_temp_screen,xstart+18,ystart+18, '( ) 7%',dialog_background+dialog_text); ShowStr(ptr_temp_screen,xstart+18,ystart+19, '( ) 14%',dialog_background+dialog_text); If (vibrato_depth = 0) then ShowVStr(ptr_temp_screen,xstart+19,ystart+18,#11' ',dialog_background+dialog_item) else ShowVStr(ptr_temp_screen,xstart+19,ystart+18,' '#11,dialog_background+dialog_item); ShowCStr(ptr_temp_screen,xstart+2,ystart+21, 'PATTERN LENGT~H~', dialog_background+LO(attr[13]), dialog_background+HI(attr[13])); ShowCStr(ptr_temp_screen,xstart+2,ystart+22, 'NUMBER O~F~ TRACKS', dialog_background+LO(attr[14]), dialog_background+HI(attr[14])); ShowC3Str(ptr_temp_screen,xstart+2,ystart+24, '[ ] ~PERCUSSiON TRACK E`X`TENSiON ('#160','#161','#162','#163','#164')~', dialog_background+dialog_text, dialog_background+LO(attr[15]), dialog_background+HI(attr[15])); If percussion_mode then ShowStr(ptr_temp_screen,xstart+3,ystart+24,#251,dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+24,' ',dialog_background+dialog_item); ShowC3Str(ptr_temp_screen,xstart+2,ystart+25, '[ ] ~VOL`U`ME SCALiNG~', dialog_background+dialog_text, dialog_background+LO(attr[16]), dialog_background+HI(attr[16])); If volume_scaling then ShowStr(ptr_temp_screen,xstart+3,ystart+25, #251, dialog_background+dialog_item) else ShowStr(ptr_temp_screen,xstart+3,ystart+25, ' ', dialog_background+dialog_item); is_setting.append_enabled := TRUE; is_environment.locate_pos := 1; ShowStr(ptr_temp_screen,xstart+2,ystart+2, ExpStrR(songdata.songname,46,' '), dialog_input_bckg+dialog_input); ShowStr(ptr_temp_screen,xstart+2,ystart+4, ExpStrR(songdata.composer,46,' '), dialog_input_bckg+dialog_input); ShowCStr(ptr_temp_screen,xstart+13,ystart+9, ExpStrR(Num2str(songdata.tempo,10),4,' ')+ '~ {1..255}~', dialog_input_bckg+dialog_input, dialog_background+dialog_text); ShowCStr(ptr_temp_screen,xstart+13,ystart+10, ExpStrR(Num2str(songdata.speed,16),4,' ')+ '~ {1..FF}~', dialog_input_bckg+dialog_input, dialog_background+dialog_text); ShowCStr(ptr_temp_screen,xstart+13,ystart+11, '~'+ExpStrR(Num2str(songdata.macro_speedup,10),4,' ')+'~'+ ' {1..'+Num2str(calc_max_speedup(songdata.tempo),10)+'} ', dialog_background+dialog_text, dialog_input_bckg+dialog_input); ShowCStr(ptr_temp_screen,xstart+19,ystart+21, ExpStrR(Num2str(songdata.patt_len,10),3,' ')+ '~ {1..256}~', dialog_input_bckg+dialog_input, dialog_background+dialog_text); ShowCStr(ptr_temp_screen,xstart+19,ystart+22, ExpStrR(Num2str(songdata.nm_tracks,10),3,' ')+ '~ {1..20}~', dialog_input_bckg+dialog_input, dialog_background+dialog_text); move2screen_alt; _song_variables_pos := pos; Case pos of 1: begin is_setting.character_set := [#32..#255]; temps := InputStr(songdata.songname,xstart+2,ystart+2, 42,42, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); songdata.songname := truncate_string(temps); _check_key_shortcuts; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 2 else If (is_environment.keystroke = kUP) then pos := 16 else If (is_environment.keystroke = kShTAB) then If (_old_pos_lck in RANGE_LCK) then pos := RANGE_LCK_LO+3+((_old_pos_lck-RANGE_LCK_LO) DIV 4)*4 else pos := RANGE_LCK_LO+3; end; 2: begin is_setting.character_set := [#32..#255]; temps := InputStr(songdata.composer,xstart+2,ystart+4, 42,42, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); songdata.composer := truncate_string(temps); _check_key_shortcuts; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 3 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 1; end; 3: begin is_setting.character_set := DEC_NUM_CHARSET; is_environment.ext_proc := _show_current_bpm_with_hints; is_environment.min_num := 1; is_environment.max_num := 255; Repeat temps := InputStr(Num2str(songdata.tempo,10), xstart+13,ystart+9,3,3, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,10) > 0) and (Str2num(temps,10) < 256)); is_environment.ext_proc := NIL; If ((Str2num(temps,10) > 0) and (Str2num(temps,10) < 256)) then begin songdata.tempo := Str2num(temps,10); If (play_status = isStopped) then tempo := songdata.tempo; end; If (calc_max_speedup(songdata.tempo) < songdata.macro_speedup) then songdata.macro_speedup := calc_max_speedup(songdata.tempo); _check_key_shortcuts; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 4 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 2; end; 4: begin is_setting.character_set := HEX_NUM_CHARSET; is_environment.ext_proc := _show_current_bpm_with_hints; is_environment.min_num := 1; is_environment.max_num := 255; Repeat temps := InputStr(Num2str(songdata.speed,16), xstart+13,ystart+10,2,2, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or (Str2num(temps,16) in [1..255]); is_environment.ext_proc := NIL; If (Str2num(temps,16) in [1..255]) then begin songdata.speed := Str2num(temps,16); If (play_status = isStopped) then speed := songdata.speed; end; _check_key_shortcuts; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) then pos := 5 else If (is_environment.keystroke = kDOWN) then pos := 17 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 3; end; 5: begin GotoXY(xstart+27,ystart+10); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kUP: pos := 3; kLEFT,kShTAB: pos := 4; kDOWN,kTAB,kENTER: pos := 17; kRIGHT: If (songdata.nm_tracks < 5) then pos := 17 else pos := 30; kSPACE: speed_update := NOT speed_update; end; end; 17: begin is_setting.character_set := DEC_NUM_CHARSET; is_environment.min_num := 1; is_environment.max_num := calc_max_speedup(songdata.tempo); Repeat temps := InputStr(Num2str(songdata.macro_speedup,10), xstart+13,ystart+11,4,4, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= calc_max_speedup(songdata.tempo))); If ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= calc_max_speedup(songdata.tempo))) then songdata.macro_speedup := Str2num(temps,10); _check_key_shortcuts; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 6 else If (is_environment.keystroke = kUP) then pos := 4 else If (is_environment.keystroke = kShTAB) then pos := 5; end; 6: begin GotoXY(xstart+3,ystart+13); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kLEFT: If (songdata.nm_tracks < 7) then pos := 17 else pos := 111; kUP,kShTAB: pos := 17; kDOWN,kTAB,kENTER: pos := 7; kRIGHT: pos := _old_pos_4op; kSPACE: lockvol := NOT lockvol; end; end; 7: begin GotoXY(xstart+3,ystart+14); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kUP,kShTAB: pos := 6; kLEFT: If (songdata.nm_tracks < 8) then pos := 78 else pos := 115; kTAB,kENTER: pos := 8; kDOWN: pos := 8; kRIGHT: pos := 79; kSPACE: panlock := NOT panlock; end; end; 8: begin GotoXY(xstart+3,ystart+15); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kUP: pos := 7; kLEFT: If (songdata.nm_tracks < 9) then pos := 79 else pos := 119; kShTAB: pos := 7; kDOWN: pos := 9; kTAB,kENTER: If (tremolo_depth = 0) then pos := 9 else pos := 10; kRIGHT: pos := 80; kSPACE: lockVP := NOT lockVP; end; end; 9: begin GotoXY(xstart+3,ystart+18); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kUP: pos := 8; kLEFT: If (songdata.nm_tracks < 12) then pos := 82 else pos := 131; kShTAB: pos := 8; kRIGHT,kTAB,kENTER: If (vibrato_depth = 0) then pos := 11 else pos := 12; kDOWN: pos := 10; kSPACE: tremolo_depth := 0; end; end; 10: begin GotoXY(xstart+3,ystart+19); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kUP: pos := 9; kShTAB: pos := 8; kDOWN: pos := 13; kTAB,kENTER: If (vibrato_depth = 0) then pos := 11 else pos := 12; kLEFT: If (songdata.nm_tracks < 13) then pos := 83 else pos := 135; kRIGHT: pos := 12; kSPACE: tremolo_depth := 1; end; end; 11: begin GotoXY(xstart+19,ystart+18); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kUP: pos := 8; kShTAB: If (tremolo_depth = 0) then pos := 9 else pos := 10; kDOWN: pos := 12; kTAB,kENTER: pos := 13; kLEFT: pos := 9; kRIGHT: pos := 83; kSPACE: vibrato_depth := 0; end; end; 12: begin GotoXY(xstart+19,ystart+19); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kUP: pos := 11; kShTAB: pos := 9; kDOWN,kTAB,kENTER: pos := 13; kLEFT: pos := 10; kRIGHT: If (songdata.nm_tracks < 14) then pos := 13 else pos := 57; kSPACE: vibrato_depth := 1; end; end; 13: begin is_setting.character_set := DEC_NUM_CHARSET; is_environment.min_num := 1; is_environment.max_num := 256; Repeat temps := InputStr(Num2str(songdata.patt_len,10), xstart+19,ystart+21,3,3, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= 256)); If ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= 256)) then begin If (current_line <= Str2num(temps,10)) then songdata.patt_len := Str2num(temps,10) else begin status_backup.replay_forbidden := replay_forbidden; status_backup.play_status := play_status; replay_forbidden := TRUE; If (play_status <> isStopped) then play_status := isPaused; pattern_break := TRUE; next_line := 0; ticks := tick0; update_song_position; songdata.patt_len := Str2num(temps,10); replay_forbidden := status_backup.replay_forbidden; play_status := status_backup.play_status; end; force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; _check_key_shortcuts; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 14 else If (is_environment.keystroke = kUP) then pos := 12 else If (is_environment.keystroke = kShTAB) then If (vibrato_depth = 0) then pos := 11 else pos := 12; end; 14: begin is_setting.character_set := DEC_NUM_CHARSET; is_environment.min_num := 1; is_environment.max_num := 20; Repeat temps := InputStr(Num2str(songdata.nm_tracks,10), xstart+19,ystart+22,2,2, dialog_input_bckg+dialog_input, dialog_def_bckg+dialog_def); until (is_environment.keystroke = kESC) or ((Str2num(temps,10) >= 1) and (Str2num(temps,10) <= 20)); If (Str2num(temps,10) >= 1) and (Str2num(temps,10) <= 20) then begin songdata.nm_tracks := Str2num(temps,10); If (songdata.nm_tracks > 18) and NOT percussion_mode then begin reset_player; percussion_mode := TRUE; _chan_n := _chpm_n; _chan_m := _chpm_m; _chan_c := _chpm_c; reset_player; end; If (songdata.nm_tracks < 15) and (songdata.flag_4op OR $20 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT $20; reset_player; end; If (songdata.nm_tracks < 13) and (songdata.flag_4op OR $10 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT $10; reset_player; end; If (songdata.nm_tracks < 11) and (songdata.flag_4op OR 8 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT 8; reset_player; end; If (songdata.nm_tracks < 6) and (songdata.flag_4op OR 4 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT 4; reset_player; end; If (songdata.nm_tracks < 4) and (songdata.flag_4op OR 2 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT 2; reset_player; end; If (songdata.nm_tracks < 2) and (songdata.flag_4op OR 1 = songdata.flag_4op) then begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT 1; reset_player; end; force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; _check_key_shortcuts; If (is_environment.keystroke = kENTER) or (is_environment.keystroke = kTAB) or (is_environment.keystroke = kDOWN) then pos := 15 else If (is_environment.keystroke = kUP) or (is_environment.keystroke = kShTAB) then pos := 13; end; 15: begin GotoXY(xstart+3,ystart+24); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kLEFT: If (songdata.nm_tracks < 18) then pos := 14 else pos := 155; kRIGHT: If (songdata.nm_tracks < 19) then pos := 16 else pos := 72; kUP,kShTAB: pos := 14; kDOWN,kTAB,kENTER: pos := 16; end; If (is_environment.keystroke = kSPACE) then If NOT percussion_mode then begin reset_player; songdata.nm_tracks := 20; percussion_mode := TRUE; _chan_n := _chpm_n; _chan_m := _chpm_m; _chan_c := _chpm_c; reset_player; If (play_status = isStopped) then init_buffers; end else begin reset_player; If (songdata.nm_tracks > 18) then songdata.nm_tracks := 18; percussion_mode := FALSE; _chan_n := _chmm_n; _chan_m := _chmm_m; _chan_c := _chmm_c; reset_player; If (play_status = isStopped) then init_buffers; end; force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; 16: begin GotoXY(xstart+3,ystart+25); ThinCursor; is_environment.keystroke := getkey; _check_key_shortcuts; Case is_environment.keystroke of kUP: pos := 15; kLEFT: If (songdata.nm_tracks < 19) then pos := 15 else pos := 159; kRIGHT: If (songdata.nm_tracks < 20) then pos := 1 else pos := 75; kShTAB: pos := 15; kDOWN: pos := 1; kTAB,kENTER: begin pos := _old_pos_4op; pos_4op := 0; end; kSPACE: volume_scaling := NOT volume_scaling; end; end; RANGE_PAN_LO..RANGE_PAN_HI: begin GotoXY(xstart+51+(pos-RANGE_PAN_LO) MOD 3*3,ystart+6+(pos-RANGE_PAN_LO) DIV 3); ThinCursor; is_environment.keystroke := getkey; _old_pos_pan := pos; _check_key_shortcuts; Case is_environment.keystroke of kLEFT: pos := _left_pos_pan[pos-RANGE_PAN_LO+1]; kRIGHT: pos := _right_pos_pan[pos-RANGE_PAN_LO+1]; kUP: If ((pos-RANGE_PAN_LO) DIV 3 > 0) then Dec(pos,3) else pos := pos+PRED(songdata.nm_tracks)*3; kDOWN: If ((pos-RANGE_PAN_LO) DIV 3 < PRED(songdata.nm_tracks)) then Inc(pos,3) else pos := 18+(pos-RANGE_PAN_LO) MOD 3; kShTAB: begin pos := _old_pos_4op; pos_4op := 0; end; kTAB,kENTER: pos := RANGE_LCK_LO+(pos-RANGE_PAN_LO) DIV 3*4; kSPACE: begin songdata.lock_flags[SUCC((pos-RANGE_PAN_LO) DIV 3)] := songdata.lock_flags[SUCC((pos-RANGE_PAN_LO) DIV 3)] AND NOT 3+ _pan_pos[(pos-RANGE_PAN_LO) MOD 3]; panlock := TRUE; end; end; end; RANGE_4OP_LO..RANGE_4OP_HI: begin If (pos_4op <> 0) and NOT (songdata.flag_4op OR (1 SHL PRED(pos-RANGE_4OP_LO+1)) = songdata.flag_4op) then pos_4op := 0; GotoXY(xstart+35+pos_4op*11,ystart+13+pos-RANGE_4OP_LO); ThinCursor; is_environment.keystroke := getkey; _old_pos_4op := pos; _check_key_shortcuts; Case is_environment.keystroke of kLEFT: If (pos_4op <> 0) then pos_4op := 0 else pos := _left_pos_4op[pos-RANGE_4OP_LO+1]; kRIGHT: If (pos_4op <> 1) and (songdata.flag_4op OR (1 SHL PRED(pos-RANGE_4OP_LO+1)) = songdata.flag_4op) then pos_4op := 1 else pos := _right_pos_4op[pos-RANGE_4OP_LO+1]; kUP: If (pos > 78) then pos := _up_pos_4op[pos-RANGE_4OP_LO+1] else pos := 17; kDOWN: pos := _down_pos_4op[pos-RANGE_4OP_LO+1]; kShTAB: pos := 16; kTAB,kENTER: If (_old_pos_pan in RANGE_PAN) then pos := _old_pos_pan else pos := 19; end; If (is_environment.keystroke = kSPACE) then Case pos_4op of 0: If (songdata.flag_4op OR (1 SHL PRED(pos-RANGE_4OP_LO+1)) <> songdata.flag_4op) then begin reset_player; Case (pos-RANGE_4OP_LO+1) of 1: songdata.nm_tracks := min(songdata.nm_tracks,2); 2: songdata.nm_tracks := min(songdata.nm_tracks,4); 3: songdata.nm_tracks := min(songdata.nm_tracks,6); 4: songdata.nm_tracks := min(songdata.nm_tracks,11); 5: songdata.nm_tracks := min(songdata.nm_tracks,13); 6: songdata.nm_tracks := min(songdata.nm_tracks,15); end; songdata.flag_4op := songdata.flag_4op OR (1 SHL PRED(pos-RANGE_4OP_LO+1)); reset_player; If (play_status = isStopped) then init_buffers; end else begin reset_player; songdata.flag_4op := songdata.flag_4op AND NOT (1 SHL PRED(pos-RANGE_4OP_LO+1)); reset_player; If (play_status = isStopped) then init_buffers; end; 1: begin songdata.lock_flags[_4op_main_chan[pos-RANGE_4OP_LO+1]] := songdata.lock_flags[_4op_main_chan[pos-RANGE_4OP_LO+1]] XOR $40; songdata.lock_flags[PRED(_4op_main_chan[pos-RANGE_4OP_LO+1])] := songdata.lock_flags[PRED(_4op_main_chan[pos-RANGE_4OP_LO+1])] XOR $40; end; end; force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; RANGE_LCK_LO..RANGE_LCK_HI: begin GotoXY(xstart+64+(pos-RANGE_LCK_LO) MOD 4*4,ystart+6+(pos-RANGE_LCK_LO) DIV 4); ThinCursor; is_environment.keystroke := getkey; _old_pos_lck := pos; _check_key_shortcuts; Case is_environment.keystroke of kLEFT: pos := _left_pos_lck[pos-RANGE_LCK_LO+1]; kRIGHT: pos := _right_pos_lck[pos-RANGE_LCK_LO+1]; kUP: If ((pos-RANGE_LCK_LO) DIV 4 > 0) then Dec(pos,4) else pos := RANGE_LCK_LO+PRED(songdata.nm_tracks)*4+(pos-RANGE_LCK_LO) MOD 4; kDOWN: If ((pos-RANGE_LCK_LO) DIV 4 < PRED(songdata.nm_tracks)) then Inc(pos,4) else pos := RANGE_LCK_LO+(pos-RANGE_LCK_LO) MOD 4; kShTAB: Case (pos-RANGE_LCK_LO) MOD 4 of 0: pos := RANGE_PAN_LO+1+(pos-RANGE_LCK_LO) DIV 4*3; else Dec(pos); end; kTAB, kENTER: Case (pos-RANGE_LCK_LO) MOD 4 of 3: pos := 1; else Inc(pos); end; kSPACE: Case (pos-RANGE_LCK_LO) MOD 4 of 0: songdata.lock_flags[SUCC((pos-RANGE_LCK_LO) DIV 4)] := songdata.lock_flags[SUCC((pos-RANGE_LCK_LO) DIV 4)] XOR 8; 1: songdata.lock_flags[SUCC((pos-RANGE_LCK_LO) DIV 4)] := songdata.lock_flags[SUCC((pos-RANGE_LCK_LO) DIV 4)] XOR 4; 2: begin songdata.lock_flags[SUCC((pos-RANGE_LCK_LO) DIV 4)] := songdata.lock_flags[SUCC((pos-RANGE_LCK_LO) DIV 4)] XOR $10; lockvol := TRUE; end; 3: begin songdata.lock_flags[SUCC((pos-RANGE_LCK_LO) DIV 4)] := songdata.lock_flags[SUCC((pos-RANGE_LCK_LO) DIV 4)] XOR $20; lockVP := TRUE; end; end; end; end; end; _end: {$IFDEF GO32V2} realtime_gfx_poll_proc; keyboard_reset_buffer_alt; {$ELSE} draw_screen; {$ENDIF} until (is_environment.keystroke = kESC) or (is_environment.keystroke = kF1) or (is_environment.keystroke = kCtENTR); If (nm_track_chan > songdata.nm_tracks) then nm_track_chan := songdata.nm_tracks; songdata.common_flag := BYTE(speed_update)+BYTE(lockvol) SHL 1+ BYTE(lockVP) SHL 2+ tremolo_depth SHL 3+ vibrato_depth SHL 4+ BYTE(panlock) SHL 5+ BYTE(percussion_mode) SHL 6+ BYTE(volume_scaling) SHL 7; If (Update32(songdata,SizeOf(songdata),0) <> songdata_crc) then module_archived := FALSE; If (play_status = isStopped) then begin current_tremolo_depth := tremolo_depth; current_vibrato_depth := vibrato_depth; end; add_bank_position('?song_variables_window?pos',-1,pos); add_bank_position('?song_variables_window?pos_4op',-1,pos_4op); HideCursor; Move(old_keys,is_setting.terminate_keys,SizeOf(old_keys)); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+79+2; move_to_screen_area[4] := ystart+26+1; move2screen; _IRQFREQ_update_event := FALSE; _show_bpm_realtime_proc := old_bpm_proc; is_environment.min_num := 1; is_environment.max_num := SizeOf(DWORD); If (is_environment.keystroke = kF1) then begin HELP('song_variables'); GOTO _jmp1; end; If (is_environment.keystroke = kCtENTR) then begin LINE_MARKING_SETUP; GOTO _jmp1; end; end; procedure NUKE; var temp,temp1,temp2: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:NUKE'; {$ENDIF} temp1 := Dialog('SO YOU THiNK iT REALLY SUCKS, DON''T YOU?$'+ 'WHAT DO YOU WANT TO BE NUKED?$', '~O~RDER$~P~ATTERNS$iNSTR [$~N~AMES$~R~EGS$~M~ACROS$]$ARP/~V~iB$~A~LL$', ' NUKE''M ',clearpos); clearpos := temp1; If (dl_environment.keystroke <> kESC) then begin If (temp1 = 1) then begin FillChar(songdata.pattern_order,SizeOf(songdata.pattern_order),$080); PATTERN_ORDER_page_refresh(pattord_page); end; If (temp1 = 2) then begin For temp := 1 to max_patterns DIV 8 do FillChar(pattdata^[PRED(temp)],8*PATTERN_SIZE,0); PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); For temp2 := 0 to $7f do songdata.pattern_names[temp2] := ' PAT_'+byte2hex(temp2)+' '#247' '; pattern_list__page := 1; end; If (temp1 = 4) then begin For temp2 := 1 to 255 do begin FillChar(songdata.instr_names[temp2][2],SizeOf(songdata.instr_names[temp2])-2,0); songdata.instr_names[temp2] := songdata.instr_names[temp2][1]+ 'iNS_'+byte2hex(temp2)+#247' '; end; end; If (temp1 = 5) then begin FillChar(songdata.instr_data,SizeOf(songdata.instr_data),0); FillChar(songdata.ins_4op_flags,SizeOf(songdata.ins_4op_flags),0); update_4op_flag_marks; end; If (temp1 = 6) then begin FillChar(songdata.instr_macros,SizeOf(songdata.instr_macros),0); _macro_editor__pos[FALSE] := 1; _macro_editor__fmreg_hpos[FALSE] := 1; _macro_editor__fmreg_hpos[TRUE] := 1; _macro_editor__fmreg_page[FALSE] := 1; _macro_editor__fmreg_page[TRUE] := 1; _macro_editor__fmreg_left_margin[FALSE] := 1; _macro_editor__fmreg_left_margin[TRUE] := 1; _macro_editor__fmreg_cursor_pos[FALSE] := 1; _macro_editor__fmreg_cursor_pos[TRUE] := 1; add_bank_position('?internal_instrument_data?macro?pos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_page',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_hpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_vpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_left_margin',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_cursor_pos',-1,1); end; If (temp1 = 8) then begin FillChar(songdata.macro_table,SizeOf(songdata.macro_table),0); _macro_editor__pos[TRUE] := 8; _macro_editor__arpeggio_page[FALSE] := 1; _macro_editor__arpeggio_page[TRUE] := 1; _macro_editor__vibrato_hpos[FALSE] := 1; _macro_editor__vibrato_hpos[TRUE] := 1; _macro_editor__vibrato_page[FALSE] := 1; _macro_editor__vibrato_page[TRUE] := 1; add_bank_position('?internal_instrument_data?macro_av?pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?arp_pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?vib_pos',-1,1); end; If (temp1 = 9) then begin fade_out_playback(FALSE); stop_playing; tempo := init_tempo; speed := init_speed; mark_line := 4; IRQ_freq_shift := 0; playback_speed_shift := 0; init_songdata; POSITIONS_reset; songdata_title := 'noname.'; FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); track_notes := FALSE; track_chan_start := 1; nm_track_chan := 1; remap_mtype := 1; remap_ins1 := 1; remap_ins2 := 1; remap_selection := 1; replace_selection := 1; replace_prompt := FALSE; replace_data.event_to_find.note := '???'; replace_data.event_to_find.inst := '??'; replace_data.event_to_find.fx_1 := '???'; replace_data.event_to_find.fx_2 := '???'; replace_data.new_event.note := '???'; replace_data.new_event.inst := '??'; replace_data.new_event.fx_1 := '???'; replace_data.new_event.fx_2 := '???'; current_inst := 1; pattern_list__page := 1; _macro_editor__pos[FALSE] := 1; _macro_editor__pos[TRUE] := 8; _macro_editor__fmreg_hpos[FALSE] := 1; _macro_editor__fmreg_hpos[TRUE] := 1; _macro_editor__fmreg_page[FALSE] := 1; _macro_editor__fmreg_page[TRUE] := 1; _macro_editor__fmreg_left_margin[FALSE] := 1; _macro_editor__fmreg_left_margin[TRUE] := 1; _macro_editor__fmreg_cursor_pos[FALSE] := 1; _macro_editor__fmreg_cursor_pos[TRUE] := 1; add_bank_position('?internal_instrument_data?macro?pos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_page',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_hpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_vpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_left_margin',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_cursor_pos',-1,1); _macro_editor__arpeggio_page[FALSE] := 1; _macro_editor__arpeggio_page[TRUE] := 1; _macro_editor__vibrato_hpos[FALSE] := 1; _macro_editor__vibrato_hpos[TRUE] := 1; _macro_editor__vibrato_page[FALSE] := 1; _macro_editor__vibrato_page[TRUE] := 1; add_bank_position('?internal_instrument_data?macro_av?pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?arp_pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?vib_pos',-1,1); add_bank_position('?song_variables_window?pos',-1,1); add_bank_position('?song_variables_window?pos_4op',-1,0); add_bank_position('?replace_window?pos',-1,1); add_bank_position('?replace_window?posfx',-1,1); add_bank_position('?message_board?hpos',-1,1); add_bank_position('?message_board?vpos',-1,1); For temp := 1 to 255 do begin add_bank_position('?instrument_editor?'+byte2hex(temp)+'?carrier',-1,1); add_bank_position('?instrument_editor?'+byte2hex(temp)+'?carrier?hpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(temp)+'?carrier?vpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(temp)+'?modulator?hpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(temp)+'?modulator?vpos',-1,1); end; For temp := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[temp] := temp; _rearrange_track_pos := 1; end else module_archived := FALSE; end; end; procedure MESSAGE_BOARD; const new_keys: array[1..21] of Word = (kF1,kESC,kENTER,kUP,kDOWN,kLEFT,kRIGHT, kHOME,kEND,kPgUP,kPGDOWN,kCtHOME,kCtEND, kCtPgUP,kCtPgDN,kTAB,kCtBkSp, kCtrlY,kDELETE,kBkSPC,kSPACE); var old_keys: array[1..21] of Word; old_append_enabled: Boolean; idx,idx2,vpos,vpos2,ref_vpos,old_vpos,hpos: Byte; xstart,ystart: Byte; flag: Boolean; fkey: Word; temps: String; p_mb: pMESSAGE_BOARD_DATA; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:MESSAGE_BOARD'; {$ENDIF} p_mb := Addr(songdata.reserved_data); If Empty(songdata.reserved_data,SizeOf(songdata.reserved_data)) then p_mb^.signature := MB_SIGNATURE else If (p_mb^.signature <> MB_SIGNATURE) then EXIT; is_environment.insert_mode := TRUE; _jmp1: If _force_program_quit then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); HideCursor; ScreenMemCopy(screen_ptr,ptr_temp_screen); centered_frame_vdest := ptr_temp_screen; centered_frame(xstart,ystart,MB_HSIZE+3,MB_VSIZE+1,' MESSAGE BOARD ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); move_to_screen_data := ptr_temp_screen; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+MB_HSIZE+3+2; move_to_screen_area[4] := ystart+MB_VSIZE+1+1; For idx := 1 to MB_VSIZE do ShowStr(centered_frame_vdest,xstart+2,ystart+1+idx-1, ExpStrR(p_mb^.data[idx],MB_HSIZE,' '), dl_setting.text_attr); move2screen_alt; centered_frame_vdest := screen_ptr; old_append_enabled := is_setting.append_enabled; is_setting.append_enabled := FALSE; Move(is_setting.terminate_keys,old_keys,SizeOf(old_keys)); Move(new_keys,is_setting.terminate_keys,SizeOf(new_keys)); hpos := min(get_bank_position('?message_board?hpos',-1),1); vpos := min(get_bank_position('?message_board?vpos',-1),1); If NOT _force_program_quit then Repeat If (hpos > Length(p_mb^.data[vpos])+1) then hpos := Length(p_mb^.data[vpos])+1; is_setting.insert_mode := is_environment.insert_mode; is_environment.locate_pos := hpos; is_setting.character_set := [#32..#255]; p_mb^.data[vpos] := InputStr(p_mb^.data[vpos],xstart+2, ystart+1+vpos-1,MB_HSIZE,MB_HSIZE, dl_setting.text_attr,dl_setting.text_attr); hpos := is_environment.locate_pos; fkey := is_environment.keystroke; ref_vpos := vpos; Case fkey of kUP: If (vpos > 1) then Dec(vpos); kDOWN: If (vpos < MB_VSIZE) then Inc(vpos); kLEFT: If (hpos > 1) then Dec(hpos) else If (vpos > 1) then begin Dec(vpos); If (Length(p_mb^.data[vpos]) <> 0) then hpos := max(Length(p_mb^.data[vpos])+1,MB_HSIZE) else begin hpos := MB_HSIZE; p_mb^.data[vpos] := ExpStrR('',MB_HSIZE,' '); end; end; kRIGHT: If (hpos < MB_HSIZE) then Inc(hpos) else If (vpos < MB_VSIZE) then begin Inc(vpos); hpos := 1; end; kCtPgUP: vpos := 1; kCtPgDN: vpos := MB_VSIZE; kPgUP: begin old_vpos := vpos; If (vpos > 1) then Repeat Dec(vpos); until (vpos = 1) or (CutStr(p_mb^.data[vpos]) <> ''); If (vpos = old_vpos) then vpos := 1; end; kPgDOWN: begin old_vpos := vpos; If (vpos < MB_VSIZE) then Repeat Inc(vpos); until (vpos = MB_VSIZE) or (CutStr(p_mb^.data[vpos]) <> ''); If (vpos = old_vpos) then vpos := MB_VSIZE; end; kHOME: If (hpos > 1) then hpos := 1 else vpos := 1; kCtHOME: begin vpos := 1; hpos := 1; end; kEND: If (hpos < Length(CutStrR(p_mb^.data[vpos],0))+1) then hpos := Length(CutStrR(p_mb^.data[vpos],0))+1 else If (hpos < MB_HSIZE) then hpos := MB_HSIZE else vpos := MB_VSIZE; kCtEND: begin vpos := MB_VSIZE; hpos := Length(p_mb^.data[MB_VSIZE])+1; end; kENTER: If (vpos < MB_VSIZE) then begin If (CutStr(p_mb^.data[MB_VSIZE]) = '') then begin If (hpos < MB_HSIZE) then begin temps := Copy(p_mb^.data[vpos],hpos,Length(p_mb^.data[vpos])); If (temps <> '') then Delete(p_mb^.data[vpos],hpos,Length(p_mb^.data[vpos])); end else temps := ''; For idx := MB_VSIZE downto vpos+1 do p_mb^.data[idx] := p_mb^.data[idx-1]; p_mb^.data[vpos+1] := temps; end; Inc(vpos); hpos := 1; end; kDELETE: If ((hpos = Length(p_mb^.data[vpos])) and (p_mb^.data[vpos][Length(p_mb^.data[vpos])] <> ' ')) or NOT ((CutStr(p_mb^.data[vpos]) = '') or (hpos >= Length(p_mb^.data[vpos])) or (CutStrR(p_mb^.data[vpos],hpos) <> CutStrR(p_mb^.data[vpos],0))) then Delete(p_mb^.data[vpos],hpos,1) else If (vpos < MB_VSIZE) then begin If (Length(CutStrR(p_mb^.data[vpos],hpos))+ Length(CutStrR(p_mb^.data[vpos+1],0)) <= MB_HSIZE) then begin p_mb^.data[vpos] := CutStrR(p_mb^.data[vpos],hpos)+ CutStrR(p_mb^.data[vpos+1],0); If (Length(p_mb^.data[vpos]) > MB_HSIZE) then Delete(p_mb^.data[vpos],MB_HSIZE+1,Length(p_mb^.data[vpos])); For idx := vpos+1 to MB_VSIZE-1 do p_mb^.data[idx] := p_mb^.data[idx+1]; p_mb^.data[MB_VSIZE] := ''; end; end; kTAB: begin If (vpos > 1) then begin vpos2 := vpos; Repeat Dec(vpos2); temps := CutStr(Copy(p_mb^.data[vpos2],hpos+1,Length(p_mb^.data[vpos2])-hpos)); until (vpos2 = 1) or (temps <> ''); If (hpos <= Length(p_mb^.data[vpos2])) then begin idx2 := hpos+1; While (idx2 < Length(p_mb^.data[vpos2])) and (p_mb^.data[vpos2][idx2] <> ' ') do Inc(idx2); While (idx2 < Length(p_mb^.data[vpos2])) and (p_mb^.data[vpos2][idx2] = ' ') do Inc(idx2); If (idx2-hpos > 1) then begin Insert(ExpStrL('',idx2-hpos,' '),p_mb^.data[vpos],hpos); Inc(hpos,idx2-hpos); end end end; If (Length(p_mb^.data[vpos]) > MB_HSIZE) then Delete(p_mb^.data[vpos],MB_HSIZE+1,Length(p_mb^.data[vpos])); end; kSPACE: begin If NOT ctrl_pressed then idx2 := vpos else idx2 := MB_VSIZE; flag := FALSE; For idx := vpos to idx2 do If (Length(CutStrR(p_mb^.data[idx],0)) = MB_HSIZE) then begin flag := TRUE; BREAK; end; If NOT flag and is_environment.insert_mode then For idx := vpos to idx2 do begin Insert(' ',p_mb^.data[idx],hpos); If (Length(p_mb^.data[idx]) > MB_HSIZE) then Delete(p_mb^.data[idx],MB_HSIZE+1,Length(p_mb^.data[idx])); end else If NOT is_environment.insert_mode then p_mb^.data[idx][hpos] := ' '; If (NOT flag or NOT is_environment.insert_mode) and (hpos < MB_HSIZE) then Inc(hpos); end; kCtBkSp: If NOT shift_pressed then begin If (hpos = MB_HSIZE) and (BYTE(p_mb^.data[vpos][0]) > 0) then Dec(BYTE(p_mb^.data[vpos][0])); While (p_mb^.data[vpos][hpos-1] in is_setting.word_characters) and (hpos > 1) do begin Dec(hpos); Delete(p_mb^.data[vpos],hpos,1); end; While NOT (p_mb^.data[vpos][hpos-1] in is_setting.word_characters) and (hpos > 1) do begin Dec(hpos); Delete(p_mb^.data[vpos],hpos,1); end; end else If (hpos < MB_HSIZE) then begin Dec(hpos); If (hpos <> 0) then For idx := vpos to MB_VSIZE do Delete(p_mb^.data[idx],hpos,1) else hpos := 1; end else For idx := vpos to MB_VSIZE do If (BYTE(p_mb^.data[idx][0]) > 0) then Dec(BYTE(p_mb^.data[idx][0])); kBkSPC: If (hpos > 1) then If (hpos < MB_HSIZE) or (p_mb^.data[vpos][hpos] = ' ') then begin Dec(hpos); Delete(p_mb^.data[vpos],hpos,1); end else If (BYTE(p_mb^.data[vpos][0]) > 0) then Dec(BYTE(p_mb^.data[vpos][0])) else else If (vpos > 1) then If (Length(CutStrR(p_mb^.data[vpos-1],0))+ Length(CutStrR(p_mb^.data[vpos],0)) <= MB_HSIZE) then begin Dec(vpos); hpos := Length(p_mb^.data[vpos])+1; p_mb^.data[vpos] := CutStrR(p_mb^.data[vpos],0)+ CutStrR(p_mb^.data[vpos+1],0); If (Length(p_mb^.data[vpos]) > MB_HSIZE) then Delete(p_mb^.data[vpos],MB_HSIZE+1,Length(p_mb^.data[vpos])); For idx := vpos+1 to MB_VSIZE-1 do p_mb^.data[idx] := p_mb^.data[idx+1]; p_mb^.data[MB_VSIZE] := ''; end; kCtrlY: If NOT shift_pressed then begin For idx := vpos to MB_VSIZE-1 do p_mb^.data[idx] := p_mb^.data[idx+1]; p_mb^.data[MB_VSIZE] := ''; end; end; If (Length(p_mb^.data[vpos]) < hpos) then p_mb^.data[vpos] := ExpStrR(p_mb^.data[vpos],hpos,' '); If (ref_vpos <> vpos) then p_mb^.data[ref_vpos] := CutStrR(p_mb^.data[ref_vpos],0); For idx := 1 to MB_VSIZE do ShowStr(centered_frame_vdest,xstart+2,ystart+1+idx-1, ExpStrR(p_mb^.data[idx],MB_HSIZE,' '), dl_setting.text_attr); until (fkey = kESC) or (fkey = kF1) or _force_program_quit; is_setting.append_enabled := old_append_enabled; Move(old_keys,is_setting.terminate_keys,SizeOf(old_keys)); add_bank_position('?message_board?hpos',-1,hpos); add_bank_position('?message_board?vpos',-1,vpos); HideCursor; move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+MB_HSIZE+3+2; move_to_screen_area[4] := ystart+MB_VSIZE+1+1; move2screen; If (fkey = kF1) then begin HELP('message_board'); GOTO _jmp1; end; end; procedure QUIT_request; var temp: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:QUIT_request'; {$ENDIF} If _force_program_quit then begin fkey := kESC; EXIT; end; temp := Dialog('...AND YOU WiLL KNOW MY NAME iS THE LORD, WHEN i LAY$'+ 'MY VENGEANCE UPON THEE...$', '~Q~UiT$~O~OOPS$', ' EZECHiEL 25:17 ',1); If (dl_environment.keystroke <> kESC) and (temp = 1) then begin fkey := kESC; _force_program_quit := TRUE; end else fkey := kENTER; end; procedure show_progress(value: Longint); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:show_progress'; {$ENDIF} If (progress_num_steps = 0) or (progress_value = 0) then EXIT; If (value <> DWORD_NULL) then begin If (progress_num_steps = 1) then progress_new_value := Round(40/progress_value*value) else progress_new_value := Round(40/progress_num_steps*PRED(progress_step)+ 40/progress_num_steps/progress_value*value); progress_new_value := max(progress_new_value,40); If (progress_new_value <> progress_old_value) then begin progress_old_value := progress_new_value; ShowStr(screen_ptr,progress_xstart+35,progress_ystart-1, ExpStrL(Num2Str(Round(100/40*progress_new_value),10)+'%',5,' '), dialog_background+dialog_hi_text); ShowCStr(screen_ptr, progress_xstart,progress_ystart, '~'+ExpStrL('',progress_new_value,#219)+'~'+ ExpStrL('',40-progress_new_value,#219), dialog_background+dialog_prog_bar1, dialog_background+dialog_prog_bar2); realtime_gfx_poll_proc; draw_screen; end; end else begin ShowStr(screen_ptr,progress_xstart+35,progress_ystart-1, ExpStrL('0%',5,' '), dialog_background+dialog_hi_text); ShowStr(screen_ptr, progress_xstart,progress_ystart, ExpStrL('',40,#219), dialog_background+dialog_prog_bar1); realtime_gfx_poll_proc; draw_screen; end; end; procedure show_progress(value,refresh_dif: Longint); begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:show_progress'; {$ENDIF} If (progress_num_steps = 0) or (progress_value = 0) then EXIT; If (value <> DWORD_NULL) then begin If (progress_num_steps = 1) then progress_new_value := Round(40/progress_value*value) else progress_new_value := Round(40/progress_num_steps*PRED(progress_step)+ 40/progress_num_steps/progress_value*value); progress_new_value := max(progress_new_value,40); If (Abs(progress_new_value-progress_old_value) >= refresh_dif) or (progress_new_value = 40) then begin progress_old_value := progress_new_value; ShowStr(screen_ptr,progress_xstart+35,progress_ystart-1, ExpStrL(Num2Str(Round(100/40*progress_new_value),10)+'%',5,' '), dialog_background+dialog_hi_text); ShowCStr(screen_ptr, progress_xstart,progress_ystart, '~'+ExpStrL('',progress_new_value,#219)+'~'+ ExpStrL('',40-progress_new_value,#219), dialog_background+dialog_prog_bar1, dialog_background+dialog_prog_bar2); realtime_gfx_poll_proc; draw_screen; end; end else begin ShowStr(screen_ptr,progress_xstart+35,progress_ystart-1, ExpStrL('0%',5,' '), dialog_background+dialog_hi_text); ShowStr(screen_ptr, progress_xstart,progress_ystart, ExpStrL('',40,#219), dialog_background+dialog_prog_bar1); realtime_gfx_poll_proc; draw_screen; end; end; const last_dir: array[1..4] of String[DIR_SIZE] = ('','','',''); last_file: array[1..4] of String[FILENAME_SIZE] = ('FNAME:EXT','FNAME:EXT', 'FNAME:EXT','FNAME:EXT'); function FILE_open(masks: String; loadBankPossible: Boolean): Byte; var fname,temps: String; mpos,index: Byte; old_ext_proc: procedure; old_songdata_source: String; old_play_status: tPLAY_STATUS; old_tracing: Boolean; temp_marks: array[1..255] of Char; temp_marks2: array[0..$7f] of Char; xstart,ystart: Byte; flag: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:FILE_open:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; end; label _jmp1; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:FILE_open'; {$ENDIF} flag := BYTE_NULL; old_play_status := play_status; old_tracing := tracing; If (Pos('a2i',Lower(masks)) = 0) and (Pos('a2f',Lower(masks)) = 0) and (Pos('a2w',Lower(masks)) = 0) then mpos := 1 else mpos := 2; For index := 1 to 255 do temp_marks[index] := songdata.instr_names[index][1]; For index := 0 to $7f do temp_marks2[index] := songdata.pattern_names[index][1]; _jmp1: If _force_program_quit then EXIT; old_songdata_source := songdata_source; If NOT quick_cmd then begin fs_environment.last_file := last_file[mpos]; fs_environment.last_dir := last_dir[mpos]; old_ext_proc := mn_environment.ext_proc; If (mpos = 2) then mn_environment.ext_proc := fselect_external_proc; fname := Fselect(masks); mn_environment.ext_proc := old_ext_proc; last_file[mpos] := fs_environment.last_file; last_dir[mpos] := fs_environment.last_dir; If (mn_environment.keystroke <> kENTER) then EXIT else If (mpos = 1) then songdata_source := fname else instdata_source := fname; end else If (mpos = 1) then fname := songdata_source else fname := instdata_source; load_flag := BYTE_NULL; limit_exceeded := FALSE; HideCursor; nul_volume_bars; no_status_refresh := TRUE; If (Lower(ExtOnly(fname)) = 'a2m') or (Lower(ExtOnly(fname)) = 'a2t') then begin ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; temps := Upper(ExtOnly(fname))+' FiLE'; centered_frame(xstart,ystart,43,3,' '+temps+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_num_steps := 1; progress_step := 1; If (Lower(ExtOnly(fname)) = 'a2m') then temps := 'MODULE' else temps := 'TiNY MODULE'; ShowCStr(screen_ptr,xstart+2,ystart+1, 'DECOMPRESSiNG '+temps+' DATA...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(DWORD_NULL); end; If (Lower(ExtOnly(fname)) = 'a2m') then a2m_file_loader; If (Lower(ExtOnly(fname)) = 'a2t') then a2t_file_loader; If (Lower(ExtOnly(fname)) = 'a2p') then a2p_file_loader; If (Lower(ExtOnly(fname)) = 'amd') then amd_file_loader; If (Lower(ExtOnly(fname)) = 'cff') then cff_file_loader; If (Lower(ExtOnly(fname)) = 'dfm') then dfm_file_loader; If (Lower(ExtOnly(fname)) = 'fmk') then fmk_file_loader; If (Lower(ExtOnly(fname)) = 'hsc') then hsc_file_loader; If (Lower(ExtOnly(fname)) = 'mtk') then mtk_file_loader; If (Lower(ExtOnly(fname)) = 'rad') then rad_file_loader; If (Lower(ExtOnly(fname)) = 's3m') then s3m_file_loader; If (Lower(ExtOnly(fname)) = 'sat') then sat_file_loader; If (Lower(ExtOnly(fname)) = 'sa2') then sa2_file_loader; If (Lower(ExtOnly(fname)) = 'xms') then amd_file_loader; If (Lower(ExtOnly(fname)) = 'a2i') then a2i_file_loader; If (Lower(ExtOnly(fname)) = 'a2f') then a2f_file_loader; If ((Lower(ExtOnly(fname)) = 'a2m') or (Lower(ExtOnly(fname)) = 'a2t')) and (load_flag = 1) then begin progress_num_steps := 1; progress_step := 1; progress_value := 1; progress_old_value := BYTE_NULL; _draw_screen_without_delay := TRUE; show_progress(1); // delay for awhile to show progress bar at 100% {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; end; If (Lower(ExtOnly(fname)) = 'a2b') then If shift_pressed and NOT ctrl_pressed and NOT alt_pressed then begin If loadBankPossible then begin index := Dialog('ALL UNSAVED INSTRUMENT DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2B LOADER ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then a2b_file_loader(FALSE,loadBankPossible); // w/o bank selector end else a2b_file_loader(TRUE,loadBankPossible); // w/ bank selector end else a2b_file_loader(TRUE,loadBankPossible); // w/ bank selector If (Lower(ExtOnly(fname)) = 'a2w') then If shift_pressed and NOT ctrl_pressed and NOT alt_pressed then begin If loadBankPossible then begin If _arp_vib_loader then index := Dialog('ALL UNSAVED ARPEGGiO/ViBRATO MACRO DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2W LOADER ',1) else index := Dialog('ALL UNSAVED iNSTRUMENT AND MACRO DATA WiLL BE LOST$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' A2W LOADER ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then a2w_file_loader(TRUE,_arp_vib_loader,FALSE,loadBankPossible,FALSE); // w/o bank selector end else a2w_file_loader(TRUE,_arp_vib_loader,TRUE,loadBankPossible,FALSE); // w/ bank selector _arp_vib_loader := FALSE; end else begin a2w_file_loader(TRUE,_arp_vib_loader,TRUE,loadBankPossible,FALSE); // w/ bank selector _arp_vib_loader := FALSE; end; If (Lower(ExtOnly(fname)) = 'bnk') then bnk_file_loader; If (Lower(ExtOnly(fname)) = 'cif') then cif_file_loader; If (Lower(ExtOnly(fname)) = 'fib') then fib_file_loader; If (Lower(ExtOnly(fname)) = 'fin') then fin_file_loader; If (Lower(ExtOnly(fname)) = 'ibk') then ibk_file_loader; If (Lower(ExtOnly(fname)) = 'ins') then ins_file_loader; If (Lower(ExtOnly(fname)) = 'sbi') then sbi_file_loader; If (Lower(ExtOnly(fname)) = 'sgi') then sgi_file_loader; // ThinCursor; If (mpos = 1) then Case load_flag of 0: If (old_songdata_source <> '') and (old_songdata_source <> songdata_source) then begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; index := Dialog('THERE WAS AN ERROR WHiLE LOADiNG NEW MODULE$'+ 'DO YOU WiSH TO RELOAD PREViOUS?$', '~Y~UP$~N~OPE$',' PATTERN EDiTOR ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then begin quick_cmd := TRUE; songdata_source := old_songdata_source; FILE_open('*.a2m$*.a2t$*.a2p$*.amd$*.cff$*.dfm$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); quick_cmd := FALSE; end; end else begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; index := Dialog('THERE WAS AN ERROR WHiLE LOADiNG NEW MODULE$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' PATTERN EDiTOR ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then else If (dl_environment.keystroke <> kESC) then init_songdata; end; 1: begin If limit_exceeded then If (old_songdata_source <> '') and (old_songdata_source <> songdata_source) then begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; index := Dialog('MODULE WAS NOT COMPLETELY LOADED DUE TO LACK OF MEMORY$'+ 'DO YOU WiSH TO RELOAD PREViOUS?$', '~Y~UP$~N~OPE$',' PATTERN EDiTOR ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then begin quick_cmd := TRUE; songdata_source := old_songdata_source; FILE_open('*.a2m$*.a2t$*.a2p$*.amd$*.cff$*.dfm$*.hsc$*.mtk$*.rad$'+ '*.s3m$*.sat$*.sa2$*.xms$',FALSE); quick_cmd := FALSE; end; end else begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; index := Dialog('MODULE WAS NOT COMPLETELY LOADED DUE TO LACK OF MEMORY$'+ 'DO YOU WiSH TO CONTiNUE?$', '~Y~UP$~N~OPE$',' PATTERN EDiTOR ',1); If (dl_environment.keystroke <> kESC) and (index = 1) then else If (dl_environment.keystroke <> kESC) then init_songdata; end; 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); mark_line := songdata.bpm_data.rows_per_beat; IRQ_freq_shift := songdata.bpm_data.tempo_finetune; current_tremolo_depth := tremolo_depth; current_vibrato_depth := vibrato_depth; 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; init_buffers; If (Lower(ExtOnly(fname)) <> 'a2p') then For index := 1 to 255 do songdata.instr_names[index] := ' iNS_'+byte2hex(index)+#247' '+ Copy(songdata.instr_names[index],10,32); If (Lower(ExtOnly(fname)) <> 'a2p') then For index := 0 to $7f do songdata.pattern_names[index] := ' PAT_'+byte2hex(index)+' '#247' '+ Copy(songdata.pattern_names[index],12,30); If NOT quick_cmd then begin FillChar(channel_flag,SizeOf(channel_flag),BYTE(TRUE)); track_notes := FALSE; track_chan_start := 1; nm_track_chan := 1; remap_mtype := 1; remap_ins1 := 1; remap_ins2 := 1; remap_selection := 1; replace_selection := 1; replace_prompt := FALSE; replace_data.event_to_find.note := '???'; replace_data.event_to_find.inst := '??'; replace_data.event_to_find.fx_1 := '???'; replace_data.event_to_find.fx_2 := '???'; replace_data.new_event.note := '???'; replace_data.new_event.inst := '??'; replace_data.new_event.fx_1 := '???'; replace_data.new_event.fx_2 := '???'; current_inst := 1; pattern_list__page := 1; _macro_editor__pos[FALSE] := 1; _macro_editor__pos[TRUE] := 8; _macro_editor__fmreg_hpos[FALSE] := 1; _macro_editor__fmreg_hpos[TRUE] := 1; _macro_editor__fmreg_page[FALSE] := 1; _macro_editor__fmreg_page[TRUE] := 1; _macro_editor__fmreg_left_margin[FALSE] := 1; _macro_editor__fmreg_left_margin[TRUE] := 1; _macro_editor__fmreg_cursor_pos[FALSE] := 1; _macro_editor__fmreg_cursor_pos[TRUE] := 1; add_bank_position('?internal_instrument_data?macro?pos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_page',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_hpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_vpos',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_left_margin',-1,1); add_bank_position('?internal_instrument_data?macro?fmreg_cursor_pos',-1,1); _macro_editor__arpeggio_page[FALSE] := 1; _macro_editor__arpeggio_page[TRUE] := 1; _macro_editor__vibrato_hpos[FALSE] := 1; _macro_editor__vibrato_hpos[TRUE] := 1; _macro_editor__vibrato_page[FALSE] := 1; _macro_editor__vibrato_page[TRUE] := 1; add_bank_position('?internal_instrument_data?macro_av?pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?arp_pos',-1,1); add_bank_position('?internal_instrument_data?macro_av?vib_pos',-1,1); add_bank_position('?song_variables_window?pos',-1,1); add_bank_position('?song_variables_window?pos_4op',-1,0); add_bank_position('?replace_window?pos',-1,1); add_bank_position('?replace_window?posfx',-1,1); add_bank_position('?message_board?hpos',-1,1); add_bank_position('?message_board?vpos',-1,1); For index := 1 to 255 do begin add_bank_position('?instrument_editor?'+byte2hex(index)+'?carrier',-1,1); add_bank_position('?instrument_editor?'+byte2hex(index)+'?carrier?hpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(index)+'?carrier?vpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(index)+'?modulator?hpos',-1,1); add_bank_position('?instrument_editor?'+byte2hex(index)+'?modulator?vpos',-1,1); end; For index := 1 to _rearrange_nm_tracks do _rearrange_tracklist_idx[index] := index; _rearrange_track_pos := 1; end else begin For index := 1 to 255 do songdata.instr_names[index][1] := temp_marks[index]; For index := 0 to $7f do songdata.pattern_names[index][1] := temp_marks2[index]; end; reset_player; If NOT quick_cmd or NOT keep_position then If (Lower(ExtOnly(fname)) <> 'a2p') and NOT (shift_pressed and (mpos = 1) and (load_flag <> BYTE_NULL) and NOT quick_cmd and (old_play_status = isPlaying)) then POSITIONS_reset; songdata_crc := Update32(songdata,SizeOf(songdata),0); If (Lower(ExtOnly(fname)) <> 'a2p') then begin module_archived := TRUE; songdata_crc_ord := Update32(songdata.pattern_order, SizeOf(songdata.pattern_order),0); end; end end else If (load_flag <> BYTE_NULL) then module_archived := FALSE else If NOT quick_cmd then If (Lower(ExtOnly(fname)) = 'bnk') or (Lower(ExtOnly(fname)) = 'fib') or (Lower(ExtOnly(fname)) = 'ibk') then GOTO _jmp1; If (load_flag <> BYTE_NULL) then begin songdata.songname := FilterStr2(songdata.songname,_valid_characters,'_'); songdata.composer := FilterStr2(songdata.composer,_valid_characters,'_'); For index := 1 to 255 do songdata.instr_names[index] := Copy(songdata.instr_names[index],1,9)+ FilterStr2(Copy(cstr2str(songdata.instr_names[index]),10,32),_valid_characters,'_'); end; If shift_pressed and (mpos = 1) and (load_flag <> BYTE_NULL) and NOT quick_cmd and (old_play_status = isPlaying) then begin start_playing; tracing := old_tracing; If NOT quick_cmd or NOT keep_position then If (Lower(ExtOnly(fname)) <> 'a2p') and NOT tracing then POSITIONS_reset; end else begin force_scrollbars := TRUE; PATTERN_ORDER_page_refresh(pattord_page); PATTERN_page_refresh(pattern_page); force_scrollbars := FALSE; end; flag := 1; FillChar(ai_table,SizeOf(ai_table),0); no_status_refresh := FALSE; FILE_open := flag; end; function _a2m_saver: Byte; 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_'; var f: File; header: tHEADER; temp,index: Longint; xstart,ystart: Byte; temp_marks: array[1..255] of Char; temp_marks2: array[0..$7f] of Char; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2m_saver:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; progress_num_steps := 0; progress_value := 0; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2m_saver'; {$ENDIF} _a2m_saver := 0; {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(songdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2M SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2m_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; FillChar(songdata.songname[SUCC(Length(songdata.songname))], PRED(SizeOf(songdata.songname))- Length(songdata.songname),0); FillChar(songdata.composer[SUCC(Length(songdata.composer))], PRED(SizeOf(songdata.composer))- Length(songdata.composer),0); For temp := 1 to 255 do FillChar(songdata.instr_names[temp][SUCC(Length(songdata.instr_names[temp]))], PRED(SizeOf(songdata.instr_names[temp]))- Length(songdata.instr_names[temp]),0); For temp := 0 to $7f do FillChar(songdata.pattern_names[temp][SUCC(Length(songdata.pattern_names[temp]))], PRED(SizeOf(songdata.pattern_names[temp]))- Length(songdata.pattern_names[temp]),0); FillChar(header,SizeOf(header),0); count_patterns(header.patts); header.crc32 := DWORD_NULL; header.ident := id; songdata.common_flag := BYTE(speed_update)+BYTE(lockvol) SHL 1+ BYTE(lockVP) SHL 2+ tremolo_depth SHL 3+ vibrato_depth SHL 4+ BYTE(panlock) SHL 5+ BYTE(percussion_mode) SHL 6+ BYTE(volume_scaling) SHL 7; songdata.bpm_data.rows_per_beat := mark_line; songdata.bpm_data.tempo_finetune := IRQ_freq_shift; header.ffver := FFVER_A2M; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; If (header.patts = 0) then header.patts := 1; centered_frame(xstart,ystart,43,3,' A2M FiLE ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_step := 1; progress_num_steps := (header.patts-1) DIV 8 +2; ShowCStr(screen_ptr,xstart+2,ystart+1, 'COMPRESSiNG MODULE DATA...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(DWORD_NULL); For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; Delete(songdata.instr_names[temp],1,9); FillChar(songdata.instr_names[temp][SUCC(Length(songdata.instr_names[temp]))], 32-Length(songdata.instr_names[temp]),0); end; For temp := 0 to $7f do begin temp_marks2[temp] := songdata.pattern_names[temp][1]; Delete(songdata.pattern_names[temp],1,11); FillChar(songdata.pattern_names[temp][SUCC(Length(songdata.pattern_names[temp]))], 32-Length(songdata.pattern_names[temp]),0); end; header.b0len := LZH_compress(songdata,buf1,SizeOf(songdata)); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); For temp := 0 to $7f do Insert(temp_marks2[temp]+ 'PAT_'+byte2hex(temp)+' '#247' ', songdata.pattern_names[temp],1); BlockWriteF(f,buf1,header.b0len,temp); Inc(progress_step); If NOT (temp = header.b0len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b0len,header.crc32); header.b1len[0] := LZH_compress(pattdata^[0],buf1,SizeOf(pattdata^[0])); BlockWriteF(f,buf1,header.b1len[0],temp); Inc(progress_step); If NOT (temp = header.b1len[0]) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b1len[0],header.crc32); For index := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(index)) then begin header.b1len[index] := LZH_compress(pattdata^[index],buf1,SizeOf(pattdata^[index])); BlockWriteF(f,buf1,header.b1len[index],temp); Inc(progress_step); If NOT (temp = header.b1len[index]) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b1len[index],header.crc32); end; header.crc32 := Update32(header.b0len,2,header.crc32); For index := 0 to 15 do header.crc32 := Update32(header.b1len[index],2,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2M SAVER ',1); EXIT; end; CloseF(f); _restore; songdata_title := NameOnly(songdata_source); songdata_crc := Update32(songdata,SizeOf(songdata),0); songdata_crc_ord := Update32(songdata.pattern_order, SizeOf(songdata.pattern_order),0); module_archived := TRUE; end; function _a2t_saver: Byte; 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; instruments: Byte; temp,temp2,index: Longint; temps: String; xstart,ystart: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2t_saver:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; progress_num_steps := 0; progress_value := 0; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2t_saver'; {$ENDIF} _a2t_saver := 0; {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(songdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2T SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2t_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; FillChar(header,SizeOf(header),0); count_patterns(header.patts); header.crc32 := DWORD_NULL; header.ident := id; header.tempo := songdata.tempo; header.speed := songdata.speed; header.cflag := BYTE(speed_update)+BYTE(lockvol) SHL 1+ BYTE(lockVP) SHL 2+ tremolo_depth SHL 3+ vibrato_depth SHL 4+ BYTE(panlock) SHL 5+ BYTE(percussion_mode) SHL 6+ BYTE(volume_scaling) SHL 7; songdata.bpm_data.rows_per_beat := mark_line; songdata.bpm_data.tempo_finetune := IRQ_freq_shift; header.patln := songdata.patt_len; header.nmtrk := songdata.nm_tracks; header.mcspd := songdata.macro_speedup; header.is4op := songdata.flag_4op; Move(songdata.lock_flags,header.locks,SizeOf(header.locks)); header.ffver := FFVER_A2T; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; If (header.patts = 0) then header.patts := 1; temps := 'A2T FiLE'; centered_frame(xstart,ystart,43,3,' '+temps+' ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_step := 1; progress_num_steps := (header.patts-1) DIV 8 +6; ShowCStr(screen_ptr,xstart+2,ystart+1, 'COMPRESSiNG TiNY MODULE DATA...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(DWORD_NULL); count_instruments(instruments); instruments := min(instruments,1); temp2 := 0; Move(songdata.bpm_data,buf2[temp2],SizeOf(songdata.bpm_data)); Inc(temp2,SizeOf(songdata.bpm_data)); Move(songdata.ins_4op_flags,buf2[temp2],SizeOf(songdata.ins_4op_flags)); Inc(temp2,SizeOf(songdata.ins_4op_flags)); Move(songdata.reserved_data,buf2[temp2],SizeOf(songdata.reserved_data)); Inc(temp2,SizeOf(songdata.reserved_data)); Move(songdata.instr_data,buf2[temp2],instruments*SizeOf(songdata.instr_data[1])); Inc(temp2,instruments*SizeOf(songdata.instr_data[1])); header.b0len := LZH_compress_ultra(buf2,buf1,temp2); BlockWriteF(f,buf1,header.b0len,temp); Inc(progress_step); If NOT (temp = header.b0len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b0len,header.crc32); temp := 0; temp2 := instruments*SizeOf(songdata.instr_macros[1]); If NOT Empty(songdata.instr_macros,temp2) then begin header.b1len := LZH_compress_ultra(songdata.instr_macros,buf1,temp2); BlockWriteF(f,buf1,header.b1len,temp); end else header.b1len := 0; Inc(progress_step); If NOT (temp = header.b1len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b1len,header.crc32); temp := 0; temp2 := SizeOf(songdata.macro_table); If NOT Empty(songdata.macro_table,temp2) then begin header.b2len := LZH_compress_ultra(songdata.macro_table,buf1,temp2); BlockWriteF(f,buf1,header.b2len,temp); end else header.b2len := 0; Inc(progress_step); If NOT (temp = header.b2len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b2len,header.crc32); temp := 0; temp2 := SizeOf(songdata.dis_fmreg_col); If NOT Empty(songdata.dis_fmreg_col,temp2) then begin header.b3len := LZH_compress_ultra(songdata.dis_fmreg_col,buf1,temp2); BlockWriteF(f,buf1,header.b3len,temp); end else header.b3len := 0; Inc(progress_step); If NOT (temp = header.b3len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b3len,header.crc32); temp2 := SizeOf(songdata.pattern_order); header.b4len := LZH_compress_ultra(songdata.pattern_order,buf1,temp2); BlockWriteF(f,buf1,header.b4len,temp); Inc(progress_step); If NOT (temp = header.b4len) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b4len,header.crc32); If (header.patts < 1*8) then temp2 := header.patts*SizeOf(pattdata^[0][0]) else temp2 := SizeOf(pattdata^[0]); header.b5len[0] := LZH_compress_ultra(pattdata^[0],buf1,temp2); BlockWriteF(f,buf1,header.b5len[0],temp); Inc(progress_step); If NOT (temp = header.b5len[0]) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b5len[0],header.crc32); For index := 1 to 15 do If ((header.patts-1) DIV 8 > PRED(index)) then begin If (header.patts < SUCC(index)*8) then temp2 := (header.patts-index*8)*SizeOf(pattdata^[index][0]) else temp2 := SizeOf(pattdata^[index]); header.b5len[index] := LZH_compress_ultra(pattdata^[index],buf1,temp2); BlockWriteF(f,buf1,header.b5len[index],temp); Inc(progress_step); If NOT (temp = header.b5len[index]) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b5len[index],header.crc32); end; header.crc32 := Update32(header.b0len,2,header.crc32); header.crc32 := Update32(header.b1len,2,header.crc32); header.crc32 := Update32(header.b2len,2,header.crc32); header.crc32 := Update32(header.b3len,2,header.crc32); header.crc32 := Update32(header.b4len,2,header.crc32); For index := 0 to 15 do header.crc32 := Update32(header.b5len[index],2,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); _restore; Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2T SAVER ',1); EXIT; end; CloseF(f); _restore; songdata_title := NameOnly(songdata_source); songdata_crc := Update32(songdata,SizeOf(songdata),0); songdata_crc_ord := Update32(songdata.pattern_order, SizeOf(songdata.pattern_order),0); module_archived := TRUE; end; function _a2i_saver: Byte; type tHEADER = Record ident: array[1..7] of Char; crc16: Word; ffver: Byte; b0len: Word; end; const id = '_A2ins_'; var f: File; header: tHEADER; temp,temp2,temp3: Longint; ins_4op: Word; crc: Word; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2i_saver'; {$ENDIF} _a2i_saver := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(instdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2i SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2i_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; progress_num_steps := 0; header.ident := id; header.ffver := FFVER_A2I; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; temp3 := 0; ins_4op := check_4op_to_test; If (ins_4op <> 0) then begin // 4OP 1/2 Move(songdata.instr_data[HI(ins_4op)],buf2[temp3], SizeOf(songdata.instr_data[HI(ins_4op)])); Inc(temp3,SizeOf(songdata.instr_data[HI(ins_4op)])); temp_str := Copy(songdata.instr_names[HI(ins_4op)],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); // 4OP 2/2 Move(songdata.instr_data[LO(ins_4op)],buf2[temp3], SizeOf(songdata.instr_data[LO(ins_4op)])); Inc(temp3,SizeOf(songdata.instr_data[LO(ins_4op)])); temp_str := Copy(songdata.instr_names[LO(ins_4op)],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); end else begin Move(songdata.instr_data[current_inst],buf2[temp3], SizeOf(songdata.instr_data[current_inst])); Inc(temp3,SizeOf(songdata.instr_data[current_inst])); temp_str := Copy(songdata.instr_names[current_inst],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); end; temp2 := LZH_compress(buf2,buf3,temp3); BlockWriteF(f,buf3,temp2,temp); If NOT (temp = temp2) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; header.b0len := temp; crc := WORD_NULL; crc := Update16(header.b0len,1,crc); crc := Update16(buf3,header.b0len,crc); header.crc16 := crc; ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2i SAVER ',1); EXIT; end; CloseF(f); end; function _a2f_saver: Byte; type tHEADER = Record ident: array[1..18] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; const id = '_a2ins_w/fm-macro_'; var f: File; header: tHEADER; temp,temp2,temp3: Longint; ins_4op: Word; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2f_saver'; {$ENDIF} _a2f_saver := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(instdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2F SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2f_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; progress_num_steps := 0; header.ident := id; header.ffver := FFVER_A2F; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; temp3 := 0; ins_4op := check_4op_to_test; If (ins_4op <> 0) then begin // 4OP 1/2 Move(songdata.instr_data[HI(ins_4op)],buf2[temp3], SizeOf(songdata.instr_data[HI(ins_4op)])); Inc(temp3,SizeOf(songdata.instr_data[HI(ins_4op)])); temp_str := Copy(songdata.instr_names[HI(ins_4op)],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); temp2 := 0; Move(songdata.instr_macros[HI(ins_4op)],buf3[temp2], SizeOf(songdata.instr_macros[HI(ins_4op)])); Inc(temp2,SizeOf(songdata.instr_macros[HI(ins_4op)])); tREGISTER_TABLE(Addr(buf3[temp2])^).arpeggio_table := 0; tREGISTER_TABLE(Addr(buf3[temp2])^).vibrato_table := 0; Move(songdata.dis_fmreg_col[HI(ins_4op)], buf3[temp2], SizeOf(songdata.dis_fmreg_col[HI(ins_4op)])); Inc(temp2,SizeOf(songdata.dis_fmreg_col[HI(ins_4op)])); Move(buf3,buf2[temp3],temp2); Inc(temp3,temp2); // 4OP 2/2 Move(songdata.instr_data[LO(ins_4op)],buf2[temp3], SizeOf(songdata.instr_data[LO(ins_4op)])); Inc(temp3,SizeOf(songdata.instr_data[LO(ins_4op)])); temp_str := Copy(songdata.instr_names[LO(ins_4op)],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); temp2 := 0; Move(songdata.instr_macros[LO(ins_4op)],buf3[temp2], SizeOf(songdata.instr_macros[LO(ins_4op)])); Inc(temp2,SizeOf(songdata.instr_macros[LO(ins_4op)])); tREGISTER_TABLE(Addr(buf3[temp2])^).arpeggio_table := 0; tREGISTER_TABLE(Addr(buf3[temp2])^).vibrato_table := 0; Move(songdata.dis_fmreg_col[LO(ins_4op)], buf3[temp2], SizeOf(songdata.dis_fmreg_col[LO(ins_4op)])); Inc(temp2,SizeOf(songdata.dis_fmreg_col[LO(ins_4op)])); Move(buf3,buf2[temp3],temp2); Inc(temp3,temp2); end else begin Move(songdata.instr_data[current_inst],buf2[temp3], SizeOf(songdata.instr_data[current_inst])); Inc(temp3,SizeOf(songdata.instr_data[current_inst])); temp_str := Copy(songdata.instr_names[current_inst],10,32); Move(temp_str,buf2[temp3],SUCC(Length(temp_str))); Inc(temp3,SUCC(Length(temp_str))); temp2 := 0; Move(songdata.instr_macros[current_inst],buf3[temp2], SizeOf(songdata.instr_macros[current_inst])); Inc(temp2,SizeOf(songdata.instr_macros[current_inst])); tREGISTER_TABLE(Addr(buf3[temp2])^).arpeggio_table := 0; tREGISTER_TABLE(Addr(buf3[temp2])^).vibrato_table := 0; Move(songdata.dis_fmreg_col[current_inst], buf3[temp2], SizeOf(songdata.dis_fmreg_col[current_inst])); Inc(temp2,SizeOf(songdata.dis_fmreg_col[current_inst])); Move(buf3,buf2[temp3],temp2); Inc(temp3,temp2); end; temp2 := LZH_compress(buf2,buf3,temp3); BlockWriteF(f,buf3,temp2,temp); If NOT (temp = temp2) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; header.b0len := temp; header.crc32 := DWORD_NULL; header.crc32 := Update32(header.b0len,1,header.crc32); header.crc32 := Update32(buf3,header.b0len,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2F SAVER ',1); EXIT; end; CloseF(f); end; function _a2p_saver: Byte; type tHEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; const id = '_A2pattern_'; var f: File; header: tHEADER; temp,temp2: Longint; temp_str: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2p_saver'; {$ENDIF} _a2p_saver := 0; {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(songdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2P SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2p_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; progress_num_steps := 0; header.crc32 := DWORD_NULL; header.ident := id; header.ffver := FFVER_A2P; If (pattern2use <> BYTE_NULL) then Move(pattdata^[pattern2use DIV 8][pattern2use MOD 8], buf2, PATTERN_SIZE) else Move(pattdata^[pattern_patt DIV 8][pattern_patt MOD 8], buf2, PATTERN_SIZE); If (pattern2use <> BYTE_NULL) then temp_str := Copy(songdata.pattern_names[pattern2use],12,30) else temp_str := Copy(songdata.pattern_names[pattern_patt],12,30); FillChar(temp_str[SUCC(Length(temp_str))],30-Length(temp_str),0); Move(temp_str,buf2[PATTERN_SIZE],Length(temp_str)+1); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; temp2 := PATTERN_SIZE+30+1; header.b0len := LZH_compress(buf2,buf1,temp2); BlockWriteF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b0len,header.crc32); header.crc32 := Update32(header.b0len,2,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2P SAVER ',1); EXIT; end; CloseF(f); end; function _a2b_saver: Byte; const id = '_A2insbank_'; type tHEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; var f: File; header: tHEADER; temp,temp2,temp3: Longint; crc: Longint; temp_marks: array[1..255] of Char; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2b_saver'; {$ENDIF} _a2b_saver := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(instdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2B SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2b_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; progress_num_steps := 0; header.ident := id; header.ffver := FFVER_A2B; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; Delete(songdata.instr_names[temp],1,9); FillChar(songdata.instr_names[temp][SUCC(Length(songdata.instr_names[temp]))], 32-Length(songdata.instr_names[temp]),0); end; temp3 := SizeOf(songdata.instr_names)+SizeOf(songdata.instr_data); Move(songdata.instr_names,buf2,temp3); Move(songdata.ins_4op_flags,buf2[temp3],SizeOf(songdata.ins_4op_flags)); Inc(temp3,SizeOf(songdata.ins_4op_flags)); temp2 := LZH_compress(buf2,buf1,temp3); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); BlockWriteF(f,buf1,temp2,temp); If NOT (temp = temp2) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; header.b0len := temp; crc := DWORD_NULL; crc := Update32(header.b0len,2,crc); crc := Update32(buf1,header.b0len,crc); header.crc32 := crc; ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2B SAVER ',1); EXIT; end; CloseF(f); end; function _a2w_saver: Byte; const id = '_A2insbank_w/macros_'; type tHEADER = Record ident: array[1..20] of Char; crc32: Longint; ffver: Byte; b0len: Longint; b1len: Longint; b2len: Longint; end; var f: File; header: tHEADER; temp,temp3: Longint; temp_marks: array[1..255] of Char; xstart,ystart: Byte; procedure _restore; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2w_saver:_restore'; {$ENDIF} move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+43+2+1; move_to_screen_area[4] := ystart+3+1; move2screen; progress_num_steps := 0; progress_value := 0; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:_a2w_saver'; {$ENDIF} _a2w_saver := 0; {$i-} Assign(f,instdata_source); ResetF(f); {$i+} If (IOresult = 0) and NOT quick_cmd then begin If (dl_environment.keystroke = kESC) then EXIT; temp := Dialog('FiLE "'+iCASE(NameOnly(instdata_source))+ '" ALREADY EXiSTS iN DESTiNATiON DiRECTORY$', '~O~VERWRiTE$~R~ENAME$~C~ANCEL$',' A2W SAVER ',1); If ((dl_environment.keystroke <> kESC) and (temp = 3)) or (dl_environment.keystroke = kESC) then begin CloseF(f); EXIT; end else If (dl_environment.keystroke <> kESC) and (temp = 2) then begin CloseF(f); _a2w_saver := BYTE_NULL; EXIT; end; end else If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; {$i-} RewriteF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR WRiTiNG DATA - DiSK ERROR?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; HideCursor; centered_frame(xstart,ystart,43,3,' A2W FiLE ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); progress_xstart := xstart+2; progress_ystart := ystart+2; progress_step := 1; progress_num_steps := 3; ShowCStr(screen_ptr,xstart+2,ystart+1, 'COMPRESSiNG iNSTRUMENT BANK DATA...', dialog_background+dialog_text, dialog_background+dialog_hi_text); show_progress(DWORD_NULL); header.crc32 := DWORD_NULL; header.ident := id; header.ffver := FFVER_A2W; BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; For temp := 1 to 255 do begin temp_marks[temp] := songdata.instr_names[temp][1]; Delete(songdata.instr_names[temp],1,9); FillChar(songdata.instr_names[temp][SUCC(Length(songdata.instr_names[temp]))], 32-Length(songdata.instr_names[temp]),0); end; temp3 := SizeOf(songdata.instr_names)+ SizeOf(songdata.instr_data)+ SizeOf(songdata.instr_macros); Move(songdata.instr_names,buf2,temp3); Move(songdata.ins_4op_flags,buf2[temp3],SizeOf(songdata.ins_4op_flags)); Inc(temp3,SizeOf(songdata.ins_4op_flags)); header.b0len := LZH_compress(buf2,buf1,temp3); Inc(progress_step); For temp := 1 to 255 do Insert(temp_marks[temp]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); BlockWriteF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b0len,header.crc32); header.b1len := LZH_compress(songdata.macro_table,buf1,SizeOf(songdata.macro_table)); Inc(progress_step); BlockWriteF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b1len,header.crc32); header.b2len := LZH_compress(songdata.dis_fmreg_col,buf1,SizeOf(songdata.dis_fmreg_col)); Inc(progress_step); BlockWriteF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; header.crc32 := Update32(buf1,header.b2len,header.crc32); header.crc32 := Update32(header.b0len,2,header.crc32); header.crc32 := Update32(header.b1len,2,header.crc32); header.crc32 := Update32(header.b2len,2,header.crc32); ResetF_RW(f); BlockWriteF(f,header,SizeOf(header),temp); If NOT (temp = SizeOf(header)) then begin CloseF(f); EraseF(f); Dialog('ERROR WRiTiNG DATA - DiSK FULL?$'+ 'SAViNG STOPPED$', '~O~KAY$',' A2W SAVER ',1); EXIT; end; CloseF(f); progress_num_steps := 1; progress_step := 1; progress_value := 1; progress_old_value := BYTE_NULL; _draw_screen_without_delay := TRUE; show_progress(1); // delay for awhile to show progress bar at 100% {$IFDEF GO32V2} CRT.Delay(500); {$ELSE} SDL_Delay(200); {$ENDIF} _restore; end; procedure FILE_save(ext: String); var quit_flag: Boolean; temp_str: String; temp,mpos: Byte; old_songdata_source, old_instdata_source: String; label _jmp1,_jmp2; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ADT2EXTN.PAS:FILE_save'; {$ENDIF} old_songdata_source := songdata_source; old_instdata_source := instdata_source; If (songdata_source <> '') then songdata_source := iCase_filename(PathOnly(songdata_source))+ Lower_filename(BaseNameOnly(songdata_source))+'.'+ext; If (instdata_source <> '') then instdata_source := iCase_filename(PathOnly(instdata_source))+ Lower_filename(BaseNameOnly(instdata_source))+'.'+ext; _jmp1: If quick_cmd then If ((Lower_filename(ext) = 'a2m') or (Lower_filename(ext) = 'a2t')) and (songdata_source <> '') then GOTO _jmp2; Repeat is_setting.append_enabled := TRUE; is_setting.character_set := [#32..#255]; dl_setting.center_text := FALSE; dl_setting.terminate_keys[3] := kTAB; is_setting.terminate_keys[3] := kTAB; is_environment.locate_pos := 1; dl_environment.context := ' TAB '#196#16' FiLE SELECTOR '; If (Lower_filename(ext) = 'a2i') then begin If NOT alt_ins_name then begin If (a2i_default_path = '') then dl_environment.input_str := instdata_source else dl_environment.input_str := iCase_filename(a2i_default_path)+NameOnly(instdata_source); end else dl_environment.input_str := iCase_filename(a2i_default_path)+ 'instr'+ExpStrL(Num2str(current_inst,10),3,'0')+'.a2i'; end; If (Lower_filename(ext) = 'a2f') then begin If NOT alt_ins_name then begin If (a2f_default_path = '') then dl_environment.input_str := instdata_source else dl_environment.input_str := iCase_filename(a2f_default_path)+NameOnly(instdata_source); end else dl_environment.input_str := iCase_filename(a2f_default_path)+ 'instr'+ExpStrL(Num2str(current_inst,10),3,'0')+'.a2f'; end; If (Lower_filename(ext) = 'a2b') then If (a2b_default_path = '') then dl_environment.input_str := instdata_source else dl_environment.input_str := iCase_filename(a2b_default_path)+NameOnly(instdata_source); If (Lower_filename(ext) = 'a2w') then If (a2w_default_path = '') then dl_environment.input_str := instdata_source else dl_environment.input_str := iCase_filename(a2w_default_path)+NameOnly(instdata_source); If (Lower_filename(ext) = 'a2m') then If (a2m_default_path = '') then dl_environment.input_str := songdata_source else dl_environment.input_str := iCase_filename(a2m_default_path)+NameOnly(songdata_source); If (Lower_filename(ext) = 'a2t') then If (a2t_default_path = '') then dl_environment.input_str := songdata_source else dl_environment.input_str := iCase_filename(a2t_default_path)+NameOnly(songdata_source); If (Lower_filename(ext) = 'a2p') then If (a2p_default_path = '') then dl_environment.input_str := songdata_source else dl_environment.input_str := iCase_filename(a2p_default_path)+NameOnly(songdata_source); Dialog('{PATH}[FiLENAME] EXTENSiON iS SET TO "'+iCase_filename(ext)+'"$', '%string_input%255$50'+ '$'+Num2str(dialog_input_bckg+dialog_input,16)+ '$'+Num2str(dialog_def_bckg+dialog_def,16)+ '$',' SAVE FiLE ',0); dl_setting.terminate_keys[3] := 0; is_setting.terminate_keys[3] := 0; dl_setting.center_text := TRUE; dl_environment.context := ''; If (dl_environment.keystroke = kESC) or ((dl_environment.keystroke <> kTAB) and (BaseNameOnly(dl_environment.input_str) = '')) then begin songdata_source := old_songdata_source; instdata_source := old_instdata_source; EXIT; end; If (dl_environment.keystroke = kENTER) then begin If (Lower_filename(ext) = 'a2m') then songdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2m'; If (Lower_filename(ext) = 'a2t') then songdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2t'; If (Lower_filename(ext) = 'a2p') then songdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2p'; If (Lower_filename(ext) = 'a2i') then instdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2i'; If (Lower_filename(ext) = 'a2f') then instdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2f'; If (Lower_filename(ext) = 'a2b') then instdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2b'; If (Lower_filename(ext) = 'a2w') then instdata_source := iCase_filename(PathOnly(dl_environment.input_str))+ Lower_filename(BaseNameOnly(dl_environment.input_str))+ '.a2w'; end; quit_flag := TRUE; If (dl_environment.keystroke = kTAB) then begin If (Lower_filename(ext) <> 'a2i') and (Lower_filename(ext) <> 'a2f') and (Lower_filename(ext) <> 'a2b') and (Lower_filename(ext) <> 'a2w') then mpos := 3 else mpos := 4; fs_environment.last_file := last_file[mpos]; fs_environment.last_dir := last_dir[mpos]; temp_str := Fselect('*.'+ext+'$'); last_file[mpos] := fs_environment.last_file; last_dir[mpos] := fs_environment.last_dir; If (mn_environment.keystroke = kESC) then quit_flag := FALSE else begin If (Lower_filename(ext) = 'a2m') then songdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2m'; If (Lower_filename(ext) = 'a2t') then songdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2t'; If (Lower_filename(ext) = 'a2p') then songdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2p'; If (Lower_filename(ext) = 'a2i') then instdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2i'; If (Lower_filename(ext) = 'a2f') then instdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2f'; If (Lower_filename(ext) = 'a2b') then instdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2b'; If (Lower_filename(ext) = 'a2w') then instdata_source := iCase_filename(PathOnly(temp_str))+ Lower_filename(BaseNameOnly(temp_str))+'.a2w'; end; end; until quit_flag; If (dl_environment.keystroke = kESC) then begin songdata_source := old_songdata_source; instdata_source := old_instdata_source; EXIT; end; _jmp2: If (Lower_filename(ext) = 'a2i') or (Lower_filename(ext) = 'a2f') or (Lower_filename(ext) = 'a2b') or (Lower_filename(ext) = 'a2w') then temp_str := instdata_source; If (Lower_filename(ext) = 'a2m') or (Lower_filename(ext) = 'a2t') or (Lower_filename(ext) = 'a2p') then temp_str := songdata_source; If (Lower_filename(ext) = 'a2m') then temp := _a2m_saver; If (Lower_filename(ext) = 'a2t') then temp := _a2t_saver; If (Lower_filename(ext) = 'a2i') then temp := _a2i_saver; If (Lower_filename(ext) = 'a2f') then temp := _a2f_saver; If (Lower_filename(ext) = 'a2p') then temp := _a2p_saver; If (Lower_filename(ext) = 'a2b') then temp := _a2b_saver; If (Lower_filename(ext) = 'a2w') then temp := _a2w_saver; If (temp = BYTE_NULL) then GOTO _jmp1; end; end. adlibtracker2-2.4.24/iloaders.inc0000644000000000000000000102430113411003760015303 0ustar rootroot// 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; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} procedure import_single_old_instrument(old_songdata: pOLD_FIXED_SONGDATA; pos,instr: Byte); begin songdata.instr_names[pos] := Copy(songdata.instr_names[pos],1,9)+ Copy(old_songdata^.instr_names[instr],10,22); songdata.instr_data[pos].fm_data := old_songdata^.instr_data[instr].fm_data; songdata.instr_data[pos].panning := old_songdata^.instr_data[instr].panning; songdata.instr_data[pos].fine_tune := old_songdata^.instr_data[instr].fine_tune; songdata.instr_data[pos].perc_voice := 0; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:a2m_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If NOT (header.ffver in [1..FFVER_A2M]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (header.ffver = 9) then import_old_flags; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} For temp := 1 to 255 do Insert(songdata.instr_names[temp][1]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); If (header.ffver = 11) then For temp := 0 to $7f do Insert(songdata.pattern_names[temp][1]+ 'PAT_'+byte2hex(temp)+' '#247' ', songdata.pattern_names[temp],1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_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.b1len[temp2],temp); If NOT (temp = header.b1len[temp2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} progress_num_steps := (header.patts-1) DIV 8 +2; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} LZH_decompress(buf1,songdata,header.b0len); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} BlockReadF(f,buf1,header.b1len[0],temp); If NOT (temp = header.b1len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} For temp := 1 to 255 do Insert(songdata.instr_names[temp][1]+ 'iNS_'+byte2hex(temp)+#247' ', songdata.instr_names[temp],1); For temp := 0 to $7f do Insert(songdata.pattern_names[temp][1]+ 'PAT_'+byte2hex(temp)+' '#247' ', songdata.pattern_names[temp],1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} LZH_decompress(buf1,pattdata^[0],header.b1len[0]); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (temp2*8+8 <= max_patterns) then begin LZH_decompress(buf1,pattdata^[temp2],header.b1len[temp2]); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end else limit_exceeded := TRUE; end; end; speed := songdata.speed; tempo := songdata.tempo; CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> Case header.ffver of {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> 1..4: load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> else load_flag := 2; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} temp := calc_max_speedup(songdata.tempo); If (songdata.macro_speedup > temp) then begin Dialog('DUE TO SYSTEM LiMiTATiONS, ~MACRO SPEEDUP~ VALUE IS ~CHANGED~$'+ 'SLOWDOWN: ~'+Num2str(songdata.macro_speedup,10)+'X -> '+Num2str(temp,10)+'X~$', '~O~KAY$',' A2M LOADER ',1); songdata.macro_speedup := temp; end; load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:a2t_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If NOT (header.ffver in [1..FFVER_A2T]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b1len,temp); If NOT (temp = header2.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header2.b2len,temp); If NOT (temp = header2.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header3.b1len,temp); If NOT (temp = header3.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header3.b2len,temp); If NOT (temp = header3.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header3.b0len,temp); If NOT (temp = header3.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header4.b0len,temp); If NOT (temp = header4.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b1len,temp); If NOT (temp = header4.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b2len,temp); If NOT (temp = header4.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b3len,temp); If NOT (temp = header4.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header4.b4len[0],temp); If NOT (temp = header4.b4len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header4)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header4.b0len,temp); If NOT (temp = header4.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_data); BlockReadF(f,buf1,header4.b1len,temp); If NOT (temp = header4.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_macros); BlockReadF(f,buf1,header4.b2len,temp); If NOT (temp = header4.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.macro_table); BlockReadF(f,buf1,header4.b3len,temp); If NOT (temp = header4.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header5.b0len,temp); If NOT (temp = header5.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b1len,temp); If NOT (temp = header5.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b2len,temp); If NOT (temp = header5.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b3len,temp); If NOT (temp = header5.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header5.b4len[0],temp); If NOT (temp = header5.b4len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header5)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header5.b0len,temp); If NOT (temp = header5.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_data); BlockReadF(f,buf1,header5.b1len,temp); If NOT (temp = header5.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_macros); BlockReadF(f,buf1,header5.b2len,temp); If NOT (temp = header5.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.macro_table); BlockReadF(f,buf1,header5.b3len,temp); If NOT (temp = header5.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_data); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.instr_macros); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.macro_table); BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; APACK_decompress(buf1,songdata.dis_fmreg_col); BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; crc := Update32(buf1,temp,crc); BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; init_songdata; load_flag := 0; SeekF(f,SizeOf(header)); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} progress_num_steps := (header.patts-1) DIV 8 +6; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} If (header.b1len <> 0) then begin BlockReadF(f,buf1,header.b1len,temp); If NOT (temp = header.b1len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; LZH_decompress(buf1,songdata.instr_macros,header.b1len); end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} If (header.b2len <> 0) then begin BlockReadF(f,buf1,header.b2len,temp); If NOT (temp = header.b2len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; LZH_decompress(buf1,songdata.macro_table,header.b2len); end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} If (header.b3len <> 0) then begin BlockReadF(f,buf1,header.b3len,temp); If NOT (temp = header.b3len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; LZH_decompress(buf1,songdata.dis_fmreg_col,header.b3len); end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} BlockReadF(f,buf1,header.b4len,temp); If NOT (temp = header.b4len) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} BlockReadF(f,buf1,header.b5len[0],temp); If NOT (temp = header.b5len[0]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; LZH_decompress(buf1,pattdata^[0],header.b5len[0]); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2T LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (temp2*8+8 <= max_patterns) then begin LZH_decompress(buf1,pattdata^[temp2],header.b5len[temp2]); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Inc(progress_step); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end else limit_exceeded := TRUE; end; end; speed := songdata.speed; tempo := songdata.tempo; CloseF(f); songdata_title := NameOnly(songdata_source); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> Case header.ffver of {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> 1..4: load_flag := 3; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> else load_flag := 4; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} temp := calc_max_speedup(songdata.tempo); If (songdata.macro_speedup > temp) then begin Dialog('DUE TO SYSTEM LiMiTATiONS, ~MACRO SPEEDUP~ VALUE IS ~CHANGED~$'+ 'SLOWDOWN: ~'+Num2str(songdata.macro_speedup,10)+'X -> '+Num2str(temp,10)+'X~$', '~O~KAY$',' A2T LOADER ',1); songdata.macro_speedup := temp; end; load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} procedure a2p_file_loader; type tOLD_HEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Word; end; type tHEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; type tNEW_HEADER = Record ident: array[1..11] of Char; crc32: Longint; ffver: Byte; b0len: Longint; end; const id = '_A2pattern_'; var f: File; header: tOLD_HEADER; header2: tHEADER; temp: Longint; line,chan: Byte; temp_str: String; crc: Longint; _pattern: Byte; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:a2p_file_loader'; {$ENDIF} If (pattern2use <> BYTE_NULL) then _pattern := pattern2use else _pattern := pattern_patt; {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); 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); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; If NOT (header.ffver in [1..FFVER_A2P]) then begin CloseF(f); Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; init_old_songdata; If (header.ffver in [1..4]) then begin FillChar(adsr_carrier,SizeOf(adsr_carrier),BYTE(FALSE)); crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header.b0len,2,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; Case header.ffver of 4: Move(buf1,old_hash_buffer,header.b0len); 3: LZSS_decompress(buf1,old_hash_buffer,header.b0len); 2: LZW_decompress(buf1,old_hash_buffer); 1: SIXPACK_decompress(buf1,old_hash_buffer,header.b0len); end; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then begin For line := 0 to $3f do For chan := 1 to 9 do import_old_a2m_event1(temp,line,chan,old_hash_buffer[0][line][chan],FALSE); songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end; end else begin For line := 0 to $3f do For chan := 1 to 9 do import_old_a2m_event1(_pattern,line,chan,old_hash_buffer[0][line][chan],FALSE); songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; If (header.ffver in [5..8]) then begin crc := DWORD_NULL; BlockReadF(f,buf1,header.b0len,temp); If NOT (temp = header.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header.b0len,2,crc); If (crc <> header.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; Case header.ffver of 8: Move(buf1,hash_buffer[0],header.b0len); 7: LZSS_decompress(buf1,hash_buffer[0],header.b0len); 6: LZW_decompress(buf1,hash_buffer[0]); 5: SIXPACK_decompress(buf1,hash_buffer[0],header.b0len); end; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then begin For line := 0 to $3f do For chan := 1 to 18 do import_old_a2m_event2(temp,line,chan,hash_buffer[0][chan][line]); songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end; end else begin For line := 0 to $3f do For chan := 1 to 18 do import_old_a2m_event2(_pattern,line,chan,hash_buffer[0][chan][line]); songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; If (header.ffver = 9) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header2.b0len,2,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then APACK_decompress(buf1,pattdata^[temp DIV 8][temp MOD 8]); songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end else begin APACK_decompress(buf1,pattdata^[_pattern DIV 8][_pattern MOD 8]); songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; If (header.ffver = 10) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header2.b0len,2,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then begin APACK_decompress(buf1,buf2); Move(buf2,pattdata^[temp DIV 8][temp MOD 8],PATTERN_SIZE); Move(buf2[PATTERN_SIZE],temp_str,buf2[PATTERN_SIZE]+1); If (temp_str <> '') then songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ temp_str else songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end; end else begin APACK_decompress(buf1,buf2); Move(buf2,pattdata^[_pattern DIV 8][_pattern MOD 8],PATTERN_SIZE); Move(buf2[PATTERN_SIZE],temp_str,buf2[PATTERN_SIZE]+1); If (temp_str <> '') then songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ temp_str else songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; If (header.ffver = FFVER_A2P) then begin ResetF(f); BlockReadF(f,header2,SizeOf(header2),temp); If NOT ((temp = SizeOf(header2)) and (header2.ident = id)) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := DWORD_NULL; BlockReadF(f,buf1,header2.b0len,temp); If NOT (temp = header2.b0len) then begin CloseF(f); Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; crc := Update32(buf1,temp,crc); crc := Update32(header2.b0len,2,crc); If (crc <> header2.crc32) then begin CloseF(f); Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' A2P LOADER ',1); EXIT; end; progress_num_steps := 0; If (pattern2use <> BYTE_NULL) and (_patts_marked <> 0) then For temp := 0 to PRED(max_patterns) do begin If (songdata.pattern_names[temp][1] <> ' ') then begin LZH_decompress(buf1,buf2,header2.b0len); Move(buf2,pattdata^[temp DIV 8][temp MOD 8],PATTERN_SIZE); Move(buf2[PATTERN_SIZE],temp_str,buf2[PATTERN_SIZE]+1); If (temp_str <> '') then songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ temp_str else songdata.pattern_names[temp] := Copy(songdata.pattern_names[temp],1,11)+ Lower(NameOnly(songdata_source)); end; end else begin LZH_decompress(buf1,buf2,header2.b0len); Move(buf2,pattdata^[_pattern DIV 8][_pattern MOD 8],PATTERN_SIZE); Move(buf2[PATTERN_SIZE],temp_str,buf2[PATTERN_SIZE]+1); If (temp_str <> '') then songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ temp_str else songdata.pattern_names[_pattern] := Copy(songdata.pattern_names[_pattern],1,11)+ Lower(NameOnly(songdata_source)); end; end; CloseF(f); load_flag := 1; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:amd_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If NOT (header.versn in [$10,$11]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' '+iCASE(ExtOnly(songdata_source))+' LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> If (header.ident = id_amd) then load_flag := 5} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> else load_flag := 6;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:cff_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR DECOMPRESSiNG MODULE DATA$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' CFF LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 7;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:dfm_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' DFM LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 8;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:hsc_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> If (Lower(ExtOnly(songdata_source)) <> 'hsc') then} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> begin} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> EXIT;} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> end;} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' HSC LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} FillChar(hscbuf,SizeOf(hscbuf),0); BlockReadF(f,hscbuf,SizeOf(hscbuf),temp); If (temp < SizeOf(hscbuf.instr)+SizeOf(hscbuf.order)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' HSC LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 9;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:mtk_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' MTK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.id_string = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' MTK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('CRC FAiLED - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' MTK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; FillChar(buffer2,SizeOf(buffer2),0); temp2 := RDC_decompress(buf1,buffer2,temp); If NOT (temp2 = header.data_size) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' MTK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 10;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} procedure list_rad_description(length: Word); var desc: array[1..22] of String[80]; temp,fkey: Word; row,temp2: Byte; xstart,ystart: Byte; begin FillChar(desc,SizeOf(desc),0); temp := 0; row := 1; While (dscbuf[temp] <> #0) and (temp < length) do begin Case dscbuf[temp] of #1: If (row < 22) then Inc(row); #2..#31: For temp2 := 1 to BYTE(dscbuf[temp]) do desc[row] := desc[row]+' '; #32..#255: desc[row] := desc[row]+dscbuf[temp]; end; Inc(temp); end; temp2 := 0; For temp := 1 to 22 do If (truncate_string(desc[temp]) <> '') then Inc(temp2); If (temp2 = 0) then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; centered_frame(xstart,ystart,81,24,' RAD DESCRiPTiON ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); For temp := 1 to 22 do ShowStr(screen_ptr,xstart+1,ystart+temp,FilterStr2(desc[temp],_valid_characters,'_'), dialog_background+dialog_context_dis); ShowCStr(screen_ptr,xstart+36,ystart+23,' ~C~ONTiNUE ', dialog_sel_itm_bck+dialog_sel_itm, dialog_sel_itm_bck+dialog_sel_short); Repeat fkey := getkey; until (fkey = kESC) or (fkey = kENTER) or (HI(fkey) = $2e); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+81+2; move_to_screen_area[4] := ystart+24+1; move2screen; no_status_refresh := TRUE; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} begin {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:rad_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' RAD LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' RAD LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (header.rmver <> $10) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' RAD LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1),temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' RAD LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' RAD LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If mod_description and (temp2 <> 0) and NOT quick_cmd and NOT shift_pressed then list_rad_description(temp2+1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 11;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:s3m_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.id = id_mod)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If (header.byte1a <> $1a) or (header.ftype <> $10) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT TYPE$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} BlockReadF(f,order_list,header.ordnum,temp); If (IOresult <> 0) or (temp <> header.ordnum) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,paraptr_ins,header.insnum*2,temp); If (IOresult <> 0) or (temp <> header.insnum*2) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,paraptr_pat,header.patnum*2,temp); If (IOresult <> 0) or (temp <> header.patnum*2) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} For temp2 := 1 to max(temp,18) do If (header.chan_set[temp2] OR $80 = header.chan_set[temp2]) then channel_flag[temp2] := FALSE; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,insdata,SizeOf(insdata),temp2); If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,patlen,SizeOf(patlen),temp2); If (temp2 <> SizeOf(patlen)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' S3M LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 12;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} procedure list_fmk_description(rows: Byte); var desc: array[1..24] of String[20]; temp,fkey: Word; row,temp2: Byte; xstart,ystart: Byte; begin FillChar(desc,SizeOf(desc),0); temp := 0; For row := 1 to rows do begin desc[row] := ''; For temp2 := 1 to 20 do begin desc[row] := desc[row]+dscbuf[temp]; Inc(temp); end; end; temp2 := 0; For temp := 1 to rows do If (truncate_string(desc[temp]) <> '') then Inc(temp2); If (temp2 = 0) then EXIT; ScreenMemCopy(screen_ptr,ptr_screen_backup); centered_frame_vdest := screen_ptr; centered_frame(xstart,ystart,21,26,' FMK DESCRiPTiON ', dialog_background+dialog_border, dialog_background+dialog_title, frame_double); For temp := 1 to rows do ShowStr(screen_ptr,xstart+1,ystart+temp,FilterStr2(desc[temp],_valid_characters,'_'), dialog_background+dialog_context_dis); ShowCStr(screen_ptr,xstart+6,ystart+25,' ~C~ONTiNUE ', dialog_sel_itm_bck+dialog_sel_itm, dialog_sel_itm_bck+dialog_sel_short); Repeat fkey := getkey; until (fkey = kESC) or (fkey = kENTER) or (HI(fkey) = $2e); move_to_screen_data := ptr_screen_backup; move_to_screen_area[1] := xstart; move_to_screen_area[2] := ystart; move_to_screen_area[3] := xstart+21+2; move_to_screen_area[4] := ystart+26+1; move2screen; no_status_refresh := TRUE; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:fmk_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.id = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If (header.bytef4 <> $f4) or NOT (header.ftype in [1,2]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT TYPE$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} If (header.ftype = 2) then begin SeekF(f,SizeOf(header)-2); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; BlockReadF(f,paraptr_msg,SizeOf(paraptr_msg),temp); If (IOresult <> 0) or (temp <> SizeOf(paraptr_msg)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; fpos_bak := FilePos(f); If (paraptr_msg <> 0) then begin SeekF(f,paraptr_msg); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,desc_rows,SizeOf(desc_rows),temp); If (IOresult <> 0) or (temp <> SizeOf(desc_rows)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If mod_description and (desc_rows <> 0) and NOT quick_cmd and NOT shift_pressed then list_fmk_description(desc_rows); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; SeekF(f,fpos_bak); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,insdata,SizeOf(insdata),temp2); If (IOresult <> 0) or (temp2 <> SizeOf(insdata)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If (paraptr_pat[pat] = 0) then CONTINUE; BlockReadF(f,patlen,SizeOf(patlen),temp2); If (temp2 <> SizeOf(patlen)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' FMK LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 13;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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 {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:sat_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If NOT (header.vernm in [1,5,6]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} SATver := header.vernm; If (SATver in [5,6]) then begin SeekF(f,0); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,headr2,SizeOf(headr2),temp); If (temp <> SizeOf(headr2)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SAT LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 14;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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 } {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'ILOADERS.INC:sa2_file_loader'; {$ENDIF} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {$i-} Assign(f,songdata_source); ResetF(f); {$i+} If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; BlockReadF(f,header,SizeOf(header),temp); If NOT ((temp = SizeOf(header)) and (header.ident = id)) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - FiLE CORRUPTED$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; If NOT (header.vernm in [8,9]) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('UNKNOWN FiLE FORMAT VERSiON$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} If (play_status <> isStopped) then begin fade_out_playback(FALSE); stop_playing; end; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := $7f;} If (header.vernm = 8) then begin SeekF(f,FilePos(f)-2); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} EXIT; end; end; FillChar(buf1,SizeOf(buf1),0); BlockReadF(f,buf1,SizeOf(buf1)-3,temp); If (IOresult <> 0) then begin CloseF(f); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} Dialog('ERROR READiNG DATA - DiSK ERROR?$'+ 'LOADiNG STOPPED$', '~O~KAY$',' SA2 LOADER ',1); {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} 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); {@ADT2PLAY_COMPILER_DIRECTIVE:INSERT> load_flag := 15;} {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_BEGIN} load_flag := 1; {@ADT2PLAY_COMPILER_DIRECTIVE:SKIP_END} end; adlibtracker2-2.4.24/menulib2.pas0000644000000000000000000004624213411003760015237 0ustar rootroot// 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 MenuLib2; {$S-,Q-,R-,V-,B-,X+} {$PACKRECORDS 1} interface uses DOS, AdT2unit,AdT2sys,AdT2keyb,AdT2ext2, DialogIO,TxtScrIO,StringIO,ParserIO; const MenuLib2_mn_setting: Record frame_type: String; shadow_enabled: Boolean; posbar_enabled: Boolean; title_attr, menu_attr, text_attr, text2_attr, default_attr, short_attr, short2_attr, disbld_attr, contxt_attr, contxt2_attr: Byte; center_box: Boolean; cycle_moves: Boolean; edit_contents: Boolean; reverse_use: Boolean; fixed_len: Byte; terminate_keys: array[1..50] of Word; end = (frame_type: frame_single; shadow_enabled: TRUE; posbar_enabled: TRUE; title_attr: $0f; menu_attr: $07; text_attr: $07; text2_attr: $70; default_attr: $0f; short_attr: $0f; short2_attr: $70; disbld_attr: $07; contxt_attr: $0f; contxt2_attr: $07; center_box: TRUE; cycle_moves: TRUE; edit_contents: FALSE; reverse_use: FALSE; fixed_len: 0; terminate_keys: ($011b,$1c0d,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000, $0000,$0000,$0000,$0000,$0000)); var MenuLib2_mn_environment: Record v_dest: tSCREEN_MEM_PTR; keystroke: Word; context: String; unpolite: Boolean; winshade: Boolean; edit_pos: Byte; curr_pos: Word; ext_proc: procedure; refresh: procedure; do_refresh: Boolean; preview: Boolean; descr_len: Byte; descr: Pointer; end; function MenuLib2_Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure MenuLib2_Init; implementation type tDBUFFR = array[1.. 100] of Record str: String; pos: Byte; key: Char; use: Boolean; end; type tMBUFFR = array[1..16384] of Record key: Char; use: Boolean; end; var idx,idx2,max,len2b,page, first,last,temp,temp2,opage,opos: Word; old_fr_shadow_enabled: Boolean; key: Word; solid: Boolean; qflg: Boolean; mbuf: tMBUFFR; contxt: String; var mnu_x,mnu_y,mnu_len,mnu_len2: Byte; mnu_data: Pointer; mnu_count: Word; var vscrollbar_pos: Word; function OutKey(str: String): Char; var result: Char; begin If (SYSTEM.Pos('~',str) = 0) then result := '~' else If (str[SYSTEM.Pos('~',str)+2] <> '~') then result := '~' else result := str[SYSTEM.Pos('~',str)+1]; OutKey := result; end; function pstr(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:pstr'; {$ENDIF} Move(pBYTE(mnu_data)[(item-1)*(mnu_len+1)],temp,mnu_len+1); If NOT solid then pstr := ExpStrR(temp,mnu_len-2,' ') else pstr := ExpStrR(temp,mnu_len,' '); end; function pdes(item: Word): String; var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:pdes'; {$ENDIF} If (mn_environment.descr <> NIL) then Move(pBYTE(mn_environment.descr)[(item-1)*(mn_environment.descr_len+1)],temp,mn_environment.descr_len+1) else temp := ''; pdes := ExpStrR(temp,mn_environment.descr_len,' '); end; procedure refresh; procedure ShowCStr_clone(dest: tSCREEN_MEM_PTR; x,y: Byte; str: String; atr1,atr2,atr3,atr4: Byte); var temp,len: Byte; highlighted: Boolean; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:refresh:ShowCStr_clone'; {$ENDIF} If NOT (MenuLib2_mn_setting.fixed_len <> 0) then begin ShowCStr(dest,x,y,str,atr1,atr2); EXIT; end; highlighted := FALSE; len := 0; For temp := 1 to Length(str) do If (str[temp] = '~') then highlighted := NOT highlighted else begin If (len < MenuLib2_mn_setting.fixed_len) then begin If NOT highlighted then ShowStr(dest,x+len,y,str[temp],atr1) else ShowStr(dest,x+len,y,str[temp],atr2); Inc(len); end else begin If NOT highlighted then ShowStr(dest,x+len,y,str[temp],atr3) else ShowStr(dest,x+len,y,str[temp],atr4); Inc(len); end end; end; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:refresh'; {$ENDIF} If (page = opage) and (idx2 = opos) and NOT MenuLib2_mn_environment.do_refresh then EXIT else begin opage := page; opos := idx2; MenuLib2_mn_environment.do_refresh := FALSE; end; For idx := page to mnu_len2+page-1 do If (idx = idx2+page-1) then ShowCStr_clone(MenuLib2_mn_environment.v_dest,mnu_x+1,mnu_y+idx2, ExpStrR(pstr(idx2+page-1)+pdes(idx2+page-1), max+(Length(pstr(idx2+page-1))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx2+page-1)+pdes(idx2+page-1))),' '), MenuLib2_mn_setting.text2_attr,MenuLib2_mn_setting.short2_attr, MenuLib2_mn_setting.text_attr,MenuLib2_mn_setting.short_attr) else If mbuf[idx].use then ShowCStr(MenuLib2_mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(pstr(idx)+pdes(idx), max+(Length(pstr(idx))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx)+pdes(idx))),' '), MenuLib2_mn_setting.text_attr,MenuLib2_mn_setting.short_attr) else ShowCStr(MenuLib2_mn_environment.v_dest,mnu_x+1,mnu_y+idx-page+1, ExpStrR(pstr(idx)+pdes(idx), max+(Length(pstr(idx))+Length(pdes(idx2+page-1))- CStrLen(pstr(idx)+pdes(idx))),' '), MenuLib2_mn_setting.disbld_attr,MenuLib2_mn_setting.disbld_attr); vscrollbar_pos := VScrollBar(MenuLib2_mn_environment.v_dest,mnu_x+max+1,mnu_y+1,temp2,mnu_count,idx2+page-1, vscrollbar_pos,MenuLib2_mn_setting.menu_attr,MenuLib2_mn_setting.menu_attr); end; function MenuLib2_Menu(var data; x,y: Byte; spos: Word; len,len2: Byte; count: Word; title: String): Word; procedure SubPos(var p: Word); var temp: Word; begin temp := p; If (temp > 1) and mbuf[temp+page-2].use then Dec(temp) else If (temp > 1) then begin Dec(temp); SubPos(temp); end else If (page > first) then Dec(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 > first) then SubPos(temp); end; procedure AddPos(var p: Word); var temp: Word; begin temp := p; If (temp < len2) and (temp < last) and mbuf[temp+page].use then Inc(temp) else If (temp < len2) and (temp < last) then begin Inc(temp); AddPos(temp); end else If (page+temp <= last) then Inc(page); If mbuf[temp+page-1].use then p := temp else If (temp+page-1 < last) then AddPos(temp); end; function RetKey(code: Byte): Word; var temp: Byte; begin RetKey := 0; For temp := 1 to count do If (UpCase(mbuf[temp].key) = UpCase(CHR(code))) then begin RetKey := temp; BREAK; end; end; procedure edit_contents(item: Word); var temp: String; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:MenuLib2_Menu:edit_contents'; {$ENDIF} is_setting.append_enabled := TRUE; is_setting.character_set := [#32..#255]; is_environment.locate_pos := 1; If (MenuLib2_mn_environment.edit_pos > 0) and (MenuLib2_mn_environment.edit_pos < max-2) then temp := Copy(pstr(item),MenuLib2_mn_environment.edit_pos+1, Length(pstr(item))-MenuLib2_mn_environment.edit_pos+1) else temp := CutStr(pstr(item)); While (temp <> '') and (temp[Length(temp)] = ' ') do Delete(temp,Length(temp),1); temp := InputStr(temp,x+1+MenuLib2_mn_environment.edit_pos,y+idx2, max-2-MenuLib2_mn_environment.edit_pos+1, max-2-MenuLib2_mn_environment.edit_pos+1, MenuLib2_mn_setting.text2_attr,MenuLib2_mn_setting.default_attr); If (is_environment.keystroke = kENTER) then begin If (MenuLib2_mn_environment.edit_pos > 0) and (MenuLib2_mn_environment.edit_pos < max-2) then temp := Copy(pstr(item),1,MenuLib2_mn_environment.edit_pos)+temp else temp := CutStr(temp); Move(temp,pBYTE(mnu_data)[(item-1)*(len+1)],len+1); end; ShowCStr(MenuLib2_mn_environment.v_dest,x+1,y+idx2, ExpStrR(pstr(item),max+(Length(pstr(item)))- CStrLen(pstr(item)),' '), MenuLib2_mn_setting.text2_attr,MenuLib2_mn_setting.short2_attr); end; begin { MenuLib2_Menu } {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:MenuLib2_Menu'; {$ENDIF} If (count = 0) then begin MenuLib2_Menu := 0; EXIT; end; max := Length(title); mnu_data := Addr(data); mnu_count := count; mnu_len := len; If NOT MenuLib2_mn_environment.unpolite then ScreenMemCopy(MenuLib2_mn_environment.v_dest,ptr_scr_backup); If (count < 1) then EXIT; vscrollbar_pos := BYTE_NULL; If NOT MenuLib2_mn_environment.preview then HideCursor; temp := 0; For idx := 1 to count do begin mbuf[idx].key := OutKey(pstr(idx)); If NOT MenuLib2_mn_setting.reverse_use then mbuf[idx].use := mbuf[idx].key <> '~' else mbuf[idx].use := NOT (mbuf[idx].key <> '~'); If mbuf[idx].use then temp := 1; end; solid := FALSE; If (temp = 0) then begin For temp := 1 to count do mbuf[temp].use := TRUE; solid := TRUE; end; For idx := 1 to count do If (max < CStrLen(pstr(idx))+MenuLib2_mn_environment.descr_len) then max := CStrLen(pstr(idx))+MenuLib2_mn_environment.descr_len; If MenuLib2_mn_setting.center_box then begin x := (work_MaxCol-max-2) DIV 2+(work_MaxCol-max-2) MOD 2; y := (work_MaxLn-len2-1) DIV 2+(work_MaxLn-len2-1) MOD 2; end; mnu_x := x; mnu_y := y; len2b := len2; If NOT MenuLib2_mn_environment.unpolite then begin old_fr_shadow_enabled := fr_setting.shadow_enabled; fr_setting.shadow_enabled := MenuLib2_mn_setting.shadow_enabled; fr_setting.update_area := FALSE; Frame(MenuLib2_mn_environment.v_dest,x,y,x+max+1,y+len2+1,MenuLib2_mn_setting.menu_attr, title,MenuLib2_mn_setting.title_attr,MenuLib2_mn_setting.frame_type); fr_setting.update_area := TRUE; fr_setting.shadow_enabled := old_fr_shadow_enabled; contxt := DietStr(MenuLib2_mn_environment.context,max+ (Length(MenuLib2_mn_environment.context)-CStrLen(MenuLib2_mn_environment.context))); ShowCStr(MenuLib2_mn_environment.v_dest,x+max+1-CStrLen(contxt),y+len2+1, contxt,MenuLib2_mn_setting.contxt_attr,MenuLib2_mn_setting.contxt2_attr); temp2 := len2; If (len2 > count) then len2 := count; If (len2 < 1) then len2 := 1; If (spos < 1) then spos := 1; If (spos > count) then spos := count; mnu_len2 := len2; MenuLib2_mn_environment.refresh := refresh; first := 1; last := count; While NOT mbuf[first].use do Inc(first); While NOT mbuf[last].use do Dec(last); If (spos < first) or (spos > last) then spos := first; idx2 := 1; page := 1; opage := WORD_NULL; opos := WORD_NULL; While (idx2+page-1 < spos) do AddPos(idx2); end; MenuLib2_mn_environment.curr_pos := idx2+page-1; MenuLib2_mn_environment.keystroke := WORD_NULL; If (Addr(MenuLib2_mn_environment.ext_proc) <> NIL) then MenuLib2_mn_environment.ext_proc; qflg := FALSE; If MenuLib2_mn_environment.preview then begin MenuLib2_mn_environment.preview := FALSE; MenuLib2_mn_environment.unpolite := TRUE; refresh; end else Repeat key := getkey; If LookUpKey(key,MenuLib2_mn_setting.terminate_keys,50) then If NOT ((key = MenuLib2_mn_setting.terminate_keys[2]) and MenuLib2_mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx2+page-1); If NOT qflg then If (LO(key) in [$20..$0ff]) then begin idx := RetKey(LO(key)); If (idx <> 0) then begin refresh; idx2 := idx; If NOT ((key = MenuLib2_mn_setting.terminate_keys[2]) and MenuLib2_mn_setting.edit_contents) then qflg := TRUE else edit_contents(idx); end; end else If NOT shift_pressed and NOT ctrl_pressed and NOT alt_pressed then Case key of kUP: If (page+idx2-1 > first) or NOT MenuLib2_mn_setting.cycle_moves then SubPos(idx2) else begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kDOWN: If (page+idx2-1 < last) or NOT MenuLib2_mn_setting.cycle_moves then AddPos(idx2) else begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kHOME: begin idx2 := 1; page := 1; If NOT mbuf[idx2+page-1].use then AddPos(idx2); end; kEND: begin idx2 := len2; page := count-len2+1; If NOT mbuf[idx2+page-1].use then SubPos(idx2); end; kPgUP: For temp := 1 to len2-1 do SubPos(idx2); kPgDOWN: For temp := 1 to len2-1 do AddPos(idx2); end; MenuLib2_mn_environment.curr_pos := idx2+page-1; refresh; MenuLib2_mn_environment.keystroke := key; If (Addr(MenuLib2_mn_environment.ext_proc) <> NIL) then MenuLib2_mn_environment.ext_proc; {$IFDEF GO32V2} // draw_screen; keyboard_reset_buffer_alt; {$ELSE} draw_screen; // keyboard_reset_buffer; {$ENDIF} until qflg or _force_program_quit; If MenuLib2_mn_environment.winshade and NOT MenuLib2_mn_environment.unpolite then begin If (Addr(move_to_screen_routine) <> NIL) then begin move_to_screen_data := ptr_scr_backup; move_to_screen_area[1] := x; move_to_screen_area[2] := y; move_to_screen_area[3] := x+max+1+2; move_to_screen_area[4] := y+len2b+1+1; move_to_screen_routine; end else ScreenMemCopy(ptr_scr_backup,MenuLib2_mn_environment.v_dest); end; MenuLib2_Menu := idx2+page-1; end; procedure MenuLib2_Init; begin {$IFDEF GO32V2} _last_debug_str_ := _debug_str_; _debug_str_ := 'MENULIB2.PAS:MenuLib2_Init'; {$ENDIF} MenuLib2_mn_setting.frame_type := frame_single; MenuLib2_mn_setting.center_box := FALSE; MenuLib2_mn_setting.shadow_enabled := FALSE; MenuLib2_mn_setting.cycle_moves := FALSE; MenuLib2_mn_setting.title_attr := dialog_background+dialog_title; MenuLib2_mn_setting.menu_attr := dialog_background+dialog_text; MenuLib2_mn_setting.text_attr := dialog_background+dialog_item; MenuLib2_mn_setting.text2_attr := dialog_sel_itm_bck+dialog_sel_itm; MenuLib2_mn_setting.default_attr := dialog_def_bckg+dialog_def; MenuLib2_mn_setting.short_attr := dialog_background+dialog_short; MenuLib2_mn_setting.short2_attr := dialog_sel_itm_bck+dialog_sel_short; MenuLib2_mn_setting.disbld_attr := dialog_background+dialog_item_dis; MenuLib2_mn_setting.contxt_attr := dialog_background+dialog_context; MenuLib2_mn_setting.contxt2_attr := dialog_background+dialog_context_dis; MenuLib2_mn_setting.terminate_keys[3] := kTAB; MenuLib2_mn_setting.terminate_keys[4] := kLEFT; MenuLib2_mn_setting.terminate_keys[5] := kRIGHT; MenuLib2_mn_setting.terminate_keys[6] := kCtrlO; MenuLib2_mn_setting.terminate_keys[7] := kF1; MenuLib2_mn_setting.terminate_keys[8] := kShTAB; MenuLib2_mn_environment.v_dest := screen_ptr; MenuLib2_mn_environment.keystroke := $0000; MenuLib2_mn_environment.context := ''; MenuLib2_mn_environment.unpolite := FALSE; MenuLib2_mn_environment.winshade := TRUE; MenuLib2_mn_environment.ext_proc := NIL; MenuLib2_mn_environment.refresh := NIL; MenuLib2_mn_environment.do_refresh := FALSE; MenuLib2_mn_environment.preview := FALSE; MenuLib2_mn_environment.descr_len := 0; MenuLib2_mn_environment.descr := NIL; end; end. adlibtracker2-2.4.24/readme-sdl.txt0000644000000000000000000000066613411003760015573 0ustar rootroot Please distribute this file with the SDL runtime environment: The Simple DirectMedia Layer (SDL for short) is a cross-platfrom library designed to make it easy to write multi-media software, such as games and emulators. The Simple DirectMedia Layer library source code is available from: http://www.libsdl.org/ This library is distributed under the terms of the GNU LGPL license: http://www.gnu.org/copyleft/lesser.html