From 634819319de331b39b92ed66edba7a74dba10b25 Mon Sep 17 00:00:00 2001 From: "W.Dee" Date: Thu, 25 Jun 2015 15:58:53 +0900 Subject: [PATCH] Initial import --- core/base/CharacterSet.cpp | 209 ++ core/base/CharacterSet.h | 25 + core/sound/win32/tvpsnd.c | 56 + core/sound/win32/tvpsnd.h | 814 +++++ core/sound/win32/tvpsnd.idl | 173 + core/sound/win32/tvpsnd.txt | 399 +++ tools/win32/callerexe/build.bat | 51 + tools/win32/callerexe/callerlib.c | 37 + tools/win32/callerexe/find_kirikiri.c | 123 + tools/win32/callerexe/find_kirikiri.h | 6 + tools/win32/callerexe/krkrconf.ico | Bin 0 -> 4710 bytes tools/win32/callerexe/krkrconf.rc | 34 + tools/win32/callerexe/krkrfont.ico | Bin 0 -> 18718 bytes tools/win32/callerexe/krkrfont.rc | 34 + tools/win32/callerexe/krkrfont.svg | 520 +++ tools/win32/callerexe/krkrlt.ico | Bin 0 -> 16158 bytes tools/win32/callerexe/krkrlt.rc | 34 + tools/win32/callerexe/krkrlt.svg | 154 + tools/win32/callerexe/krkrrel.ico | Bin 0 -> 4710 bytes tools/win32/callerexe/krkrrel.rc | 34 + tools/win32/callerexe/krkrsign.ico | Bin 0 -> 19790 bytes tools/win32/callerexe/krkrsign.rc | 34 + tools/win32/callerexe/krkrsign.svg | 141 + tools/win32/callerexe/krkrtpc.ico | Bin 0 -> 3638 bytes tools/win32/callerexe/krkrtpc.rc | 34 + tools/win32/callerexe/startup.OBJ | Bin 0 -> 536 bytes tools/win32/callerexe/startup.asm | 21 + tools/win32/callerexe/userconf.rc | 34 + tools/win32/callerexe/userconf_main.c | 62 + tools/win32/callerexe/util.c | 30 + tools/win32/callerexe/util.h | 12 + tools/win32/callerexe/xp3_stub.c | 66 + tools/win32/krdevui/ConfMain.cpp | 58 + tools/win32/krdevui/ConfMain.h | 12 + tools/win32/krdevui/ConfMainFrameUnit.cpp | 2013 +++++++++++ tools/win32/krdevui/ConfMainFrameUnit.dfm | 221 ++ tools/win32/krdevui/ConfMainFrameUnit.h | 197 + tools/win32/krdevui/ConfSettingsUnit.cpp | 125 + tools/win32/krdevui/ConfSettingsUnit.dfm | 128 + tools/win32/krdevui/ConfSettingsUnit.h | 44 + tools/win32/krdevui/FolderSelectorUnit.cpp | 224 ++ tools/win32/krdevui/FolderSelectorUnit.dfm | 1632 +++++++++ tools/win32/krdevui/FolderSelectorUnit.h | 66 + tools/win32/krdevui/FontMakerUnit.cpp | 467 +++ tools/win32/krdevui/FontMakerUnit.dfm | 778 ++++ tools/win32/krdevui/FontMakerUnit.h | 98 + tools/win32/krdevui/FontMakerWriteUnit.cpp | 333 ++ tools/win32/krdevui/FontMakerWriteUnit.dfm | 46 + tools/win32/krdevui/FontMakerWriteUnit.h | 69 + tools/win32/krdevui/FontPreviewUnit.cpp | 515 +++ tools/win32/krdevui/FontPreviewUnit.dfm | 92 + tools/win32/krdevui/FontPreviewUnit.h | 99 + tools/win32/krdevui/KrkrExecutableUnit.cpp | 74 + tools/win32/krdevui/KrkrExecutableUnit.h | 14 + tools/win32/krdevui/MainUnit.cpp | 65 + tools/win32/krdevui/RandomizeFormUnit.cpp | 131 + tools/win32/krdevui/RandomizeFormUnit.dfm | 73 + tools/win32/krdevui/RandomizeFormUnit.h | 49 + tools/win32/krdevui/RelDirSearchUnit.cpp | 119 + tools/win32/krdevui/RelDirSearchUnit.dfm | 194 + tools/win32/krdevui/RelDirSearchUnit.h | 39 + tools/win32/krdevui/RelFolderSelectorUnit.cpp | 94 + tools/win32/krdevui/RelFolderSelectorUnit.dfm | 252 ++ tools/win32/krdevui/RelFolderSelectorUnit.h | 43 + tools/win32/krdevui/RelMain.cpp | 369 ++ tools/win32/krdevui/RelMain.h | 130 + tools/win32/krdevui/RelSettingsUnit.cpp | 1366 +++++++ tools/win32/krdevui/RelSettingsUnit.dfm | 740 ++++ tools/win32/krdevui/RelSettingsUnit.h | 153 + tools/win32/krdevui/SignMainFormUnit.cpp | 351 ++ tools/win32/krdevui/SignMainFormUnit.dfm | 1014 ++++++ tools/win32/krdevui/SignMainFormUnit.h | 87 + tools/win32/krdevui/SignUnit.cpp | 289 ++ tools/win32/krdevui/SignUnit.h | 12 + tools/win32/krdevui/intermediate/dummy.txt | 1 + tools/win32/krdevui/krdevui.bpf | 50 + tools/win32/krdevui/krdevui.bpr | 188 + tools/win32/krdevui/krdevui.res | Bin 0 -> 1836 bytes tools/win32/krdevui/looptuner2/ColorScheme.h | 67 + tools/win32/krdevui/looptuner2/DSound.cpp | 450 +++ tools/win32/krdevui/looptuner2/DSound.h | 33 + .../looptuner2/EditLabelAttribUnit.cpp | 91 + .../looptuner2/EditLabelAttribUnit.dfm | 26 + .../krdevui/looptuner2/EditLabelAttribUnit.h | 51 + .../krdevui/looptuner2/EditLinkAttribUnit.cpp | 164 + .../krdevui/looptuner2/EditLinkAttribUnit.dfm | 86 + .../krdevui/looptuner2/EditLinkAttribUnit.h | 63 + .../krdevui/looptuner2/LabelDetailUnit.cpp | 82 + .../krdevui/looptuner2/LabelDetailUnit.dfm | 45 + .../krdevui/looptuner2/LabelDetailUnit.h | 48 + .../krdevui/looptuner2/LinkDetailUnit.cpp | 835 +++++ .../krdevui/looptuner2/LinkDetailUnit.dfm | 630 ++++ .../win32/krdevui/looptuner2/LinkDetailUnit.h | 181 + .../krdevui/looptuner2/LoopTunerMainUnit.cpp | 1006 ++++++ .../krdevui/looptuner2/LoopTunerMainUnit.dfm | 2086 +++++++++++ .../krdevui/looptuner2/LoopTunerMainUnit.h | 258 ++ .../krdevui/looptuner2/RIFFWaveContext.cpp | 268 ++ .../krdevui/looptuner2/RIFFWaveContext.h | 49 + .../krdevui/looptuner2/TSSWaveContext.cpp | 154 + .../win32/krdevui/looptuner2/TSSWaveContext.h | 98 + tools/win32/krdevui/looptuner2/TotalView.cpp | 479 +++ tools/win32/krdevui/looptuner2/TotalView.h | 121 + tools/win32/krdevui/looptuner2/WaveContext.h | 38 + .../krdevui/looptuner2/WaveLoopManager.cpp | 1436 ++++++++ .../krdevui/looptuner2/WaveLoopManager.h | 384 ++ tools/win32/krdevui/looptuner2/WaveReader.cpp | 637 ++++ tools/win32/krdevui/looptuner2/WaveReader.h | 155 + tools/win32/krdevui/looptuner2/WaveView.cpp | 3183 +++++++++++++++++ tools/win32/krdevui/looptuner2/WaveView.h | 371 ++ .../krdevui/looptuner2/WaveWriterUnit.cpp | 172 + .../krdevui/looptuner2/WaveWriterUnit.dfm | 55 + .../win32/krdevui/looptuner2/WaveWriterUnit.h | 51 + tools/win32/krdevui/looptuner2/help/Find.html | 74 + tools/win32/krdevui/looptuner2/help/Form.html | 236 ++ .../win32/krdevui/looptuner2/help/Intro.html | 48 + .../win32/krdevui/looptuner2/help/Menus.html | 345 ++ .../krdevui/looptuner2/help/Prepare.html | 80 + tools/win32/krdevui/looptuner2/help/hline.png | Bin 0 -> 123 bytes .../win32/krdevui/looptuner2/help/index.html | 45 + .../win32/krdevui/looptuner2/help/loaded.png | Bin 0 -> 8607 bytes tools/win32/krdevui/looptuner2/help/loop0.png | Bin 0 -> 1077 bytes tools/win32/krdevui/looptuner2/help/tune0.png | Bin 0 -> 8037 bytes tools/win32/krdevui/looptuner2/help/tune1.png | Bin 0 -> 8648 bytes tools/win32/krdevui/looptuner2/help/tune2.png | Bin 0 -> 6074 bytes tools/win32/krdevui/looptuner2/looptune.bpr | 148 + tools/win32/krdevui/looptuner2/looptune.cpp | 173 + tools/win32/krdevui/looptuner2/looptune.drc | 391 ++ tools/win32/krdevui/looptuner2/looptune.h | 22 + tools/win32/krdevui/looptuner2/looptune.res | Bin 0 -> 17048 bytes tools/win32/krdevui/tpc/JPEGQualityUnit.cpp | 48 + tools/win32/krdevui/tpc/JPEGQualityUnit.dfm | 108 + tools/win32/krdevui/tpc/JPEGQualityUnit.h | 42 + tools/win32/krdevui/tpc/LogViewerUnit.cpp | 27 + tools/win32/krdevui/tpc/LogViewerUnit.dfm | 53 + tools/win32/krdevui/tpc/LogViewerUnit.h | 33 + tools/win32/krdevui/tpc/ProgressUnit.cpp | 75 + tools/win32/krdevui/tpc/ProgressUnit.dfm | 51 + tools/win32/krdevui/tpc/ProgressUnit.h | 54 + tools/win32/krdevui/tpc/TLGMetaInfo.cpp | 82 + tools/win32/krdevui/tpc/TLGMetaInfo.h | 11 + tools/win32/krdevui/tpc/TPCMainUnit.cpp | 1169 ++++++ tools/win32/krdevui/tpc/TPCMainUnit.dfm | 346 ++ tools/win32/krdevui/tpc/TPCMainUnit.h | 110 + tools/win32/krdevui/tpc/TPCStub.cpp | 11 + tools/win32/krdevui/tpc/TPCStub.h | 6 + tools/win32/krdevui/tpc/krkrtpc.res | Bin 0 -> 4572 bytes tools/win32/krdevui/tpc/png/DeePNGUnit.cpp | 762 ++++ tools/win32/krdevui/tpc/png/DeePNGUnit.h | 106 + tools/win32/krdevui/tpc/psd/DeePSDUnit.cpp | 1109 ++++++ tools/win32/krdevui/tpc/psd/DeePSDUnit.h | 68 + tools/win32/krdevui/tpc/tlg5/TLG5Saver.cpp | 227 ++ tools/win32/krdevui/tpc/tlg5/TLG5Saver.h | 11 + tools/win32/krdevui/tpc/tlg5/slide.cpp | 213 ++ tools/win32/krdevui/tpc/tlg5/slide.h | 50 + tools/win32/krdevui/tpc/tlg6/GolombTable.cpp | 54 + tools/win32/krdevui/tpc/tlg6/GolombTable.h | 9 + tools/win32/krdevui/tpc/tlg6/TLG6BS.cpp | 0 tools/win32/krdevui/tpc/tlg6/TLG6BS.h | 193 + tools/win32/krdevui/tpc/tlg6/TLG6Saver.cpp | 1141 ++++++ tools/win32/krdevui/tpc/tlg6/TLG6Saver.h | 11 + tools/win32/sigchecker/MainUnit.cpp | 390 ++ tools/win32/sigchecker/MainUnit.dfm | 155 + tools/win32/sigchecker/MainUnit.h | 49 + .../krkrsiglib/KrkrExecutableUnit.cpp | 72 + .../krkrsiglib/KrkrExecutableUnit.h | 14 + .../krkrsiglib/KrkrSignatureUnit.cpp | 264 ++ .../sigchecker/krkrsiglib/KrkrSignatureUnit.h | 11 + tools/win32/sigchecker/loupe.ico | Bin 0 -> 18718 bytes tools/win32/sigchecker/loupe.svg | 267 ++ tools/win32/sigchecker/sigchk.bpr | 115 + tools/win32/sigchecker/sigchk.cpp | 25 + tools/win32/sigchecker/sigchk.ini | 16 + tools/win32/sigchecker/sigchk.res | Bin 0 -> 19896 bytes 173 files changed, 39224 insertions(+) create mode 100644 core/base/CharacterSet.cpp create mode 100644 core/base/CharacterSet.h create mode 100644 core/sound/win32/tvpsnd.c create mode 100644 core/sound/win32/tvpsnd.h create mode 100644 core/sound/win32/tvpsnd.idl create mode 100644 core/sound/win32/tvpsnd.txt create mode 100644 tools/win32/callerexe/build.bat create mode 100644 tools/win32/callerexe/callerlib.c create mode 100644 tools/win32/callerexe/find_kirikiri.c create mode 100644 tools/win32/callerexe/find_kirikiri.h create mode 100644 tools/win32/callerexe/krkrconf.ico create mode 100644 tools/win32/callerexe/krkrconf.rc create mode 100644 tools/win32/callerexe/krkrfont.ico create mode 100644 tools/win32/callerexe/krkrfont.rc create mode 100644 tools/win32/callerexe/krkrfont.svg create mode 100644 tools/win32/callerexe/krkrlt.ico create mode 100644 tools/win32/callerexe/krkrlt.rc create mode 100644 tools/win32/callerexe/krkrlt.svg create mode 100644 tools/win32/callerexe/krkrrel.ico create mode 100644 tools/win32/callerexe/krkrrel.rc create mode 100644 tools/win32/callerexe/krkrsign.ico create mode 100644 tools/win32/callerexe/krkrsign.rc create mode 100644 tools/win32/callerexe/krkrsign.svg create mode 100644 tools/win32/callerexe/krkrtpc.ico create mode 100644 tools/win32/callerexe/krkrtpc.rc create mode 100644 tools/win32/callerexe/startup.OBJ create mode 100644 tools/win32/callerexe/startup.asm create mode 100644 tools/win32/callerexe/userconf.rc create mode 100644 tools/win32/callerexe/userconf_main.c create mode 100644 tools/win32/callerexe/util.c create mode 100644 tools/win32/callerexe/util.h create mode 100644 tools/win32/callerexe/xp3_stub.c create mode 100644 tools/win32/krdevui/ConfMain.cpp create mode 100644 tools/win32/krdevui/ConfMain.h create mode 100644 tools/win32/krdevui/ConfMainFrameUnit.cpp create mode 100644 tools/win32/krdevui/ConfMainFrameUnit.dfm create mode 100644 tools/win32/krdevui/ConfMainFrameUnit.h create mode 100644 tools/win32/krdevui/ConfSettingsUnit.cpp create mode 100644 tools/win32/krdevui/ConfSettingsUnit.dfm create mode 100644 tools/win32/krdevui/ConfSettingsUnit.h create mode 100644 tools/win32/krdevui/FolderSelectorUnit.cpp create mode 100644 tools/win32/krdevui/FolderSelectorUnit.dfm create mode 100644 tools/win32/krdevui/FolderSelectorUnit.h create mode 100644 tools/win32/krdevui/FontMakerUnit.cpp create mode 100644 tools/win32/krdevui/FontMakerUnit.dfm create mode 100644 tools/win32/krdevui/FontMakerUnit.h create mode 100644 tools/win32/krdevui/FontMakerWriteUnit.cpp create mode 100644 tools/win32/krdevui/FontMakerWriteUnit.dfm create mode 100644 tools/win32/krdevui/FontMakerWriteUnit.h create mode 100644 tools/win32/krdevui/FontPreviewUnit.cpp create mode 100644 tools/win32/krdevui/FontPreviewUnit.dfm create mode 100644 tools/win32/krdevui/FontPreviewUnit.h create mode 100644 tools/win32/krdevui/KrkrExecutableUnit.cpp create mode 100644 tools/win32/krdevui/KrkrExecutableUnit.h create mode 100644 tools/win32/krdevui/MainUnit.cpp create mode 100644 tools/win32/krdevui/RandomizeFormUnit.cpp create mode 100644 tools/win32/krdevui/RandomizeFormUnit.dfm create mode 100644 tools/win32/krdevui/RandomizeFormUnit.h create mode 100644 tools/win32/krdevui/RelDirSearchUnit.cpp create mode 100644 tools/win32/krdevui/RelDirSearchUnit.dfm create mode 100644 tools/win32/krdevui/RelDirSearchUnit.h create mode 100644 tools/win32/krdevui/RelFolderSelectorUnit.cpp create mode 100644 tools/win32/krdevui/RelFolderSelectorUnit.dfm create mode 100644 tools/win32/krdevui/RelFolderSelectorUnit.h create mode 100644 tools/win32/krdevui/RelMain.cpp create mode 100644 tools/win32/krdevui/RelMain.h create mode 100644 tools/win32/krdevui/RelSettingsUnit.cpp create mode 100644 tools/win32/krdevui/RelSettingsUnit.dfm create mode 100644 tools/win32/krdevui/RelSettingsUnit.h create mode 100644 tools/win32/krdevui/SignMainFormUnit.cpp create mode 100644 tools/win32/krdevui/SignMainFormUnit.dfm create mode 100644 tools/win32/krdevui/SignMainFormUnit.h create mode 100644 tools/win32/krdevui/SignUnit.cpp create mode 100644 tools/win32/krdevui/SignUnit.h create mode 100644 tools/win32/krdevui/intermediate/dummy.txt create mode 100644 tools/win32/krdevui/krdevui.bpf create mode 100644 tools/win32/krdevui/krdevui.bpr create mode 100644 tools/win32/krdevui/krdevui.res create mode 100644 tools/win32/krdevui/looptuner2/ColorScheme.h create mode 100644 tools/win32/krdevui/looptuner2/DSound.cpp create mode 100644 tools/win32/krdevui/looptuner2/DSound.h create mode 100644 tools/win32/krdevui/looptuner2/EditLabelAttribUnit.cpp create mode 100644 tools/win32/krdevui/looptuner2/EditLabelAttribUnit.dfm create mode 100644 tools/win32/krdevui/looptuner2/EditLabelAttribUnit.h create mode 100644 tools/win32/krdevui/looptuner2/EditLinkAttribUnit.cpp create mode 100644 tools/win32/krdevui/looptuner2/EditLinkAttribUnit.dfm create mode 100644 tools/win32/krdevui/looptuner2/EditLinkAttribUnit.h create mode 100644 tools/win32/krdevui/looptuner2/LabelDetailUnit.cpp create mode 100644 tools/win32/krdevui/looptuner2/LabelDetailUnit.dfm create mode 100644 tools/win32/krdevui/looptuner2/LabelDetailUnit.h create mode 100644 tools/win32/krdevui/looptuner2/LinkDetailUnit.cpp create mode 100644 tools/win32/krdevui/looptuner2/LinkDetailUnit.dfm create mode 100644 tools/win32/krdevui/looptuner2/LinkDetailUnit.h create mode 100644 tools/win32/krdevui/looptuner2/LoopTunerMainUnit.cpp create mode 100644 tools/win32/krdevui/looptuner2/LoopTunerMainUnit.dfm create mode 100644 tools/win32/krdevui/looptuner2/LoopTunerMainUnit.h create mode 100644 tools/win32/krdevui/looptuner2/RIFFWaveContext.cpp create mode 100644 tools/win32/krdevui/looptuner2/RIFFWaveContext.h create mode 100644 tools/win32/krdevui/looptuner2/TSSWaveContext.cpp create mode 100644 tools/win32/krdevui/looptuner2/TSSWaveContext.h create mode 100644 tools/win32/krdevui/looptuner2/TotalView.cpp create mode 100644 tools/win32/krdevui/looptuner2/TotalView.h create mode 100644 tools/win32/krdevui/looptuner2/WaveContext.h create mode 100644 tools/win32/krdevui/looptuner2/WaveLoopManager.cpp create mode 100644 tools/win32/krdevui/looptuner2/WaveLoopManager.h create mode 100644 tools/win32/krdevui/looptuner2/WaveReader.cpp create mode 100644 tools/win32/krdevui/looptuner2/WaveReader.h create mode 100644 tools/win32/krdevui/looptuner2/WaveView.cpp create mode 100644 tools/win32/krdevui/looptuner2/WaveView.h create mode 100644 tools/win32/krdevui/looptuner2/WaveWriterUnit.cpp create mode 100644 tools/win32/krdevui/looptuner2/WaveWriterUnit.dfm create mode 100644 tools/win32/krdevui/looptuner2/WaveWriterUnit.h create mode 100644 tools/win32/krdevui/looptuner2/help/Find.html create mode 100644 tools/win32/krdevui/looptuner2/help/Form.html create mode 100644 tools/win32/krdevui/looptuner2/help/Intro.html create mode 100644 tools/win32/krdevui/looptuner2/help/Menus.html create mode 100644 tools/win32/krdevui/looptuner2/help/Prepare.html create mode 100644 tools/win32/krdevui/looptuner2/help/hline.png create mode 100644 tools/win32/krdevui/looptuner2/help/index.html create mode 100644 tools/win32/krdevui/looptuner2/help/loaded.png create mode 100644 tools/win32/krdevui/looptuner2/help/loop0.png create mode 100644 tools/win32/krdevui/looptuner2/help/tune0.png create mode 100644 tools/win32/krdevui/looptuner2/help/tune1.png create mode 100644 tools/win32/krdevui/looptuner2/help/tune2.png create mode 100644 tools/win32/krdevui/looptuner2/looptune.bpr create mode 100644 tools/win32/krdevui/looptuner2/looptune.cpp create mode 100644 tools/win32/krdevui/looptuner2/looptune.drc create mode 100644 tools/win32/krdevui/looptuner2/looptune.h create mode 100644 tools/win32/krdevui/looptuner2/looptune.res create mode 100644 tools/win32/krdevui/tpc/JPEGQualityUnit.cpp create mode 100644 tools/win32/krdevui/tpc/JPEGQualityUnit.dfm create mode 100644 tools/win32/krdevui/tpc/JPEGQualityUnit.h create mode 100644 tools/win32/krdevui/tpc/LogViewerUnit.cpp create mode 100644 tools/win32/krdevui/tpc/LogViewerUnit.dfm create mode 100644 tools/win32/krdevui/tpc/LogViewerUnit.h create mode 100644 tools/win32/krdevui/tpc/ProgressUnit.cpp create mode 100644 tools/win32/krdevui/tpc/ProgressUnit.dfm create mode 100644 tools/win32/krdevui/tpc/ProgressUnit.h create mode 100644 tools/win32/krdevui/tpc/TLGMetaInfo.cpp create mode 100644 tools/win32/krdevui/tpc/TLGMetaInfo.h create mode 100644 tools/win32/krdevui/tpc/TPCMainUnit.cpp create mode 100644 tools/win32/krdevui/tpc/TPCMainUnit.dfm create mode 100644 tools/win32/krdevui/tpc/TPCMainUnit.h create mode 100644 tools/win32/krdevui/tpc/TPCStub.cpp create mode 100644 tools/win32/krdevui/tpc/TPCStub.h create mode 100644 tools/win32/krdevui/tpc/krkrtpc.res create mode 100644 tools/win32/krdevui/tpc/png/DeePNGUnit.cpp create mode 100644 tools/win32/krdevui/tpc/png/DeePNGUnit.h create mode 100644 tools/win32/krdevui/tpc/psd/DeePSDUnit.cpp create mode 100644 tools/win32/krdevui/tpc/psd/DeePSDUnit.h create mode 100644 tools/win32/krdevui/tpc/tlg5/TLG5Saver.cpp create mode 100644 tools/win32/krdevui/tpc/tlg5/TLG5Saver.h create mode 100644 tools/win32/krdevui/tpc/tlg5/slide.cpp create mode 100644 tools/win32/krdevui/tpc/tlg5/slide.h create mode 100644 tools/win32/krdevui/tpc/tlg6/GolombTable.cpp create mode 100644 tools/win32/krdevui/tpc/tlg6/GolombTable.h create mode 100644 tools/win32/krdevui/tpc/tlg6/TLG6BS.cpp create mode 100644 tools/win32/krdevui/tpc/tlg6/TLG6BS.h create mode 100644 tools/win32/krdevui/tpc/tlg6/TLG6Saver.cpp create mode 100644 tools/win32/krdevui/tpc/tlg6/TLG6Saver.h create mode 100644 tools/win32/sigchecker/MainUnit.cpp create mode 100644 tools/win32/sigchecker/MainUnit.dfm create mode 100644 tools/win32/sigchecker/MainUnit.h create mode 100644 tools/win32/sigchecker/krkrsiglib/KrkrExecutableUnit.cpp create mode 100644 tools/win32/sigchecker/krkrsiglib/KrkrExecutableUnit.h create mode 100644 tools/win32/sigchecker/krkrsiglib/KrkrSignatureUnit.cpp create mode 100644 tools/win32/sigchecker/krkrsiglib/KrkrSignatureUnit.h create mode 100644 tools/win32/sigchecker/loupe.ico create mode 100644 tools/win32/sigchecker/loupe.svg create mode 100644 tools/win32/sigchecker/sigchk.bpr create mode 100644 tools/win32/sigchecker/sigchk.cpp create mode 100644 tools/win32/sigchecker/sigchk.ini create mode 100644 tools/win32/sigchecker/sigchk.res diff --git a/core/base/CharacterSet.cpp b/core/base/CharacterSet.cpp new file mode 100644 index 0000000..b7237ea --- /dev/null +++ b/core/base/CharacterSet.cpp @@ -0,0 +1,209 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +// Character code conversion +//--------------------------------------------------------------------------- +#include "tjsCommHead.h" + +#include "CharacterSet.h" + +//--------------------------------------------------------------------------- +static tjs_int inline TVPWideCharToUtf8(tjs_char in, char * out) +{ + // convert a wide character 'in' to utf-8 character 'out' + if (in < (1<< 7)) + { + if(out) + { + out[0] = (char)in; + } + return 1; + } + else if(in < (1<<11)) + { + if(out) + { + out[0] = (char)(0xc0 | (in >> 6)); + out[1] = (char)(0x80 | (in & 0x3f)); + } + return 2; + } + else if(in < (1<<16)) + { + if(out) + { + out[0] = (char)(0xe0 | (in >> 12)); + out[1] = (char)(0x80 | ((in >> 6) & 0x3f)); + out[2] = (char)(0x80 | (in & 0x3f)); + } + return 3; + } + else if(in < (1<<21)) + { + if(out) + { + out[0] = (char)(0xf0 | (in >> 18)); + out[1] = (char)(0x80 | ((in >> 12) & 0x3f)); + out[2] = (char)(0x80 | ((in >> 6 ) & 0x3f)); + out[3] = (char)(0x80 | (in & 0x3f)); + } + return 4; + } + else if(in < (1<<26)) + { + if(out) + { + out[0] = (char)(0xf8 | (in >> 24)); + out[1] = (char)(0x80 | ((in >> 16) & 0x3f)); + out[2] = (char)(0x80 | ((in >> 12) & 0x3f)); + out[3] = (char)(0x80 | ((in >> 6 ) & 0x3f)); + out[4] = (char)(0x80 | (in & 0x3f)); + } + return 5; + } + else if(in < (1<<31)) + { + if(out) + { + out[0] = (char)(0xfc | (in >> 30)); + out[1] = (char)(0x80 | ((in >> 24) & 0x3f)); + out[2] = (char)(0x80 | ((in >> 18) & 0x3f)); + out[3] = (char)(0x80 | ((in >> 12) & 0x3f)); + out[4] = (char)(0x80 | ((in >> 6 ) & 0x3f)); + out[5] = (char)(0x80 | (in & 0x3f)); + } + return 6; + } + + return -1; +} +//--------------------------------------------------------------------------- +tjs_int TVPWideCharToUtf8String(const tjs_char *in, char * out) +{ + // convert input wide string to output utf-8 string + int count = 0; + while(*in) + { + tjs_int n; + if(out) + { + n = TVPWideCharToUtf8(*in, out); + out += n; + } + else + { + n = TVPWideCharToUtf8(*in, NULL); + /* + in this situation, the compiler's inliner + will collapse all null check parts in + TVPWideCharToUtf8. + */ + } + if(n == -1) return -1; // invalid character found + count += n; + in++; + } + return count; +} +//--------------------------------------------------------------------------- +static bool inline TVPUtf8ToWideChar(const char * & in, tjs_char *out) +{ + // convert a utf-8 charater from 'in' to wide charater 'out' + const unsigned char * & p = (const unsigned char * &)in; + if(p[0] < 0x80) + { + if(out) *out = (tjs_char)in[0]; + in++; + return true; + } + else if(p[0] < 0xc2) + { + // invalid character + return false; + } + else if(p[0] < 0xe0) + { + // two bytes (11bits) + if((p[1] & 0xc0) != 0x80) return false; + if(out) *out = ((p[0] & 0x1f) << 6) + (p[1] & 0x3f); + in += 2; + return true; + } + else if(p[0] < 0xf0) + { + // three bytes (16bits) + if((p[1] & 0xc0) != 0x80) return false; + if((p[2] & 0xc0) != 0x80) return false; + if(out) *out = ((p[0] & 0x1f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f); + in += 3; + return true; + } + else if(p[0] < 0xf8) + { + // four bytes (21bits) + if((p[1] & 0xc0) != 0x80) return false; + if((p[2] & 0xc0) != 0x80) return false; + if((p[3] & 0xc0) != 0x80) return false; + if(out) *out = ((p[0] & 0x07) << 18) + ((p[1] & 0x3f) << 12) + + ((p[2] & 0x3f) << 6) + (p[3] & 0x3f); + in += 4; + return true; + } + else if(p[0] < 0xfc) + { + // five bytes (26bits) + if((p[1] & 0xc0) != 0x80) return false; + if((p[2] & 0xc0) != 0x80) return false; + if((p[3] & 0xc0) != 0x80) return false; + if((p[4] & 0xc0) != 0x80) return false; + if(out) *out = ((p[0] & 0x03) << 24) + ((p[1] & 0x3f) << 18) + + ((p[2] & 0x3f) << 12) + ((p[3] & 0x3f) << 6) + (p[4] & 0x3f); + in += 5; + return true; + } + else if(p[0] < 0xfe) + { + // six bytes (31bits) + if((p[1] & 0xc0) != 0x80) return false; + if((p[2] & 0xc0) != 0x80) return false; + if((p[3] & 0xc0) != 0x80) return false; + if((p[4] & 0xc0) != 0x80) return false; + if((p[5] & 0xc0) != 0x80) return false; + if(out) *out = ((p[0] & 0x01) << 30) + ((p[1] & 0x3f) << 24) + + ((p[2] & 0x3f) << 18) + ((p[3] & 0x3f) << 12) + + ((p[4] & 0x3f) << 6) + (p[5] & 0x3f); + in += 6; + return true; + } + return false; +} +//--------------------------------------------------------------------------- +tjs_int TVPUtf8ToWideCharString(const char * in, tjs_char *out) +{ + // convert input utf-8 string to output wide string + int count = 0; + while(*in) + { + tjs_char c; + if(out) + { + if(!TVPUtf8ToWideChar(in, &c)) + return -1; // invalid character found + *out++ = c; + } + else + { + if(!TVPUtf8ToWideChar(in, NULL)) + return -1; // invalid character found + } + count ++; + } + return count; +} +//--------------------------------------------------------------------------- + diff --git a/core/base/CharacterSet.h b/core/base/CharacterSet.h new file mode 100644 index 0000000..d74ca5e --- /dev/null +++ b/core/base/CharacterSet.h @@ -0,0 +1,25 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +// Character code conversion +//--------------------------------------------------------------------------- + +#ifndef __CharacterSet_H__ +#define __CharacterSet_H__ + +// various character conding conversion. +// currently only utf-8 related functions are implemented. +#include "tjsTypes.h" + + +TJS_EXP_FUNC_DEF(tjs_int, TVPWideCharToUtf8String, (const tjs_char *in, char * out)); +TJS_EXP_FUNC_DEF(tjs_int, TVPUtf8ToWideCharString, (const char * in, tjs_char *out)); + + + +#endif diff --git a/core/sound/win32/tvpsnd.c b/core/sound/win32/tvpsnd.c new file mode 100644 index 0000000..e6efa76 --- /dev/null +++ b/core/sound/win32/tvpsnd.c @@ -0,0 +1,56 @@ +/* this file contains the actual definitions of */ +/* the IIDs and CLSIDs */ + +/* link this file in with the server and any clients */ + + +/* File created by MIDL compiler version 5.01.0164 */ +/* at Tue Oct 03 00:37:04 2000 + */ +/* Compiler settings for tvpsnd.idl: + Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data +*/ +//@@MIDL_FILE_HEADING( ) +#ifdef __cplusplus +extern "C"{ +#endif + + +#ifndef __IID_DEFINED__ +#define __IID_DEFINED__ + +typedef struct _IID +{ + unsigned long x; + unsigned short s1; + unsigned short s2; + unsigned char c[8]; +} IID; + +#endif // __IID_DEFINED__ + +#ifndef CLSID_DEFINED +#define CLSID_DEFINED +typedef IID CLSID; +#endif // CLSID_DEFINED + +const IID LIBID_TVPSndSysLib = {0xF09B2E87,0x740A,0x4AEA,{0x90,0xCB,0xAE,0x1C,0x4E,0xFD,0x35,0xF1}}; + + +const IID IID_ITSSMediaBaseInfo = {0xB4C4239B,0x7D27,0x43CC,{0x85,0x23,0x66,0x95,0x5B,0xDF,0x59,0xDF}}; + + +const IID IID_ITSSStorageProvider = {0x7DD61993,0x615D,0x481D,{0xB0,0x60,0xA9,0xFD,0x48,0x39,0x44,0x30}}; + + +const IID IID_ITSSModule = {0xA938D1A5,0x2980,0x498B,{0xB0,0x51,0x99,0x93,0x1D,0x41,0x89,0x5D}}; + + +const IID IID_ITSSWaveDecoder = {0x313864E2,0x910E,0x496F,{0x8A,0x6D,0x43,0x46,0x5C,0x10,0x5B,0x58}}; + + +#ifdef __cplusplus +} +#endif + diff --git a/core/sound/win32/tvpsnd.h b/core/sound/win32/tvpsnd.h new file mode 100644 index 0000000..2995200 --- /dev/null +++ b/core/sound/win32/tvpsnd.h @@ -0,0 +1,814 @@ +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + +/* File created by MIDL compiler version 5.01.0164 */ +/* at Tue Oct 03 00:37:04 2000 + */ +/* Compiler settings for tvpsnd.idl: + Os (OptLev=s), W1, Zp8, env=Win32, ms_ext, c_ext + error checks: allocation ref bounds_check enum stub_data +*/ +//@@MIDL_FILE_HEADING( ) + + +/* verify that the version is high enough to compile this file*/ +#ifndef __REQUIRED_RPCNDR_H_VERSION__ +#define __REQUIRED_RPCNDR_H_VERSION__ 440 +#endif + +#include "rpc.h" +#include "rpcndr.h" + +#ifndef __tvpsnd_h__ +#define __tvpsnd_h__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/* Forward Declarations */ + +#ifndef __ITSSMediaBaseInfo_FWD_DEFINED__ +#define __ITSSMediaBaseInfo_FWD_DEFINED__ +typedef interface ITSSMediaBaseInfo ITSSMediaBaseInfo; +#endif /* __ITSSMediaBaseInfo_FWD_DEFINED__ */ + + +#ifndef __ITSSStorageProvider_FWD_DEFINED__ +#define __ITSSStorageProvider_FWD_DEFINED__ +typedef interface ITSSStorageProvider ITSSStorageProvider; +#endif /* __ITSSStorageProvider_FWD_DEFINED__ */ + + +#ifndef __ITSSModule_FWD_DEFINED__ +#define __ITSSModule_FWD_DEFINED__ +typedef interface ITSSModule ITSSModule; +#endif /* __ITSSModule_FWD_DEFINED__ */ + + +#ifndef __ITSSWaveDecoder_FWD_DEFINED__ +#define __ITSSWaveDecoder_FWD_DEFINED__ +typedef interface ITSSWaveDecoder ITSSWaveDecoder; +#endif /* __ITSSWaveDecoder_FWD_DEFINED__ */ + + +void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void __RPC_FAR * ); + + +#ifndef __TVPSndSysLib_LIBRARY_DEFINED__ +#define __TVPSndSysLib_LIBRARY_DEFINED__ + +/* library TVPSndSysLib */ +/* [helpstring][version][uuid] */ + +typedef /* [helpstring][version][uuid] */ struct tagTSSWaveFormat + { + /* [helpstring] */ unsigned long dwSamplesPerSec; + /* [helpstring] */ unsigned long dwChannels; + /* [helpstring] */ unsigned long dwBitsPerSample; + /* [helpstring] */ unsigned long dwSeekable; + /* [helpstring] */ unsigned __int64 ui64TotalSamples; + /* [helpstring] */ unsigned long dwTotalTime; + long dwReserved1; + long dwReserved2; + } TSSWaveFormat; + + +EXTERN_C const IID LIBID_TVPSndSysLib; + +#ifndef __ITSSMediaBaseInfo_INTERFACE_DEFINED__ +#define __ITSSMediaBaseInfo_INTERFACE_DEFINED__ + +/* interface ITSSMediaBaseInfo */ +/* [object][helpstring][version][uuid] */ + + +EXTERN_C const IID IID_ITSSMediaBaseInfo; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("B4C4239B-7D27-43CC-8523-66955BDF59DF") + ITSSMediaBaseInfo : public IUnknown + { + public: + virtual /* [helpstring][id] */ HRESULT __stdcall GetMediaType( + /* [in] */ LPWSTR shortname, + /* [in] */ LPWSTR descbuf, + /* [in] */ unsigned long descbuflen) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetLength( + /* [retval][out] */ unsigned long __RPC_FAR *length) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetTitle( + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetCopyright( + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetComment( + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetArtist( + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITSSMediaBaseInfoVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + ITSSMediaBaseInfo __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + ITSSMediaBaseInfo __RPC_FAR * This); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetMediaType )( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR shortname, + /* [in] */ LPWSTR descbuf, + /* [in] */ unsigned long descbuflen); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetLength )( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [retval][out] */ unsigned long __RPC_FAR *length); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetTitle )( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetCopyright )( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetComment )( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetArtist )( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + END_INTERFACE + } ITSSMediaBaseInfoVtbl; + + interface ITSSMediaBaseInfo + { + CONST_VTBL struct ITSSMediaBaseInfoVtbl __RPC_FAR *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITSSMediaBaseInfo_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define ITSSMediaBaseInfo_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define ITSSMediaBaseInfo_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define ITSSMediaBaseInfo_GetMediaType(This,shortname,descbuf,descbuflen) \ + (This)->lpVtbl -> GetMediaType(This,shortname,descbuf,descbuflen) + +#define ITSSMediaBaseInfo_GetLength(This,length) \ + (This)->lpVtbl -> GetLength(This,length) + +#define ITSSMediaBaseInfo_GetTitle(This,buf,buflen) \ + (This)->lpVtbl -> GetTitle(This,buf,buflen) + +#define ITSSMediaBaseInfo_GetCopyright(This,buf,buflen) \ + (This)->lpVtbl -> GetCopyright(This,buf,buflen) + +#define ITSSMediaBaseInfo_GetComment(This,buf,buflen) \ + (This)->lpVtbl -> GetComment(This,buf,buflen) + +#define ITSSMediaBaseInfo_GetArtist(This,buf,buflen) \ + (This)->lpVtbl -> GetArtist(This,buf,buflen) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetMediaType_Proxy( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR shortname, + /* [in] */ LPWSTR descbuf, + /* [in] */ unsigned long descbuflen); + + +void __RPC_STUB ITSSMediaBaseInfo_GetMediaType_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetLength_Proxy( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [retval][out] */ unsigned long __RPC_FAR *length); + + +void __RPC_STUB ITSSMediaBaseInfo_GetLength_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetTitle_Proxy( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + +void __RPC_STUB ITSSMediaBaseInfo_GetTitle_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetCopyright_Proxy( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + +void __RPC_STUB ITSSMediaBaseInfo_GetCopyright_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetComment_Proxy( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + +void __RPC_STUB ITSSMediaBaseInfo_GetComment_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSMediaBaseInfo_GetArtist_Proxy( + ITSSMediaBaseInfo __RPC_FAR * This, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + +void __RPC_STUB ITSSMediaBaseInfo_GetArtist_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __ITSSMediaBaseInfo_INTERFACE_DEFINED__ */ + + +#ifndef __ITSSStorageProvider_INTERFACE_DEFINED__ +#define __ITSSStorageProvider_INTERFACE_DEFINED__ + +/* interface ITSSStorageProvider */ +/* [object][helpstring][version][uuid] */ + + +EXTERN_C const IID IID_ITSSStorageProvider; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("7DD61993-615D-481D-B060-A9FD48394430") + ITSSStorageProvider : public IUnknown + { + public: + virtual /* [helpstring][id] */ HRESULT __stdcall GetStreamForRead( + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetStreamForWrite( + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetStreamForUpdate( + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITSSStorageProviderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + ITSSStorageProvider __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + ITSSStorageProvider __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + ITSSStorageProvider __RPC_FAR * This); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetStreamForRead )( + ITSSStorageProvider __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetStreamForWrite )( + ITSSStorageProvider __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetStreamForUpdate )( + ITSSStorageProvider __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream); + + END_INTERFACE + } ITSSStorageProviderVtbl; + + interface ITSSStorageProvider + { + CONST_VTBL struct ITSSStorageProviderVtbl __RPC_FAR *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITSSStorageProvider_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define ITSSStorageProvider_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define ITSSStorageProvider_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define ITSSStorageProvider_GetStreamForRead(This,url,stream) \ + (This)->lpVtbl -> GetStreamForRead(This,url,stream) + +#define ITSSStorageProvider_GetStreamForWrite(This,url,stream) \ + (This)->lpVtbl -> GetStreamForWrite(This,url,stream) + +#define ITSSStorageProvider_GetStreamForUpdate(This,url,stream) \ + (This)->lpVtbl -> GetStreamForUpdate(This,url,stream) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [helpstring][id] */ HRESULT __stdcall ITSSStorageProvider_GetStreamForRead_Proxy( + ITSSStorageProvider __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream); + + +void __RPC_STUB ITSSStorageProvider_GetStreamForRead_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSStorageProvider_GetStreamForWrite_Proxy( + ITSSStorageProvider __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream); + + +void __RPC_STUB ITSSStorageProvider_GetStreamForWrite_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSStorageProvider_GetStreamForUpdate_Proxy( + ITSSStorageProvider __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *stream); + + +void __RPC_STUB ITSSStorageProvider_GetStreamForUpdate_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __ITSSStorageProvider_INTERFACE_DEFINED__ */ + + +#ifndef __ITSSModule_INTERFACE_DEFINED__ +#define __ITSSModule_INTERFACE_DEFINED__ + +/* interface ITSSModule */ +/* [object][helpstring][version][uuid] */ + + +EXTERN_C const IID IID_ITSSModule; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("A938D1A5-2980-498B-B051-99931D41895D") + ITSSModule : public IUnknown + { + public: + virtual /* [helpstring][id] */ HRESULT __stdcall GetModuleCopyright( + /* [in] */ LPWSTR buffer, + /* [in] */ unsigned long buflen) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetModuleDescription( + /* [in] */ LPWSTR buffer, + /* [in] */ unsigned long buflen) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetSupportExts( + /* [in] */ unsigned long index, + /* [in] */ LPWSTR mediashortname, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetMediaInfo( + /* [in] */ LPWSTR url, + /* [retval][out] */ ITSSMediaBaseInfo __RPC_FAR *__RPC_FAR *info) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetMediaSupport( + /* [in] */ LPWSTR url) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall GetMediaInstance( + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *instance) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITSSModuleVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + ITSSModule __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + ITSSModule __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + ITSSModule __RPC_FAR * This); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetModuleCopyright )( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR buffer, + /* [in] */ unsigned long buflen); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetModuleDescription )( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR buffer, + /* [in] */ unsigned long buflen); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetSupportExts )( + ITSSModule __RPC_FAR * This, + /* [in] */ unsigned long index, + /* [in] */ LPWSTR mediashortname, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetMediaInfo )( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ ITSSMediaBaseInfo __RPC_FAR *__RPC_FAR *info); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetMediaSupport )( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR url); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetMediaInstance )( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *instance); + + END_INTERFACE + } ITSSModuleVtbl; + + interface ITSSModule + { + CONST_VTBL struct ITSSModuleVtbl __RPC_FAR *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITSSModule_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define ITSSModule_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define ITSSModule_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define ITSSModule_GetModuleCopyright(This,buffer,buflen) \ + (This)->lpVtbl -> GetModuleCopyright(This,buffer,buflen) + +#define ITSSModule_GetModuleDescription(This,buffer,buflen) \ + (This)->lpVtbl -> GetModuleDescription(This,buffer,buflen) + +#define ITSSModule_GetSupportExts(This,index,mediashortname,buf,buflen) \ + (This)->lpVtbl -> GetSupportExts(This,index,mediashortname,buf,buflen) + +#define ITSSModule_GetMediaInfo(This,url,info) \ + (This)->lpVtbl -> GetMediaInfo(This,url,info) + +#define ITSSModule_GetMediaSupport(This,url) \ + (This)->lpVtbl -> GetMediaSupport(This,url) + +#define ITSSModule_GetMediaInstance(This,url,instance) \ + (This)->lpVtbl -> GetMediaInstance(This,url,instance) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetModuleCopyright_Proxy( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR buffer, + /* [in] */ unsigned long buflen); + + +void __RPC_STUB ITSSModule_GetModuleCopyright_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetModuleDescription_Proxy( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR buffer, + /* [in] */ unsigned long buflen); + + +void __RPC_STUB ITSSModule_GetModuleDescription_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetSupportExts_Proxy( + ITSSModule __RPC_FAR * This, + /* [in] */ unsigned long index, + /* [in] */ LPWSTR mediashortname, + /* [in] */ LPWSTR buf, + /* [in] */ unsigned long buflen); + + +void __RPC_STUB ITSSModule_GetSupportExts_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetMediaInfo_Proxy( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ ITSSMediaBaseInfo __RPC_FAR *__RPC_FAR *info); + + +void __RPC_STUB ITSSModule_GetMediaInfo_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetMediaSupport_Proxy( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR url); + + +void __RPC_STUB ITSSModule_GetMediaSupport_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSModule_GetMediaInstance_Proxy( + ITSSModule __RPC_FAR * This, + /* [in] */ LPWSTR url, + /* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *instance); + + +void __RPC_STUB ITSSModule_GetMediaInstance_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __ITSSModule_INTERFACE_DEFINED__ */ + + +#ifndef __ITSSWaveDecoder_INTERFACE_DEFINED__ +#define __ITSSWaveDecoder_INTERFACE_DEFINED__ + +/* interface ITSSWaveDecoder */ +/* [object][helpstring][version][uuid] */ + + +EXTERN_C const IID IID_ITSSWaveDecoder; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("313864E2-910E-496F-8A6D-43465C105B58") + ITSSWaveDecoder : public IUnknown + { + public: + virtual /* [helpstring][id] */ HRESULT __stdcall GetFormat( + /* [in] */ TSSWaveFormat __RPC_FAR *format) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall Render( + /* [in] */ void __RPC_FAR *buf, + /* [in] */ unsigned long bufsamplelen, + /* [out] */ unsigned long __RPC_FAR *rendered, + /* [retval][out] */ unsigned long __RPC_FAR *status) = 0; + + virtual /* [helpstring][id] */ HRESULT __stdcall SetPosition( + /* [in] */ unsigned __int64 samplepos) = 0; + + }; + +#else /* C style interface */ + + typedef struct ITSSWaveDecoderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + ITSSWaveDecoder __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + ITSSWaveDecoder __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + ITSSWaveDecoder __RPC_FAR * This); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *GetFormat )( + ITSSWaveDecoder __RPC_FAR * This, + /* [in] */ TSSWaveFormat __RPC_FAR *format); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *Render )( + ITSSWaveDecoder __RPC_FAR * This, + /* [in] */ void __RPC_FAR *buf, + /* [in] */ unsigned long bufsamplelen, + /* [out] */ unsigned long __RPC_FAR *rendered, + /* [retval][out] */ unsigned long __RPC_FAR *status); + + /* [helpstring][id] */ HRESULT ( __stdcall __RPC_FAR *SetPosition )( + ITSSWaveDecoder __RPC_FAR * This, + /* [in] */ unsigned __int64 samplepos); + + END_INTERFACE + } ITSSWaveDecoderVtbl; + + interface ITSSWaveDecoder + { + CONST_VTBL struct ITSSWaveDecoderVtbl __RPC_FAR *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ITSSWaveDecoder_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define ITSSWaveDecoder_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define ITSSWaveDecoder_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define ITSSWaveDecoder_GetFormat(This,format) \ + (This)->lpVtbl -> GetFormat(This,format) + +#define ITSSWaveDecoder_Render(This,buf,bufsamplelen,rendered,status) \ + (This)->lpVtbl -> Render(This,buf,bufsamplelen,rendered,status) + +#define ITSSWaveDecoder_SetPosition(This,samplepos) \ + (This)->lpVtbl -> SetPosition(This,samplepos) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [helpstring][id] */ HRESULT __stdcall ITSSWaveDecoder_GetFormat_Proxy( + ITSSWaveDecoder __RPC_FAR * This, + /* [in] */ TSSWaveFormat __RPC_FAR *format); + + +void __RPC_STUB ITSSWaveDecoder_GetFormat_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSWaveDecoder_Render_Proxy( + ITSSWaveDecoder __RPC_FAR * This, + /* [in] */ void __RPC_FAR *buf, + /* [in] */ unsigned long bufsamplelen, + /* [out] */ unsigned long __RPC_FAR *rendered, + /* [retval][out] */ unsigned long __RPC_FAR *status); + + +void __RPC_STUB ITSSWaveDecoder_Render_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring][id] */ HRESULT __stdcall ITSSWaveDecoder_SetPosition_Proxy( + ITSSWaveDecoder __RPC_FAR * This, + /* [in] */ unsigned __int64 samplepos); + + +void __RPC_STUB ITSSWaveDecoder_SetPosition_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __ITSSWaveDecoder_INTERFACE_DEFINED__ */ + +#endif /* __TVPSndSysLib_LIBRARY_DEFINED__ */ + +/* Additional Prototypes for ALL interfaces */ + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/sound/win32/tvpsnd.idl b/core/sound/win32/tvpsnd.idl new file mode 100644 index 0000000..60679cc --- /dev/null +++ b/core/sound/win32/tvpsnd.idl @@ -0,0 +1,173 @@ +[ + uuid(F09B2E87-740A-4AEA-90CB-AE1C4EFD35F1), + version(1.0), + helpstring("TVP Sound System Library") + +] +library TVPSndSysLib +{ + + importlib("stdole2.tlb"); + + [ + uuid(B4C4239B-7D27-43CC-8523-66955BDF59DF), + version(1.9), + helpstring("TVP Sound System Media Base Information Interface") + ] + interface ITSSMediaBaseInfo: IUnknown + { + [ + id(0x00000001), + helpstring("メディアの種類文字列の取得") + ] + HRESULT _stdcall GetMediaType([in] LPWSTR shortname, [in] LPWSTR descbuf, [in] unsigned long descbuflen ); + [ + id(0x00000002), + helpstring("曲長さの取得") + ] + HRESULT _stdcall GetLength([out, retval] unsigned long * length ); + [ + id(0x00000003), + helpstring("メディアタイトルの取得") + ] + HRESULT _stdcall GetTitle([in] LPWSTR buf, [in] unsigned long buflen ); + [ + id(0x00000004), + helpstring("メディア著作権情報の取得") + ] + HRESULT _stdcall GetCopyright([in] LPWSTR buf, [in] unsigned long buflen ); + [ + id(0x00000005), + helpstring("メディアコメントの取得") + ] + HRESULT _stdcall GetComment([in] LPWSTR buf, [in] unsigned long buflen ); + [ + id(0x00000006), + helpstring("メディアアーティストの取得") + ] + HRESULT _stdcall GetArtist([in] LPWSTR buf, [in] unsigned long buflen ); + }; + + [ + uuid(76CA2F83-6E9F-4687-9E2D-5C898E5DB2A7), + version(1.0), + helpstring("TVP Sound System Wave Format Record") + ] + typedef struct tagTSSWaveFormat + { + [ + helpstring("サンプリング周波数") + ] + unsigned long dwSamplesPerSec; + [ + helpstring("チャネル数") + ] + unsigned long dwChannels; + [ + helpstring("ビット数") + ] + unsigned long dwBitsPerSample; + [ + helpstring("シーク可能か") + ] + unsigned long dwSeekable; + [ + helpstring("全サンプル数") + ] + unsigned __int64 ui64TotalSamples; + [ + helpstring("全時間") + ] + unsigned long dwTotalTime; + long dwReserved1; + long dwReserved2; + } TSSWaveFormat; + + [ + uuid(7DD61993-615D-481D-B060-A9FD48394430), + version(1.6), + helpstring("TVP Sound System Storage Stream Provider") + ] + interface ITSSStorageProvider: IUnknown + { + [ + id(0x00000001), + helpstring("ストレージの読み込み用IStreamの取得") + ] + HRESULT _stdcall GetStreamForRead([in] LPWSTR url, [out, retval] IUnknown ** stream ); + [ + id(0x00000002), + helpstring("ストレージの書き込み用IStreamの取得") + ] + HRESULT _stdcall GetStreamForWrite([in] LPWSTR url, [out, retval] IUnknown ** stream ); + [ + id(0x00000003), + helpstring("ストレージの更新用IStreamの取得") + ] + HRESULT _stdcall GetStreamForUpdate([in] LPWSTR url, [out, retval] IUnknown ** stream ); + }; + + [ + uuid(A938D1A5-2980-498B-B051-99931D41895D), + version(1.9), + helpstring("TVP Sound System Module Interface") + ] + interface ITSSModule: IUnknown + { + [ + id(0x00000001), + helpstring("モジュールの著作権情報の取得") + ] + HRESULT _stdcall GetModuleCopyright([in] LPWSTR buffer, [in] unsigned long buflen ); + [ + id(0x00000002), + helpstring("モジュールの追加情報の取得") + ] + HRESULT _stdcall GetModuleDescription([in] LPWSTR buffer, [in] unsigned long buflen ); + [ + id(0x00000003), + helpstring("対応ファイル拡張子の取得") + ] + HRESULT _stdcall GetSupportExts([in] unsigned long index, [in] LPWSTR mediashortname, [in] LPWSTR buf, [in] unsigned long buflen ); + [ + id(0x00000004), + helpstring("指定メディアの情報を取得") + ] + HRESULT _stdcall GetMediaInfo([in] LPWSTR url, [out, retval] ITSSMediaBaseInfo ** info ); + [ + id(0x00000005), + helpstring("指定メディアをこのプラグインで扱えるか検査") + ] + HRESULT _stdcall GetMediaSupport([in] LPWSTR url ); + [ + id(0x00000006), + helpstring("メディア再生用オブジェクトの取得") + ] + HRESULT _stdcall GetMediaInstance([in] LPWSTR url, [out, retval] IUnknown ** instance ); + }; + + [ + uuid(313864E2-910E-496F-8A6D-43465C105B58), + version(1.6), + helpstring("TVP Sound System Wave Decoder Interface") + ] + interface ITSSWaveDecoder: IUnknown + { + [ + id(0x00000001), + helpstring("再生フォーマットの取得") + ] + HRESULT _stdcall GetFormat([in] TSSWaveFormat * format ); + [ + id(0x00000002), + helpstring("現在位置からデコード") + ] + HRESULT _stdcall Render([in] void * buf, [in] unsigned long bufsamplelen, [out] unsigned long * rendered, [out, retval] unsigned long * status ); + [ + id(0x00000003), + helpstring("指定位置へのデコード位置の移動") + ] + HRESULT _stdcall SetPosition([in] unsigned __int64 samplepos ); + }; + +}; \ No newline at end of file diff --git a/core/sound/win32/tvpsnd.txt b/core/sound/win32/tvpsnd.txt new file mode 100644 index 0000000..b352a9e --- /dev/null +++ b/core/sound/win32/tvpsnd.txt @@ -0,0 +1,399 @@ +全般的に。 + +文字列をプラグインがわから本体的に返すときは、本体側から渡された文字列バッ +ファと、そのサイズ ( ゼロ終結文字を含む ) が渡されるので ( ただし例外あり)、 +プラグイン側はその文字列バッファに書き込み、そのサイズを超えて書き込んで +はならない。文字コードはワイド文字列を用いる。 + +URL で、ファイルがローカルにある場合は file: を省略できる。また、パス区 +切りは / を使うこととする。 +もちろん、本体側はローカルファイルのみのサポートでもよい。 + +以下、「サンプル単位」とは、16bit pcm の場合 2byte、8bit pcm の場合は +1byte を占有する、量子化データの単位である。また、「マルチチャネルサンプル +単位」とは、モノラルの場合 1 サンプル単位、ステレオの場合 2 サンプル単位 +を占有する、すべてのチャネルを合わせた量子化データの単位である。 + + +---------------------------------------------------------------------- +DLL からエクスポートされるもの +これらの関数はメインスレッドからのみ呼ぶ。 + +HRESULT _stdcall GetModuleInstance(ITSSModule **out, ITSSStorageProvider *provider, + IStream * config, HWND mainwin); +機能: +  モジュールのインスタンスの取得 +プラグイン側: +  out に ITSSModule のインスタンスを作成するなどして返す。 +  provider には、本体側のファイルを開くための ITSSStorageProvider イ + ンタフェースが渡されるので、ファイルを開く必要があるときに利用する。 +  config には、このプラグイン用の設定データを記録してある IStream イ + ンタフェースが渡されるが、NULL が渡されたときは設定データは渡されなか + ったものとして処理する。 +  mainwin にはアプリケーションのメインウィンドウのハンドルが渡され + ているが、NULL の場合もある。 +本体側: +  プラグインを使用するときにこの関数を呼ぶ。out にはプラグインから + ITSSModule インタフェースが渡されるので、使用し終わったら Release + メソッドで解放する。 +  config には、そのプラグイン用の設定データファイルなどの IStream + インタフェースを渡す ( データは読み込みモードで開けばいい )。面倒な + ときや、設定データが無い場合は NULL を渡してもよい。 +  mainwin にはアプリケーションのメインウィンドウのハンドルを渡すが、 + NULL でもよい。 +戻り値: + S_OK : 正常 + それ以外 : 異常 + + +ULONG _stdcall GetModuleThreadModel(void) +機能: +  モジュールのスレッドモデルを得る +プラグイン側: +  *result にスレッドモデルを返す。 + 0 シングルスレッドモデル ( リエントラントでない ) + 1 アパートメントスレッドモデル ( リエントラントである ) +  この関数をエクスポートしていないときは、アパートメントスレッドモ + デルであると見なされる。 +本体側: +  0 が返された場合は、プラグインに対して複数のスレッドから同時にア + クセスできない ( 複数スレッドが同時にではなければアクセスすることは + できる )。 +  1 が返された場合は、プラグインに対して複数のスレッドから同時にア + クセスはできるが、一つのオブジェクトに対しては複数スレッドから同時 + にアクセスしてはならない。 +  プラグインがこの関数をエクスポートしていないときは、アパートメン + トスレッドモデルであると見なす。 +戻り値 : + 0 : シングルスレッドモデル ( リエントラントでない ) + 1 : アパートメントスレッドモデル ( リエントラントである ) + + + +HRESULT _stdcall ShowConfigWindow([in] HWND parentwin, [in] IStream * storage ); +機能: +  設定ダイアログの表示 +プラグイン側: +  設定ダイアログを表示する。parentwin には親ウィンドウとなるべきウ + ィンドウのハンドルが渡されるので、活用する。設定が終わったら、storage + に設定データを格納する。格納形式はプラグインが決める。 +  設定ダイアログを表示しない場合は、この関数をエクスポートしなくてよい。 +本体側: +  設定ダイアログを表示したいときに呼び出す。parentwin には親ウィン + ドウとなるべきウィンドウのハンドルを渡す。 +  storage には設定データを渡すための IStream インタフェースを渡す + ( ストリームに書き込める必要がある )。 +  この関数がエクスポートされていないときは、設定ダイアログを表示さ + せることはできない。 +戻り値: + S_OK : 正常 + E_NOTIMPL : 実装していない + それ以外 : 異常 + + + +ULONG _stdcall CanUnloadNow(void); +機能: +  プラグインを解放できるかどうかを返す +プラグイン側: +  この DLL をすぐに解放してもよいかを返す。一般的には、内部に参照カ + ウンタをおき、ITSSModule などのインタフェースが作成されたらその参照 + カウンタをインクリメント、削除されればデクリメントして、その参照カ + ウンタを返せばよい。 +本体側: +  プラグインを解放するまえにこの関数でチェックすべき。 +  この関数がエクスポートされていないときは、すぐに解放してかまわない。 +戻り値: + 0 : 解放可能 + それ以外 : 解放不可 + + +---------------------------------------------------------------------- +ITSSModule +プラグインにつき1個、必要になるオブジェクト。GetModuleInstance でこの +インタフェースを返す。 + +HRESULT _stdcall GetModuleCopyright([in] LPWSTR buffer, [in] unsigned long buflen ); +機能: +  モジュールの著作権情報の取得 +プラグイン側: +  プラグインの著作権情報を buffer に書き込む。buffer の長さは buflen + ( ゼロ終結文字を含む ) で与えられているので、これを越えて書き込んで + はならない。 +本体側: +  プラグインの著作権情報が必要になれば呼び出す。buffer には文字列バ + ッファ、buflen にはそのサイズ ( ゼロ終結文字を含む ) を与える。 +戻り値: + S_OK : 正常 + E_NOTIMPL : 実装していない + それ以外 : 異常 + + +HRESULT _stdcall GetModuleDescription([in] LPWSTR buffer, [in] unsigned long buflen ); +機能: +  モジュールの追加情報の取得 +プラグイン側: +  GetModuleCopyright と同じ。 +本体側: +  プラグインの追加情報が必要になれば呼び出す。そのほかは + GetModuleCopyright と同じ。 +戻り値: + S_OK : 正常 + E_NOTIMPL : 実装していない + それ以外 : 異常 + + +HRESULT _stdcall GetSupportExts([in] unsigned long index, [in] LPWSTR mediashortname, [in] LPWSTR buf, [in] unsigned long buflen ); +機能: +  対応ファイル拡張子の取得 +プラグイン側: +  index には、本体側から 0 から順に数値が渡されるので、その数値に対 + 応したファイル拡張子を返す。対応している拡張子インデックスを越えて + 呼ばれれば、S_FALSE を返す。 +  mediashortname には、その拡張子に対応するメディア名を書き込むため + のバッファへのポインタが渡される。本体側では char[33] で確保されて + いるバッファなので、ゼロ終結文字を含んで 32 文字まで書き込むことが + できる。 +  buf には、ファイル拡張子を書き込む。buflen はバッファ長。ファイル + 拡張子は . (ドット) をふくむ。もし、ファイル形式が拡張子によらない + 場合は、ドットもなしに空文字を返す ( buf[0]='\0' )。 +本体側: +  mediashortname には char[33] で確保したバッファへのポインタを渡す。 +  buf, buflen には、ファイル拡張子が返されるので、MAX_PATH +1 のバ + ッファ長を確保する。 +  index は 0 からはじめ、プラグインが S_FALSE を返すまで 1 を加えつ + つ繰り返し呼び出す。ただし、プラグイン側が S_FALSE を返したときには + 既にインデックスを越えているので、mediashortname , buf には情報は格 + 納されていない。 +  buf に空文字列が設定された場合は、そのプラグインを蹴ってもよいし、 + GetMediaSupport を呼び出してプラグインにその都度対応を確認させるこ + ともできる。 +戻り値: + S_OK : 正常 ( 情報は格納された ) + S_FALSE : インデックスを越えている ( 情報は格納されていない ) + そのほか : 異常 + + +HRESULT _stdcall GetMediaInfo([in] LPWSTR url, [out, retval] ITSSMediaBaseInfo ** info ); +機能: +  指定メディアの情報を取得 +プラグイン側: +  url にはメディアの存在する場所 ( Uniform Resource Locator で ) が + 渡される。必要であれば、GetModuleInstance で渡された provider を用 + いてファイルを開き、メディアの内容を得る。 +  info には、作成した ITSSMediaBaseInfo インタフェース、またはその + 派生インタフェースを返す。 +本体側: +  url にはメディアの存在する場所を渡す。 +  info には ITSSMediaBaseInfo インタフェースが渡されるので、これで + メディアの情報を得る。使用し終わったら Release メソッドで解放するこ + と。 +戻り値: + S_OK : 正常 + E_NOTIMPL : 実装していない ( 情報は得られない ) + それ以外 : 異常 + + +HRESULT _stdcall GetMediaSupport([in] LPWSTR url ); +機能: +  指定メディアをこのプラグインで扱えるか検査 +プラグイン側: +  渡された url を頼りに、このメディアが扱える形式であるかどうかを + 返す。 +本体側: +  メディアがプラグインで扱えるかどうかを検査したいときに、このメソ + ッドを呼び出す。 +戻り値: + S_OK : 正常 + E_NOTIMPL : 実装していない ( GetSupportExts で指定した拡張子を持つ + ファイルは例外なく読めるんじゃボケ ) + それ以外 : 異常 + + +HRESULT _stdcall GetMediaInstance([in] LPWSTR url, [out, retval] IUnknown ** instance ); +機能: +  メディア再生用オブジェクトの取得 +プラグイン側: +  渡された url を再生することのできる再生用オブジェクトを返し、 + instance に返す。 +本体側: +  url については GetMediaInfo を参照。 +  プラグインから帰ってくる instance は IUnknown * 型 なので、本体側 + で instance->QueryInterface メソッドを呼び出し、どのような種類のメ + ディア再生用オブジェクトなのかを特定する。現在 ITSSWaveDecoder が規 + 定されている。 +  instance で返されたオブジェクトを使用し終わったら、Release メソッ + ドを呼び出して解放する。 +戻り値: + S_OK : 正常 + それ以外 : 異常 + + +---------------------------------------------------------------------- +ITSSMediaBaseInfo +指定された曲に関する情報を得るためのインタフェース。 +より高度な情報もこのインタフェースから派生したクラスによって得られる。 + +HRESULT _stdcall GetMediaType([in] LPWSTR shortname, [in] LPWSTR descbuf, [in] unsigned long descbuflen ); +機能: +  メディアの種類文字列の取得 +プラグイン側: +  このメディアの種類を shortname, descbuf に返す。 +  shortname については、ITSSModule::GetSupportExts の mediashortname + を参照。 +本体側: +  メディアの種類に関する情報を得たいときにこのメソッドを呼ぶ。 +  shortname については、ITSSModule::GetSupportExts の mediashortname + を参照。 +戻り値: + S_OK : 正常 + E_NOTIMPL : 実装していない + それ以外 : 異常 + + +HRESULT _stdcall GetLength([out, retval] unsigned long * length ); +機能: +  曲長さの取得 +プラグイン側: +  このメディアの曲長を *length に ms 単位で返す。 +  曲長がわからない場合は、メソッドの戻り値として E_NOTIMPL を返すこ + と。 +本体側: +  メディアの曲長を得たいときにこのメソッドを呼ぶ。 +戻り値: + S_OK : 正常 + E_NOTIMPL : 曲長はわからない + それ以外 : 異常 + +HRESULT _stdcall GetTitle([in] LPWSTR buf, [in] unsigned long buflen ); +機能: +  メディアタイトルの取得 + + +HRESULT _stdcall GetCopyright([in] LPWSTR buf, [in] unsigned long buflen ); +機能: +  メディア著作権情報の取得 + + +HRESULT _stdcall GetComment([in] LPWSTR buf, [in] unsigned long buflen ); +機能: +  メディアコメントの取得 + + +HRESULT _stdcall GetArtist([in] LPWSTR buf, [in] unsigned long buflen ); +機能: +  メディアアーティストの取得 + + +---------------------------------------------------------------------- +ITSSWaveDecoder +Wave 形式のファイルをデコードするためのインタフェース。 + + +HRESULT _stdcall GetFormat([in] TSSWaveFormat * format ); +機能: +  再生フォーマットの取得 +プラグイン側: +  format に、このメディアの再生フォーマットを設定する。 + typedef struct tagTSSWaveFormat + { + unsigned long dwSamplesPerSec; + unsigned long dwChannels; + unsigned long dwBitsPerSample; + unsigned long dwSeekable; + unsigned __int64 ui64TotalSamples; // マルチチャネルサンプル単位 + unsigned long dwTotalTime; + unsigned long dwReserved0; + unsigned long dwReserved1; + } TSSWaveFormat; +  TSSWaveFormat の dwSeekable フィールドは、サンプル数単位精度でシ + ーク可能な場合は 2、ms 単位精度でシーク可能な場合は 1、シークがで + きない、あるいはシークできても精度が悪いという場合は 0 を入れる。 +本体側: +  format には TSSWaveFormat へのポインタを渡す。 +  プラグイン側からフォーマットが返されるので、再生の準備をする。 +戻り値: + S_OK : 正常 + それ以外 : 異常 + + +HRESULT _stdcall Render([in] void * buf, [in] unsigned long bufsamplelen, [out] unsigned long * rendered, [out, retval] unsigned long * continue ); +機能: +  現在位置からデコード +プラグイン側: +  現在のデコード位置からデコードをする。 +  デコードの格納先は buf 、格納すべきサンプル数は bufsamplelen でマ + ルチチャネルサンプル単位で示されている。bufsamplelen はバッファのバ + イト数ではなく、マルチチャネルサンプル数である。*rendered には実際に + デコードしたサンプル数をマルチチャネルサンプル単位で返す。 +  buf が NULL の場合は出力 PCM を格納する必要はない ( スキップ動作 )。 +  continue には、デコードが終わったかどうかのデコーダのステータスを + 返す。まだデコードを続けられる場合は 1 を返し、デコードが終了した場 + 合は 0 を返す。 +  rendered や continue に NULL が渡された場合はこれらには情報を格納 + しない。 +本体側: +  buf には PCM のサンプルを格納するためのバッファ、bufsamplelen に + は、そのバッファに格納できる最大サンプル数を渡す。 +  プラグインにスキップの動作を行わせたい場合は buf に NULL、bufsamplelen + にスキップしたいサンプル数を指定するが、rendered には実際にスキップ + されたサンプル数が格納され、それは bufsamplelen よりも少ない場合が + ある。 +  rendered には実際に格納されたサンプル数が渡されるが、bufsamplelen + よりも小さい場合がある。また、小さいからと言ってデコードが終わった + わけではない。rendered に 0 が返されても、continue が 1 ならば次の + サンプルをデコードできる。 +  continue が 1 で返ってきたときは、続けて次のデコードをすることが + できる。0 で返ってきたときは次のデコードはできない。 +戻り値: + S_OK : 正常 + それ以外 : 異常 + +ド位 +HRESULT _stdcall SetPosition([in] unsigned __int64 samplepos ); +機能: +  指定位置へのデコード位置の移動 +プラグイン側: +  samplepos には、移動先の位置がマルチチャネルサンプル単位で渡され + る ( ms 単位ではない ) ので、その位置にデコード位置を移動する。 +  プラグインによっては、ms 単位に精度を丸めて移動してもよいが、推 + 奨しない。 +本体側: +  シークを行うときに呼び出す。 +戻り値: + S_OK : 正常 + E_NOTIMPL : 実装していない + それ以外 : 異常 + + +---------------------------------------------------------------------- +ITSSStorageProvider +本体側で実装し、GetModuleInstance を呼ぶときにこのインタフェースを渡す。 +本体側はアパートメントスレッドモデルでこれを実装する必要がある。 + +HRESULT _stdcall GetStreamForRead([in] LPWSTR url, [out, retval] IUnknown ** stream ); +機能: +  ストレージの読み込み用IStreamの取得 +プラグイン側: +  このメソッドを用いて、指定 URL のファイルを読み込みモードで開くこ + とができる。 +  *stream には作成された IStream インタフェースが返ってくるので、使 + い終わったら Release する事。 +本体側: +  プラグイン側が要求してきたファイルを読み込みモードで開き、その + IStream インタフェースを返す。 +戻り値: + S_OK : 正常 + それ以外 : 異常 + + +HRESULT _stdcall GetStreamForWrite([in] LPWSTR url, [out, retval] IUnknown ** stream ); +機能: +  ストレージの書き込み用IStreamの取得 + +HRESULT _stdcall GetStreamForUpdate([in] LPWSTR url, [out, retval] IUnknown ** stream ); +機能: +  ストレージの更新用IStreamの取得 + + 上記二つは実装する必要なし + diff --git a/tools/win32/callerexe/build.bat b/tools/win32/callerexe/build.bat new file mode 100644 index 0000000..9842296 --- /dev/null +++ b/tools/win32/callerexe/build.bat @@ -0,0 +1,51 @@ +tasm32 /zi /ml startup.asm + +brc32 -r userconf.rc +bcc32 -O2 -v -c userconf_main.c find_kirikiri.c util.c +ilink32 -v -aa -Tpe startup.OBJ userconf_main.obj find_kirikiri.obj util.obj, userconf.exe, , import32.lib, , userconf.RES +copy userconf.exe ..\..\..\..\bin\win32\enduser-tools +copy userconf.tds ..\..\..\..\bin\win32\enduser-tools + +bcc32 -O2 -v -c xp3_stub.c find_kirikiri.c util.c +ilink32 -v -aa -Tpe startup.OBJ xp3_stub.obj find_kirikiri.obj util.obj, xp3_stub.exe, , import32.lib, , + +brc32 -r krkrrel.rc +bcc32 -O2 -v -c -okrkrrel_main.obj -DPROC_NAME=UIExecReleaser callerlib.c +ilink32 -v -aa -Tpe startup.OBJ krkrrel_main.obj, krkrrel.exe, , import32.lib, , krkrrel.RES +copy krkrrel.exe ..\..\..\..\bin\win32\tools +copy krkrrel.tds ..\..\..\..\bin\win32\tools + +brc32 -r krkrconf.rc +bcc32 -O2 -v -c -okrkrconf_main.obj -DPROC_NAME=UIExecConfig callerlib.c +ilink32 -v -aa -Tpe startup.OBJ krkrconf_main.obj, krkrconf.exe, , import32.lib, , krkrconf.RES +copy krkrconf.exe ..\..\..\..\bin\win32\tools +copy krkrconf.tds ..\..\..\..\bin\win32\tools + +brc32 -r krkrfont.rc +bcc32 -O2 -v -c -okrkrfont_main.obj -DPROC_NAME=UIExecFontMaker callerlib.c +ilink32 -v -aa -Tpe startup.OBJ krkrfont_main.obj, krkrfont.exe, , import32.lib, , krkrfont.RES +copy krkrfont.exe ..\..\..\..\bin\win32\tools +copy krkrfont.tds ..\..\..\..\bin\win32\tools + +brc32 -r krkrtpc.rc +bcc32 -O2 -v -c -okrkrtpc_main.obj -DPROC_NAME=UIExecTPC callerlib.c +ilink32 -v -aa -Tpe startup.OBJ krkrtpc_main.obj, krkrtpc.exe, , import32.lib, , krkrtpc.RES +copy krkrtpc.exe ..\..\..\..\bin\win32\tools +copy krkrtpc.tds ..\..\..\..\bin\win32\tools + +brc32 -r krkrsign.rc +bcc32 -O2 -v -c -okrkrsign_main.obj -DPROC_NAME=UIExecSign callerlib.c +ilink32 -v -aa -Tpe startup.OBJ krkrsign_main.obj, krkrsign.exe, , import32.lib, , krkrsign.RES +copy krkrsign.exe ..\..\..\..\bin\win32\tools +copy krkrsign.tds ..\..\..\..\bin\win32\tools + +brc32 -r krkrlt.rc +bcc32 -O2 -v -c -okrkrlt_main.obj -DPROC_NAME=UIExecLoopTuner callerlib.c +ilink32 -v -aa -Tpe startup.OBJ krkrlt_main.obj, krkrlt.exe, , import32.lib, , krkrlt.RES +copy krkrlt.exe ..\..\..\..\bin\win32\tools +copy krkrlt.tds ..\..\..\..\bin\win32\tools + + + + +pause diff --git a/tools/win32/callerexe/callerlib.c b/tools/win32/callerexe/callerlib.c new file mode 100644 index 0000000..1d7a3ea --- /dev/null +++ b/tools/win32/callerexe/callerlib.c @@ -0,0 +1,37 @@ +#include + +#define _MAKE_STRING(X) #X +#define MAKE_STRING(X) _MAKE_STRING(X) + +void callermain() +{ + HMODULE module; + void PASCAL (*proc)(void); + + module = LoadLibrary("krdevui.dll"); + if(!module) + module = LoadLibrary("tools\\krdevui.dll"); + if(!module) + { + MessageBox(NULL, + "Could not find krdevui.dll.\r\n" + "Check that the program is properly placed.", + "Error", MB_OK|MB_ICONSTOP); + return; + } + + proc = (void PASCAL (*)(void)) + GetProcAddress(module, MAKE_STRING(PROC_NAME)); + + if(!proc) + { + MessageBox(NULL, + "Could not find " MAKE_STRING(PROC_NAME) " in krdevui.dll.\r\n" + "This may be version mismatch.\r\n" + "Check that the program is placed " + "with proper version of krdevui.dll.", + "Error", MB_OK|MB_ICONSTOP); + return; + } + proc(); +} diff --git a/tools/win32/callerexe/find_kirikiri.c b/tools/win32/callerexe/find_kirikiri.c new file mode 100644 index 0000000..316321d --- /dev/null +++ b/tools/win32/callerexe/find_kirikiri.c @@ -0,0 +1,123 @@ +#include + +#include "util.h" + +/* check the specified file is kirikiri or its derivateive */ +#define MARK_SEARCH_MIN (500*1024) +#define MARK_SEARCH_MAX (4*1024*1024) +#define MARK_ONE_READ_SIZE (4*1024) +static int check_is_tvp(const char *buf) +{ + /* kirikiri always have "XOPT_EMBED_AREA_" as + a mark of embed option, at near the end of the executable. */ + /* return non-zero if "buf" is an executable of kirikiri, + otherwise return 0 */ + + HANDLE filehandle; + DWORD result; + unsigned long fileptr = MARK_SEARCH_MIN; + char tmp[MARK_ONE_READ_SIZE + 17]; + + /* open the file */ + filehandle = CreateFile( + buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if(filehandle == INVALID_HANDLE_VALUE ) return 0; + + /* seek to the start minimum point */ + result = SetFilePointer(filehandle, fileptr, NULL, FILE_BEGIN); + if(result == 0xffffffff || result != fileptr) + { + CloseHandle(filehandle); + return 0; + } + + /* search the mark */ + while(fileptr < MARK_SEARCH_MAX) + { + DWORD read = 0; + int i; + + ReadFile(filehandle, tmp, MARK_ONE_READ_SIZE, &read, NULL); + zeromemory((void*)(tmp + read), sizeof(tmp) - read); + + for(i = 0; i < MARK_ONE_READ_SIZE; i+=16) /* aligned to 16 bytes */ + { + if(tmp[i] == 'X' && comparememory(tmp + i + 1, "OPT_EMBED_AREA_", 15)) + { + /* found */ + CloseHandle(filehandle); + return 1; + } + } + + if(read < MARK_ONE_READ_SIZE) break; + + fileptr += read; + } + + /* not found */ + CloseHandle(filehandle); + return 0; +} + + +int find_kirikiri_executable(char * buf /* at least MAX_PATH + 22 size */) +{ + /* search kirikiri executable through the executable's path */ + int pathlast, found; + char *cp; + HANDLE findhandle; + WIN32_FIND_DATA fd; + char filemask[MAX_PATH+20]; + char file[MAX_PATH+22]; + + /* retrieve file path and make file mask */ + filemask[0] = '\0'; + GetModuleFileName(GetModuleHandle(NULL), filemask, MAX_PATH); + cp = filemask; + pathlast = -1; + while(1) + { + if(*cp == 0) break; + if(*cp == ':' || *cp == '\\' || *cp == '/') + pathlast = cp - filemask; + cp = CharNext(cp); + } + pathlast ++; + me_strcpy(filemask + pathlast, "*.exe"); + + /* find the file */ + found = 0; + file[0] = '\"'; + zeromemory(&fd, sizeof(fd)); + findhandle = FindFirstFile(filemask, &fd); + + if(findhandle == INVALID_HANDLE_VALUE) return 0; + + do + { + me_strcpy(file + 1, filemask); /* file[0] is '\"' */ + me_strcpy(file + pathlast + 1, fd.cFileName); + if(check_is_tvp(file + 1)) + { + found = 1; + break; + } + } while(FindNextFile(findhandle, &fd)); + + FindClose(findhandle); + + if(found) + { + me_strcpy(buf, file); + me_strcpy(buf + me_strlen(file), "\""); + + return 1; + } + else + { + return 0; + } +} + diff --git a/tools/win32/callerexe/find_kirikiri.h b/tools/win32/callerexe/find_kirikiri.h new file mode 100644 index 0000000..72aae92 --- /dev/null +++ b/tools/win32/callerexe/find_kirikiri.h @@ -0,0 +1,6 @@ +#ifndef FINDKIRIKIRIH +#define FINDKIRIKIRIH + +extern int find_kirikiri_executable(char * buf /* at least MAX_PATH + 22 size */); + +#endif diff --git a/tools/win32/callerexe/krkrconf.ico b/tools/win32/callerexe/krkrconf.ico new file mode 100644 index 0000000000000000000000000000000000000000..2810206ccb4eb2bfe747b266cb2f90ee52769c8e GIT binary patch literal 4710 zcmc(j!D`%A6oyX{7tgBBBN%*1LpMX;z^gWbf>+Z=NVB;#U}MdqbOZ@li-18Jze2gI zfI(|7(zFXh@mh;`*+tUS1nlvQ%;|ToB##`sPU)sfztQ}i#| zK?*ViP>_-g0TiSnLjVOksSyOw_5??qWB|33bqRhlC`dwv01D#C5I{i+G6YbNk_-V9 zq#{EA1)IbX1kiRuM@(t}waIlJKN%DxAwvKK@ni^~AO#r$C`d_$018r(A%KEiv=Ic* z_5zN$hym0trYrE1K|vBS1W*u9h5!mukRgDAlw=5?AQc$`D9{N%8MM7&M%*+3)NUSE z;wOWGBxDGnAf5~X6r>dM(puh)yGHCmQ7-0@z|HLVNGAKwwh5!oU$q+z63Ni#xkdh3# zzmK0gihJbc%a?L+a3F8rzLhs`-pGd!AMn$s`2q5y{M2%Oe!a)}w6`&SowZBTx1Kfa zGmCtk%`Vzy7B|)Hpw^AA*2)2~@Wpy`?X`_6wKdM;61%XaJ17&)>b9}%a&aM@-$tUn zY3M%n6YXXgm z`D>fHRegJVeGzBJK5n@F^O`%PTWGIm-LTDiHoxfX&7F9)16Oge`)p>H+HTW!Up8>| z-C}2nLAk8W?}IP>A6{)8`B3W-mwsz(YKO8Phb?Vv72Jw9FN;ICxjk;3GT!v*%Ci^i z_ny5FxtFyZus-f#*~lm-ZlmjWEVA6P!g}REWSEKkfa5)`_d9>By#E!q)hU!Vu~zw1 zokHb6&$d$GRW6R~$niNzPRI#4J}1eZ?8)&tNiN6*IX)-JCAlQ?oU}*3ROE_Wk!_Zh ztYoG<>hM!JG?fY)9Dax2;kQ!3;dl5QetUI0{0_gvZ?95^-{E)o?bYV+JNyp6y=okO zhu`71Q*!tneutmop;xKkPw*%B6FOUIlHgD9C-|*YNbo246a4n-PVguA6a4lnP4Fl9 z6a4mSOYkT76Z|%X3H}6sf}i1_SE=Cl_&t7)-%25m-{be}Y^90E@9}&5Rw{V>9>2$L zuWpau2O9r>nq{Lt1FY#NcP~tD~m-yKPWc($5nxR*z;IHsk_$&NYT2}Zg{1tvH z^(y=o{tCa9UKRcde}&&lp$dP6zd~lENrk_{U*YFJAmgv_6QNhB;8*;L-|7@AWfi~T zw>rg2OU1AFtxmC0Pw^{$t5dA>QvCb-_MPkf4|R&-Up(?Sh;Er(KK`jJc*MqR4_K=- z+K>1^ropmxx2NlTewpicEWCJ|k!JGl=qNvWSO3!G6Bafsa!x)uT4akS^UGY@4!i@p z{iS`U#B2xA98YuPz2j}#o4w-c+2Qt=xyTpCB1^0NjUpL;``rY8@Yx@Ik)^NL_oVrI zaPgd7x;oIclrb@AHPo1Epldg`*A+VA8)@JkDL7Dd7kC@Z_m?d8rvVOKO*Os`J1iuDdTN*?cb;A za+>~nnYY=HGG5m{ImI{8tqJ2vJid6mwN5#|n7awMdcJ2|u!XJ`KZi(O3)Dqc^^V!w;t@_*M| Fe*;=ySz!PG literal 0 HcmV?d00001 diff --git a/tools/win32/callerexe/krkrconf.rc b/tools/win32/callerexe/krkrconf.rc new file mode 100644 index 0000000..58a82f2 --- /dev/null +++ b/tools/win32/callerexe/krkrconf.rc @@ -0,0 +1,34 @@ +ICON1 ICON DISCARDABLE "krkrconf.ico" + +VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041104b0" + BEGIN + VALUE "Comments", "This program needs krdevui.dll\0" + VALUE "CompanyName", " \0" + VALUE "FileDescription", "TVP(kirikiri) configuration tool\0" + VALUE "FileVersion", "1.0.0.0\0" + VALUE "InternalName", "\0" + VALUE "LegalCopyright", "Copyright (C)2001-2009, W.Dee All rights reserved\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "krkrconf.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "TVP\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x411, 1200 + END +END diff --git a/tools/win32/callerexe/krkrfont.ico b/tools/win32/callerexe/krkrfont.ico new file mode 100644 index 0000000000000000000000000000000000000000..e3839e79539c65c60f3fc6461ab6806df02ff11f GIT binary patch literal 18718 zcmeHO30Ra>+dlIS2!e>_#_FJ;sFTf@i9G-Pyf8T8fM9-K-}PVr(VO$W=RD^*&pGc|?z4;# z3SljLeFc0Ek=#s(VL}KGkJ9%#LKGvc4t$P}wi4pQPNsNUk!&kO?Lbq!t%$Z3Vt;ob zT0jR>iU@$yvC~1%|54Wf(^g6^2#gU8`iEpdimXV zlT(*0Su!>}Je=!G0hqgRyu1xmH$QXvB&0{L;W|)|5dDETVA*33jd%^<2#7h8C(jCc z`)$LT4I8e0x^Q9k)zPDKZbwI7_-)CO)3-Nn{4{^*(q->;>(-6CA$nz*+vjRyN7`qc zX-X3xn(f_|UToz{FSTh;bK7;Gc^x~_0{>35FsL)dY1Fj1djKuz6-dka2Gf+_cI2;e zAyh~)w6y`60-J!du<5=KQ()IkfXZPz-n{{l3;Yl89^eOX-7=(O$G#u9apU<+o$h+x z>eUzWH*HGK+q(6W-xe-hxYN(iuN}((>?Q-rz?oWB)!=sQQ_iP`g+O;>gv^)6bi*nq&o;~1kCFMufh#@2WG*}Kg{g^8qdmn z#6<(HK!xthFTa`j{`(nuAAg*C<*TpGUp;Z++bf$kZTfxGs8I|1_wVmvA)yLkKfR;Y z($x`T>3Rh0kBX#%>9Bte>|ZdQc8nNEHI&NVAh!^xX+ej15ZC24A)?Iee;Lo>U4Z*d zbD%<(mX_wYe}CE+$B*Y^8w|OZ&Y!=KedNfIT%Asr)wF3-4H8-!t767@dQ;BGv6MS* z0_9JNBxB4Zy8Yr5`gvLe)wZc|7wN_Um_e%KFt$logy4GTcJvzC{|UhMW9AV`ph9=> z;K9}h52mDFxNspeKR^FhgTavb)?07g88KqSvcSMVA0)IXmw5S1pSE;u^f<~JKY?ye zj-p#LVE;=~X@GZA&iiekWw|tudyNnxsMP*5tm87E2Dl8)K&5WSjvdWE{P4riQ&LiL zuV26Z>&cTRugsr6|Ei;-V_zg>J@#e_PHpejTWx@w|@EMmkR*_L4VoW);f(u zT>;i(2efElTeCR(g>bq)_TjeQ%TvX9z6$U+dlEN6h~Ch_ZRkzbl?rgajAwu#k@oM; zAb7}|KH`hX}%I?5CdmlPpzZbQ$uFH930Oy_*H6*Ec#fsPIhaYax z^y%+XP~*mQEFz3LyE(J&)j%uYX}VrsRt|L1wGSO|=|=B62h#hlLA1?1m_AT-p%0sM zp=2*DeeB(pwzuj=JD%-MJKOc3U4Ff2w|{Ti6V!+HY5UUt9{uTH$N)Mq}6#8nClTSV#-+nHzaJi}vaRpywgmXUS+u)(=ArF-?K8TDJyh&oMZMBSz|@)@AM zCyi?0NuwKi(P$?x8spN8!rhuvMC0Z(*29~|Hf=%Uyjs%u=B;RAOCQRNh@hOP2^7+z z1*N5(p)bG8B&~J~*Zo((Sb*mTZ{TT`VM0)?M)WVAK{VUBHRr{gVofO)!jG*2_I7o1 zlQ|l5%#6w7NZZzze*QU=cI^0te0;k81s$^hwx8hzJS|rfm2rJ61oNuP$B5V92LUo6eA%TPtoup@69jyheFiZgE(n zru0kT^EB4AIe&u>0Mqzm&dDt07wlE14&7vKUuyfG3#ZeqMboHJExY2du#rUugOOIQ z{F3U_ak>Bny#Z4hRF)JzL6}obrB&gn;OFRY&;a83A3CsGBbVWE-+ITYuEFxUitC+i zFI*B!n?vO>^Bd?`HE*7d&YjDrIdis=jg8$gglPa%8Qk#vG+g5B=55K)ZzT0|kvU=l zl=3&=`K(3-8K@j>Z0=o+iKO4>PNP2;!SWME0xN%Tef^ar%zv_ z@bH!3a8feDP4=_@cliXH*S3+ZUGb&Cqi9dJzTAee)-mk`h{h~n!L6Fw(N|v2-ieE$ zyUS+Ky;o<_;VHv8eHIV^)CQCe4z>3mI+RAKso4|~GKu3?0p?}kJ&nKX4!xlcme+iK z4H|MD^8o$^yrwU|KC@R!ikm-94VTyAcVB_+D`(OD*Jo2`TW?Ow^A+zUm|Sglch&db zeRrNd`|JX>Z{PPGBBleTG6dndzDf8A{r+w0)sxq&TfkqS<6nTOA3K%PIcY!(&$9MX z^x7;cPMAZ6xG1ucq~9US{ik8MG)>yI>v;XrrCi#&^*d_Pq@5A*!vOO#Jn6cCv*Nvw zb9)92puEYEq^ez;%P;}pGWY_fd58US?Ruy4u-kJWbe zN`)f-U(uuK+MH-|w6!UMhUWk-gK0k7|L*V**=CdN?7uy%7nhf9scg(bG(Mz4vGk2M zHqzO%xfB((j+9EPtq5lQwjBRA-HJ(_+sbWwMolVw%_&jQtP&aGOt&Pqu+O3j-2UPr>7)k$25tY720wdwBa zS#)B?D7FoI7GnJi9a=tO`>zWo5cdIxf zdmLpk@3Z_Iqmlc_dx-A##duZW7HsI;`XE& z{hQJ;XSi@IW(3^>FE}#&g-7gPJES{*m#+X`8(IVZZ7wF%*ZUE>x!n{c%%)}ywj=!Eus&R^`DD(Av;{yNXn-}b}C}JP> z^`-IfS(pqO1M4M&O3(Soz6!okr4u-@CZnUSjt%@mN8t-QsnACFW3;0p8?k^@6iH%H zsZSgaGjXU?;xC3zFz0ZopUu8b$tRZ&e7#M{dwJjBSQ2jXjjED&lV7MQc{lk*sBzZI zuH>GU2kg=UW%soH&Z-`I{!I?GEbmqDenn+y%lUu*{r9!L{`zYtJfgNAal8jsnGOqa z(mrf2>MMpd;>7YkeMa?LyY}jug$px&S-3F$`kQa=JUn;q-2R9|>yVw3q)_a)R!Dkl z$pVxJlc9vK)FZ`uz#m&J$AlPiM~Khy)%Z-_gq?UE_$Q9>(jhl}&z|EAE?&%RvSrKp zP4nkpDTt5%@#f~upXNqIMNL6GpJ_SQR$3qNb8L{a%%>w|4;@1}xck8OPK-Ez{A0m1 z%9F^5(K* z$f#fs>)^pdoll%d|Ml9nYZuWLu0=;jZw?9yayC;o^i6da${mY)A5)^}HtyUE^!7v@ z%WHedOs@PR$~&nDN0G?in&(%1AJL$^5WgoUC%4>cLyfOXIcg|a=v+O48DDIB<{RSroLWHxa{45%F2#t*@08c#T}DW{s!*=TnD@dZPD4- z*tkSRP0dV6IgkB^&fh{P;hmta@*eEXsZn%h{76E5>_oV`MFkcDtwjB_@nQ{mh=w;1 z-39QrAZ8xa_LW!SZ*SZ74Y@XOFZyBFh>~`XI~!5$+Z01^7*Np}g1H{kbLdQEb6RLE z-2x zH7_IK`&EIXL+#544y4hH*!2__tfnQ}0RD#afm%Ry-HbK${pg@ucly|^3vE|vXoqK4 z+UebmcKP(6J-)qYU#Ae-AJmt==-QtSg$$%qLx<5z-FncmV?Wc#u$QQwo$WPb8V)?k z`lfb(eZyOay+f#`q`VCsp99>Ek}AN(gM$ZA?$k(%88isz&zTe)Jp3kPM*)FAwP!yJ zNC~@9*5Qqs-bZ?FLlv!cY&$zUUFW{eW6kB+krY0B1nKn|ID6IngmgWC0HDHtgg8sC zNvKnkq7?tWrar{&u)YPsh)sQZ$anMj{O-)u(R@cNb?)4_TRV1~C0Ey$yuZTzi1$XT z)fViORy$7j97;W%+<6S?4LmX)HFk9P_U4?)IDf+#7S4gjcY2oV>p4kM_I~^Aq`%g! zOCd+cMo9<@2Dl9NKviAPOdntRqU$t}mHF*gHM~IZw{u znP=)v+`an{&7GT6Y;A437(r}9XQ0aWKwRwYPiBuDN9`Im$SX}>HXhZgVZHM*=GBt3 zuQ{~5e;2lM3Q$%?FE8)ahYx>85fMuZ5k8?*2gcbl?tsTi-3#k_XlY}JyjR9$VEg%; zz+-I3)Cs$OVA@Y%zl*1v5#ekbOta`zv9WV<_U-$LJU#t*JW*PdvK&~q zzmMndH?Vh5+qOm;L|*%J+~BgZpPV_G%f1zGv7Fo#s_@5r`G>2k=W2vln?kGNV~_pK zALovv$wBRkz3SJ^itgqOmeH^ zz+-&NO42;lD350x(+gM6lx;{FDc?2FA%nV4HIvGfjoFHPx&CoJaRZ_qD;Iz2u{Ox} zDxW7n^CrOQsps%`g)iZJEEi%tj#Y(MKVIWMAR+G-)H5JwJ)l+SjQ%!;LMKPV0$WGp zBB3&BgsM=Z(-dO7#Q2Uts#r`*lzP%D50l;|6SzeN$9n)_ zFQo*9@OitUh!IEZS|C>@W*&fPpF(SS1mpJ2sZsr zBfN}{e)7pDUDvExm({qj&y=PPwWnl{8A~a{hunvZ26)IxqUWM!Vqzu&ADZI_4jj^V z#fn5@Ok2M!UUNsae^w6}OXFd~mu*_!u~R75AU?_*fdO56@lJk46YDiUH^sSS`gD~~`i$mn($@!T?tCy~HieIx@dpxi11x??e5}^Xz5I&d zkA#eA4s_W)bim!KbE0V4lsS2W2S@HloG)N;j*e~7=8I4dPoBfw0nw*flcj&gO{dMn zLJDxM()RV&6My#i@5g+x4e&_+e8$GM&l}w|e<6-JtzBYRpWGtcqv_VH@w<3edU-YX zN=Vq2>*dw{MZA~sJv^J7;Bxwuc@kC3bG`h-xKS;UKme)h)^~c-C15vIl$+t?M&%OCw=0(BqN|H*ypH7hK(K`FkcJvBVa!4PfFr~!+ZnGhyBW@%=g!&`Y-=Kta5uTVKVs;gXxKt7e*vd@&p2V(;BvNxwzgnG8g(V10Ori*1 zu}j1yri#P^=^`~fLuBL>$ma!=pc0g*5wt5@P->i@^h7}!se%eJgiec1fiRUwjM0c) zE5b!;Vw^}nkSH?JQ$;~e296YTf>a5DG)NP^OHdrrC8k3U;xY;ls}%{VFp;Q<5xc@y zh}5`5k)C)!WTd8xf{Yw|AlOH+k6<6cK7xG&`v~??0UD!Ls1m}2CNV~Y?^=N}CW^%L z10ppeU1SvG2%kt2K`)XRu$)Br27IHBNGv%(V%>2PADn}AD1QRVpNR7BLitls{&bW- z1LZG3`E{tG1VZ@;&+D#I07N~%h7R@nEtXZ=LO)^RB-o0Dyk7v)GMbk70qtS@w$yAuf4}b9paA1|46P)X#(hXhMHADn{+vMuT46$Rd>^hbR zvj9h9G*OWg-0VKtXBY%V`KID{)Y8 z$>YNUfhGk|Us|^h3z!s`)h)XB16OJxl9%Q5Ad;VgrBB9e9pkkx(5-ZPpqIq>sTfzxH9#!@^TI9;XKs%G8GiAM9{y|04GHMDn2Gd%I{gU;Nqy9M7L)m1r z_!ikH?qN+tv=qm^M*uwoN4*9HuZc`hVNC?^nh5UU^^mPx46VXqX%aCR@N|PgTc^?q zkqDNu0>fJ(cuEF%N)C7m24cIOr91_LutV!oo`QkSV;d$zFs2AR#{o%aG0}Tqq6gw22at0r(n1xqwv6Fti?bZ0o&q$Bn+~847djTPF!8a#!-QzY;d2|PstPf>%X5O@lKr>MbGa==sE!BcX;Q{2E)a==qy zKeXo*NND*IcuEdHmYA2(URwpFz6bU?qz*7i3MFLNez*F+TQ`F!o z5_k%h(;)<&0#dtH0#A{^Q?kHQ)Zi%+c!~s`Lf|O`o+8B%-AF>a0#8wcr%2!_5_k%J zBdC?YQ_z+oK&fLT@Dw$8iUgh_fv32mKjNPMSxN3VMxz9tf^!%UA8}s-Pr+OYaw7i1 z^IZZ@A@CG6cnZRhKVd(E$Q>_EU@1($369Tkc$#)~SIJKzOLln8l^;YFlaMT-%FVkR z7#y61c)VsoHU|OxV0zC&0Ed?dATcK6%d9iY#Wekv1Rw?pvjT&&I0*~jQE(uX$_WAx zl@%Po+T{1Fz(85N^j%~@Ko&0zfH1~?lQ;q)E!$?6z&yI7kR_3Y8u$t<>;dIsTxM8` c(NKvI4DWhGWnxKYz;cXXL>(~-8A!+YUt)i#_y7O^ literal 0 HcmV?d00001 diff --git a/tools/win32/callerexe/krkrfont.rc b/tools/win32/callerexe/krkrfont.rc new file mode 100644 index 0000000..9ae28cb --- /dev/null +++ b/tools/win32/callerexe/krkrfont.rc @@ -0,0 +1,34 @@ +ICON1 ICON "krkrfont.ico" + +VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041104b0" + BEGIN + VALUE "Comments", "This program needs krdevui.dll\0" + VALUE "CompanyName", " \0" + VALUE "FileDescription", "TVP(kirikiri) Font Renderer\0" + VALUE "FileVersion", "1.0.0.0\0" + VALUE "InternalName", "\0" + VALUE "LegalCopyright", "Copyright (C)2001-2009, W.Dee All rights reserved\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "krkrfont.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "TVP\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x411, 1200 + END +END diff --git a/tools/win32/callerexe/krkrfont.svg b/tools/win32/callerexe/krkrfont.svg new file mode 100644 index 0000000..8d6ad10 --- /dev/null +++ b/tools/win32/callerexe/krkrfont.svg @@ -0,0 +1,520 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/win32/callerexe/krkrlt.ico b/tools/win32/callerexe/krkrlt.ico new file mode 100644 index 0000000000000000000000000000000000000000..5d206b5f2b76eae9a4f549f68e6e0ab028916dae GIT binary patch literal 16158 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 literal 0 HcmV?d00001 diff --git a/tools/win32/callerexe/krkrlt.rc b/tools/win32/callerexe/krkrlt.rc new file mode 100644 index 0000000..1789d8b --- /dev/null +++ b/tools/win32/callerexe/krkrlt.rc @@ -0,0 +1,34 @@ +ICON1 ICON DISCARDABLE "krkrlt.ico" + +VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041104b0" + BEGIN + VALUE "Comments", "This program needs krdevui.dll .\0" + VALUE "CompanyName", " \0" + VALUE "FileDescription", "TVP(kirikiri) PCM Loop Tuner\0" + VALUE "FileVersion", "1.0.0.0\0" + VALUE "InternalName", "\0" + VALUE "LegalCopyright", "Copyright (C)2002-2009, W.Dee All rights reserved\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "krkrlt.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "TVP\0" + VALUE "ProductVersion", "1, 0, 0, 0\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x411, 1200 + END +END diff --git a/tools/win32/callerexe/krkrlt.svg b/tools/win32/callerexe/krkrlt.svg new file mode 100644 index 0000000..d3baef1 --- /dev/null +++ b/tools/win32/callerexe/krkrlt.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/win32/callerexe/krkrrel.ico b/tools/win32/callerexe/krkrrel.ico new file mode 100644 index 0000000000000000000000000000000000000000..1638e76301ceb1d3fd419bcb1c6e0a2a0b1cad68 GIT binary patch literal 4710 zcmeH}J!l+96oB7G3MU;0wuEt55Lj_#H)*DF6=Oj6D^7XfW$xl^owVJf>w zLQUT_@f4}-CI*2E2W3H0C5b>L-+Qw^cc)9@I(VcvGw)~Kd^bNsofrsw!hZ{l-67oSpinkINsI)8dP z$&*s+-!?w2rs7+@$>008wQJ?y<4?D2d7J0e70G($PnBui^QPU?Y-!_nALM|YCVrszlQBoWSf3EkRlz+ z0y0Q9gtL#VBkeh_=+7?|XB-b_+8S!Q?{>~@FBqF2pJSsZ@&Wo%N+-0kmC{PqPadzV zs9uKfSp6KG$L0@B{CN|f8a+LLg7MUrZ&y3pDd`sIe5eP-Z5cOGwJpEyF;Z!Zt+T6t z0ewJw3AuKA=03;|Q!SEzZmEQ%NR=CEy0%W^-^OzM%lERlxF}0YOEMabgx{51y?RyF z*4E_u_3Lu;=1sYO|GwP4dspt|sTY^j+$z!aD?FhPJRFn7So^@(UM zY`PsbH+JR^%paIvwLkb35Ey*X%OOJNH8QA5)7n9u)~mGNH8P-67xrr@oqubBXW3j4@a`x8sp_- z`A#-BH-!sG9zJ|1Po6xH7cXAO^XJdy)vH(X`t@sh^X82l9v;fc$%&kuoyqZ^Nxpsd zjNfs^>gsPm8}gZ^c~wm^e5XR@Ipsfw9=84(D9S!%kjoKe*!#<}oQb&LZ$i2hQ{(sd zap#CWpwEAJT3^W#nPM;~!07$MD~Crpfnt!MnD*C4t=l;Fi}PuJpWhgY^YfxDc?tUb z1mNyUVg9=1SBTE1o$Q~=KNXPu6Z|t7=H$;)@SOegPv^G)mZA60(9-m(Q4}alx3X(I``!H)TNzq59`^|jT{co_*PRno{@w64L8tMh3~L} z)?}jpF5h!=W9EO)H6LAt{6neuM#06MW(_sn_unbJlXyiT@4r*tf2Z&*@&EizsfVNP zj~lFB?aK)LkLAH~Q&v$o>b=oksfJ>CRs9$7FtuST%#qkFv3`!42Jw-z!(`!Y04QmU~(4Z*5?Q!vpTbaU)gR Vautpdu0Zp3_SV0EeSlmO`5Wo-CWQb1 literal 0 HcmV?d00001 diff --git a/tools/win32/callerexe/krkrrel.rc b/tools/win32/callerexe/krkrrel.rc new file mode 100644 index 0000000..af70c41 --- /dev/null +++ b/tools/win32/callerexe/krkrrel.rc @@ -0,0 +1,34 @@ +ICON1 ICON "krkrrel.ico" + +VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,0 + PRODUCTVERSION 1,0,0,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041104b0" + BEGIN + VALUE "Comments", "This program needs krdevui.dll\0" + VALUE "CompanyName", " \0" + VALUE "FileDescription", "TVP(kirikiri) Releaser\0" + VALUE "FileVersion", "1.0.0.0\0" + VALUE "InternalName", "\0" + VALUE "LegalCopyright", "Copyright (C) 2002-2009, W.Dee All rights reserved\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "krkrrel.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "TVP\0" + VALUE "ProductVersion", "1, 0, 0, 1\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x411, 1200 + END +END diff --git a/tools/win32/callerexe/krkrsign.ico b/tools/win32/callerexe/krkrsign.ico new file mode 100644 index 0000000000000000000000000000000000000000..b9837dcc8ca54a5a14de0a2fda106a9e6c0a7e99 GIT binary patch literal 19790 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 + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/win32/callerexe/krkrtpc.ico b/tools/win32/callerexe/krkrtpc.ico new file mode 100644 index 0000000000000000000000000000000000000000..566a4c3cf55418996ada7d0a97c23e8567df5996 GIT binary patch literal 3638 zcmeH~KZs*h6vn@C5f}eXxtM`WAtGq8Sfvn>Mi4|CBrs*B5*tY>3!4NBXY&U$vS9nB zST$X?a>}F#h!$qRMnrj;eTFHrL#A9^o#XG^J8zkt!P#az_mJw~M(7qq=b8(l`}wDW@{>0 zNmZ+=VGZ@Hr-2PLv596jd&KOLt*yyQC0Vs9YcyoNo@_9XO(wD#8a;893i7v*kN(|V z4;=Y3WtY~9ngQd8|yV77eHnp>}!;;+9?c2A*`?$Zq&(fUf`1qLRdBWuP zz(3$`a3A~y{?ze((=EoeS}p3#&yNKcZ(Jz?Zw!{Xk(8ud$ zk@Yd5-U$tvcguW|PPdym)9F|z)UDIWn3?uary7`?@4CS(qBzTW>I-H^bd-H6KGvOy z_JGeDF2A3!g?Z*Yi=p0~K-r3i0(_rc2NmG^@#WTHJ=23{5^h{6KG|oV?6Xhy zS>A*H!9L5&A8j5iuU)v$!vM@JOT@MbyR4tz$3vpj+Mu=!k_z_+u=v*&YGWLcQqd%$}V+TARS z=d{SOHitp%Fu%)*(LLz$3&)OS-N14<1phegc6)9J@cFZFaQLM?FU;Mk^M1J4IsTwK z4^G=Yo2&AZ#{CC(@#0SJ+(8rO#~6IZNfgObr#EhN+Cg>Xy(^5H7dheF+V~B;H~E=} zg`)FOa?Z!_eTb*x0-tr;Z6EN!X^cPj4}EYDIs~tbkMRdrA-?lG`h(Kb`LkZToo668 zT`XLvTYSDuoW~!Wp64G5AE%LLtXp(+_L}pHaCo0(Vwo=hw{Ys8AAiPWC|=;B(^JlG r(Pw@=b^71@8RoGR&93<8{z?v<`WMCHME-T+f69t{jPlf)Acp)e#<RwtyX){Lk^{&hk{6vy)2E}tQWP#W*7CaQng^kwvt59o5!Gg zP>>+9LX}eR;>Ay}`yuoTh`O-fVfRgqi*uOwpZA;p%$qld{m?zX>iT=TxvJNA3i?oZ z0j`(xQ_q13VBFbr*ITCLd9}v+PR%vVuQk`Jx0+@?Hys8k6n=}%?++;jGH2&Q3D^?y z>MS%6TXXDXNBLAL+TnQ|HwGk`x;;>|97_??F9850Mz^5~<@3Dde7KOHehW3I#kr-@ zm-6w2g7{x)_4^p~wTGL~g0tJO@ zIt_=QWiqqQO4+WcMO%nXzIGxDt&b2U5ocOiS?EEIcLIJyLZ`>bx@axDT3K`j)nW8g zsy&Dp@b1!VdlE9hU4VjtXjWJgrv{)2*c(z3cxcZui8d2tIfs~V{vSr9-lAB_Y@{g9 zZ9?Z##h>g5QNEoNfIkx0ehs6SIy#gl>S$?_?$1)(AyJg5njg)|!0=HVKa<4HAO8Sm C4sHPe literal 0 HcmV?d00001 diff --git a/tools/win32/callerexe/startup.asm b/tools/win32/callerexe/startup.asm new file mode 100644 index 0000000..2a8a4b2 --- /dev/null +++ b/tools/win32/callerexe/startup.asm @@ -0,0 +1,21 @@ +.386p +model flat + +ASSUME CS: FLAT, DS: FLAT, SS: FLAT, ES: FLAT +_TEXT SEGMENT PUBLIC DWORD USE32 PUBLIC 'CODE' + +EXTRN _callermain :near +EXTRN ExitProcess :near + +PUBLIC EntryPoint + + +EntryPoint proc near + call _callermain + push 0 + call ExitProcess +EntryPoint endp + +_TEXT ENDS + +END EntryPoint diff --git a/tools/win32/callerexe/userconf.rc b/tools/win32/callerexe/userconf.rc new file mode 100644 index 0000000..1dd04d1 --- /dev/null +++ b/tools/win32/callerexe/userconf.rc @@ -0,0 +1,34 @@ +ICON1 ICON DISCARDABLE "krkrconf.ico" + +VERSION_INFO VERSIONINFO + FILEVERSION 1,1,2,0 + PRODUCTVERSION 1,1,2,0 + FILEFLAGSMASK 0x3fL + FILEFLAGS 0x0L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "041104b0" + BEGIN + VALUE "Comments", "This program needs kirikiri executable to configure itself.\0" + VALUE "CompanyName", " \0" + VALUE "FileDescription", "TVP(kirikiri) configuration tool\0" + VALUE "FileVersion", "1.1.2.0\0" + VALUE "InternalName", "\0" + VALUE "LegalCopyright", "Copyright (C)2001-2009, W.Dee All rights reserved\0" + VALUE "LegalTrademarks", "\0" + VALUE "OriginalFilename", "krkrconf.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "TVP\0" + VALUE "ProductVersion", "1, 1, 2, 1\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x411, 1200 + END +END diff --git a/tools/win32/callerexe/userconf_main.c b/tools/win32/callerexe/userconf_main.c new file mode 100644 index 0000000..b5beace --- /dev/null +++ b/tools/win32/callerexe/userconf_main.c @@ -0,0 +1,62 @@ +#include +#include "util.h" +#include "find_kirikiri.h" + + +void process(void) +{ + /* search kirikiri executable through the executable's path */ + char file[MAX_PATH+22]; + + if(find_kirikiri_executable(file)) + { + STARTUPINFO si; + PROCESS_INFORMATION pi; + BOOL ret; + + zeromemory(&si, sizeof(si)); + + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_SHOWNORMAL; + + me_strcpy(file + me_strlen(file), " -userconf"); + /* append argument */ + + ret = /* execute the executable with "-userconf" option */ + CreateProcess( + NULL, + file, + NULL, + NULL, + FALSE, + 0, + NULL, + NULL, + &si, + &pi); + + if(ret) + { + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } + } + else + { + MessageBox(NULL, + "Could not find kirikiri executable. " + "Check that the program is properly placed.", + "Error", MB_OK|MB_ICONSTOP); + } +} + + + +/* callermain is called immediately after entry point */ +void callermain(void) +{ + process(); +} + + diff --git a/tools/win32/callerexe/util.c b/tools/win32/callerexe/util.c new file mode 100644 index 0000000..250415f --- /dev/null +++ b/tools/win32/callerexe/util.c @@ -0,0 +1,30 @@ +/* some compatibility functions + (standerd runtime library cannot be used) */ +void zeromemory(void *ptr, unsigned long count) +{ + char *p = (char*)ptr; + unsigned long i; + for(i = 0; i < count; i++) p[i] = 0; +} + +int comparememory(const void *ptr1, const void *ptr2, unsigned long count) +{ + const char *p1 = (const char*)ptr1; + const char *p2 = (const char*)ptr2; + while(count--) if(*(p1++) != *(p2++)) return 0; + return 1; +} + +long me_strlen(const char *s) +{ + const char *o = s; + while(*s) s++; + return s - o; +} + + +void me_strcpy(char *d, const char *s) +{ + while((*(d++) = *(s++)) != '\0'); +} + diff --git a/tools/win32/callerexe/util.h b/tools/win32/callerexe/util.h new file mode 100644 index 0000000..e010e91 --- /dev/null +++ b/tools/win32/callerexe/util.h @@ -0,0 +1,12 @@ +#ifndef UTILH +#define UTILH + +/* some compatibility functions + (standerd runtime library cannot be used) */ +extern void zeromemory(void *ptr, unsigned long count); +extern int comparememory(const void *ptr1, const void *ptr2, unsigned long count); +extern long me_strlen(const char *s); +extern void me_strcpy(char *d, const char *s); + + +#endif diff --git a/tools/win32/callerexe/xp3_stub.c b/tools/win32/callerexe/xp3_stub.c new file mode 100644 index 0000000..4b5db98 --- /dev/null +++ b/tools/win32/callerexe/xp3_stub.c @@ -0,0 +1,66 @@ +#include +#include "util.h" +#include "find_kirikiri.h" + + +void process(void) +{ + /* search kirikiri executable through the executable's path */ + char file[MAX_PATH*2+24]; + + if(find_kirikiri_executable(file)) + { + STARTUPINFO si; + PROCESS_INFORMATION pi; + BOOL ret; + + // append self filename to the executable path + me_strcpy(file + me_strlen(file), " \""); + GetModuleFileName(GetModuleHandle(NULL), + file + me_strlen(file), MAX_PATH); + me_strcpy(file + me_strlen(file), "\""); + + // execute the executable + zeromemory(&si, sizeof(si)); + + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_SHOWNORMAL; + + ret = /* execute the executable with "-userconf" option */ + CreateProcess( + NULL, + file, + NULL, + NULL, + FALSE, + 0, + NULL, + NULL, + &si, + &pi); + + if(ret) + { + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } + } + else + { + MessageBox(NULL, + "Could not find kirikiri executable. " + "Check that the program is properly placed.", + "Error", MB_OK|MB_ICONSTOP); + } +} + + + +/* callermain is called immediately after entry point */ +void callermain(void) +{ + process(); +} + + diff --git a/tools/win32/krdevui/ConfMain.cpp b/tools/win32/krdevui/ConfMain.cpp new file mode 100644 index 0000000..667159d --- /dev/null +++ b/tools/win32/krdevui/ConfMain.cpp @@ -0,0 +1,58 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "ConfMain.h" +#include "ConfSettingsUnit.h" + +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +extern "C" void _export PASCAL UIExecConfig() +{ + AnsiString file; + bool userconf = false; + int paramcount = ParamCount(); + for(int i = 1; i <= paramcount; i++) + { + AnsiString param = ParamStr(i); + if(param.c_str()[0] != '-') + file = param; + else if(param == "-userconf") + userconf = true; + } + + TConfSettingsForm *form = new TConfSettingsForm(Application, userconf); + + if(file != "") + { + if(form->InitializeConfig(file)) + { + form->ShowModal(); + } + } + else + { + if(form->SelectFile()) + { + form->ShowModal(); + } + } + delete form; + ExitProcess(0); +} +//--------------------------------------------------------------------------- + + +#pragma package(smart_init) diff --git a/tools/win32/krdevui/ConfMain.h b/tools/win32/krdevui/ConfMain.h new file mode 100644 index 0000000..fd9e79e --- /dev/null +++ b/tools/win32/krdevui/ConfMain.h @@ -0,0 +1,12 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef ConfMainH +#define ConfMainH +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/ConfMainFrameUnit.cpp b/tools/win32/krdevui/ConfMainFrameUnit.cpp new file mode 100644 index 0000000..297e5e8 --- /dev/null +++ b/tools/win32/krdevui/ConfMainFrameUnit.cpp @@ -0,0 +1,2013 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef TVP_ENVIRON + #include + #pragma hdrstop +#else + #include "tjsCommHead.h" +#endif + +#include +#include +#include +#include +#include "ConfMainFrameUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" + + + + + +//--------------------------------------------------------------------------- +static int HexNum(char ch) +{ + if(ch>='a' && ch<='f')return ch-'a'+10; + if(ch>='A' && ch<='F')return ch-'A'+10; + if(ch>='0' && ch<='9')return ch-'0'; + return -1; +} +//--------------------------------------------------------------------------- +static AnsiString EncodeString(AnsiString str) +{ + if(str == "") return "\"\""; + +#ifdef TVP_ENVIRON + ttstr ws(str.c_str()); + const wchar_t *p = ws.c_str(); +#else + WideString ws(str); + const wchar_t *p = ws.c_bstr(); +#endif + + AnsiString ret = "\""; + while(*p) + { + char tmp[10]; + sprintf(tmp, "\\x%X", *p); + ret += tmp; + p++; + } + return ret + "\""; +} +//--------------------------------------------------------------------------- +static AnsiString DecodeString(AnsiString str) +{ + if(str == "") return ""; + +#ifdef TVP_ENVIRON + ttstr ret; +#else + WideString ret; +#endif + + const char *p = str.c_str(); + + if(p[0] != '\"') return str; + + p++; + while(*p) + { + if(*p != '\\') break; + p++; + if(*p != 'x') break; + p++; + wchar_t ch = 0; + while(true) + { + int n = HexNum(*p); + if(n == -1) break; + ch <<= 4; + ch += n; + p++; + } + ret += ch; + } + +#ifdef TVP_ENVIRON + return ret.AsAnsiString(); +#else + return AnsiString(ret); +#endif +} +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +TLayeredOption::TLayeredOption() +{ + Parent = NULL; + Strings = new TStringList(); +} +//--------------------------------------------------------------------------- +TLayeredOption::~TLayeredOption() +{ + delete Strings; +} +//--------------------------------------------------------------------------- +void TLayeredOption::Clear() +{ + Strings->Text = ""; +} +//--------------------------------------------------------------------------- +void TLayeredOption::FromString(const AnsiString & content) +{ + Strings->Text = content; +} +//--------------------------------------------------------------------------- +void TLayeredOption::LoadFromIni(TMemIniFile * ini) +{ + Strings->Clear(); + ini->ReadSectionValues("Executable-options", Strings); +} +//--------------------------------------------------------------------------- +void TLayeredOption::LoadFromFile(const AnsiString & filename) +{ + Strings->LoadFromFile(filename); + + // leap comment lines + for(int i = Strings->Count - 1; i >= 0; i--) + { + if(Strings->Strings[i].c_str()[0] == ';') + { + Strings->Delete(i); + } + } +} +//--------------------------------------------------------------------------- +AnsiString TLayeredOption::ToString() const +{ + // for each options, exclude option which is identical to the parent value + AnsiString ret; + for(int i = 0; i < Strings->Count; i++) + { + AnsiString key = Strings->Names[i]; + AnsiString value = DecodeString(Strings->Values[Strings->Names[i]]); + if(Parent) + { + AnsiString parent_value; + if(Parent->GetOptionValue(key, parent_value)) + { + if(parent_value == value) continue; // exclude + } + } + ret += Strings->Strings[i] + "\r\n"; + } + return ret; +} +//--------------------------------------------------------------------------- +void TLayeredOption::SaveToFile(const AnsiString & filename) const +{ + AnsiString options = ToString(); + const char * warnings = +"; ============================================================================\n" +"; *DO NOT EDIT* this file unless you are understanding what you are doing.\n" +"; FYI:\n" +"; Each line consists of NAME=\"VALUE\" pair, VALUE is a series of\n" +"; \\xNN, where NN is hexadecimal representation of UNICODE codepoint.\n" +"; For example, opt=\"\\x61\\x62\\x63\\x3042\\x3044\\x3046\" means that the\n" +"; value of options \"opt\" is alphabets a, b, and c followed by Japanese\n" +"; Hiraganas A, I, and U.\n" +"; DO NOT PUT non-escaped value like opt=\"abc\". This doesn't work and should\n" +"; be like opt=\"\\x61\\x62\\x63\".\n" +"; ============================================================================\n" +""; + + TFileStream * fs = new TFileStream(filename, fmCreate|fmShareDenyWrite); + try + { + fs->Write(warnings, strlen(warnings)); + fs->Write(options.c_str(), options.Length()); + } + catch(...) + { + delete fs; + throw; + } + delete fs; +} +//--------------------------------------------------------------------------- +void TLayeredOption::SaveToIni(TMemIniFile * ini) const +{ + try { ini->EraseSection("Executable-options"); } catch(...) { } + + TStringList * list = new TStringList(); + try + { + list->Text = ToString(); + for(int i = 0; i < list->Count; i++) + { + ini->WriteString("Executable-options", list->Names[i], list->Values[list->Names[i]]); + } + } + catch(...) + { + delete list; + throw; + } + delete list; +} +//--------------------------------------------------------------------------- +bool TLayeredOption::GetOptionValue(const AnsiString & key, AnsiString & value) const +{ + // search options in this object + for(int i = 0; i < Strings->Count; i++) + { + if(key == Strings->Names[i]) + { + value = DecodeString(Strings->Values[Strings->Names[i]]); + return true; + } + } + + // search parent + if(Parent) return Parent->GetOptionValue(key, value); + return false; +} +//--------------------------------------------------------------------------- +void TLayeredOption::SetOptionValue(const AnsiString & key, const AnsiString & value) +{ + Strings->Values[key] = EncodeString(value); +} +//--------------------------------------------------------------------------- +void TLayeredOption::InternalListOptionsNames(TStringList * dest) const +{ + for(int i = 0; i < Strings->Count; i++) + { + dest->Add(Strings->Names[i]); + } + if(Parent) Parent->InternalListOptionsNames(dest); +} +//--------------------------------------------------------------------------- +void TLayeredOption::ListOptionNames(TStringList * dest) const +{ + // list all options names, including parent namespace + dest->Text = ""; + dest->Sorted = true; + dest->Duplicates = dupIgnore; // ignore duplicates, just overwrite + InternalListOptionsNames(dest); +} +//--------------------------------------------------------------------------- + + + + + + +TConfMainFrame *ConfMainFrame; + +#define KRKR_MAX_SIZE (4*1024*1024) + // maximum possible size of krkr.eXe executable + +//--------------------------------------------------------------------------- +#ifndef TVP_ENVIRON +void __fastcall ChangeIcon(AnsiString outname, AnsiString inname, + AnsiString iconname) +{ + // check input exe file + TStream *st = new TFileStream(inname, fmOpenRead|fmShareDenyWrite); + + char buf[16]; + st->Position=0; + st->ReadBuffer(buf,2); + + if(memcmp(buf,"MZ",2)) + { + delete st; + throw Exception("Invalid exe type!\nOperation was aborted."); + } + + int v,pebase; + st->Position= 0x3c; + pebase=0; + st->ReadBuffer(&pebase,2); // PE header position + st->Position=pebase; + v=0; + st->ReadBuffer(&v,2); // 'PE' + if(v!='PE') + { + delete st; + throw Exception("PE header was not found!\nOperation was aborted.\n"); + } + + // search .rsrc section pebase = 'PE' position + st->Position=pebase+6; + int objcount=0; + st->ReadBuffer(&objcount,1); // Object Count + int i; + for(i=0;iPosition=pebase+ i*40 + 0xf8; + st->ReadBuffer(buf,6); + if(!strcmp(buf,".rsrc")) break; + } + if(i==objcount) + { + delete st; + throw Exception(".rsrc section was not found!\nOperation was aborted.\n"); + } + + int rsrcofs=0; + int ofsbias; // offset bias + st->Position=pebase+ i*40 + 0xf8 +0x14; + st->ReadBuffer(&rsrcofs,4); // Phys. offset + ofsbias=0; + st->Position=pebase+ i*40 + 0xf8 +0x0c; + st->ReadBuffer(&ofsbias,4); // RVA + ofsbias-=rsrcofs; + + // search icon resource + int ne=0,ie=0; // named entry, id entry + st->Position=rsrcofs+0x0c; + st->ReadBuffer(&ne,2); // named entry + st->Position=rsrcofs+0x0e; + st->ReadBuffer(&ie,2); // id entry + for(i=0;iPosition=rsrcofs+16+ne*8+i*8; + st->ReadBuffer(&type,2); // type + if(type==3) break; // icon! + } + + if(i==ie) + { + delete st; + throw Exception("ICON resource section was not found!\nOperation was aborted.\n"); + } + + // search group icon resource + st->Position= rsrcofs+16+ne*8+i*8+4; + int icondir0ofs=0; + st->ReadBuffer(&icondir0ofs,4); + icondir0ofs=(icondir0ofs-0x80000000)+rsrcofs; + + st->Position=rsrcofs+0x0c; + st->ReadBuffer(&ne,2); // named entry + st->Position=rsrcofs+0x0e; + st->ReadBuffer(&ie,2); // id entry + for(i=0;iPosition=rsrcofs+16+ne*8+i*8; + st->ReadBuffer(&type,2); // type + if(type==14) break; // group icon! + } + + if(i==ie) + { + delete st; + throw Exception("GROUP ICON resource section was not found!\nOperation was aborted.\n"); + } + + st->Position= rsrcofs+16+ne*8+i*8+4; + int grpicondir0ofs=0; + st->ReadBuffer(&grpicondir0ofs,4); + grpicondir0ofs=(grpicondir0ofs-0x80000000)+rsrcofs; + + + // here comes icon directory; + // icon is limited by + // 1. count of icon images + // 2. total size of the icon + int maxicons; + st->Position=icondir0ofs+0x0e; + maxicons=0; + st->ReadBuffer(&maxicons,2); // id entry + int maxsize=0; + for(i=0;iPosition= icondir0ofs+16+i*8+4; + int icondir1ofs=0; + st->ReadBuffer(&icondir1ofs,4); + icondir1ofs=(icondir1ofs-0x80000000)+rsrcofs; + int psize=0; + st->Position=icondir1ofs+ 4+16; + st->ReadBuffer(&psize,4); + int size=0; + st->Position=psize+rsrcofs+4; + st->ReadBuffer(&size,4); + maxsize+=size; + } + + // analyze icon file + TFileStream *iconst; + try + { + iconst=new TFileStream(iconname,fmOpenRead); + } + catch(Exception &e) + { + delete st; + throw Exception(e); + } + + int numicons=0; + iconst->Position=4; + iconst->ReadBuffer(&numicons,2); + if(numicons>maxicons) + { + delete iconst; + delete st; + throw Exception("New icon image count exceeds original icon image count!\n" + "Operation was aborted.\n"); + } + + int iconsize=iconst->Size-6- numicons*16; + if(iconsize>maxsize) + { + delete iconst; + delete st; + throw Exception("New icon size exceeds original icon size!\n" + "Operation was aborted.\n"); + } + + // copy the program + TFileStream *outst; + if(inname != outname) + { + try + { + outst=new TFileStream(outname, fmCreate ); + } + catch(Exception &e) + { + delete st; + delete iconst; + throw Exception(e); + } + + outst->CopyFrom(st,0); + delete outst; + } + + delete st; + outst = new TFileStream(outname, fmOpenReadWrite|fmShareDenyWrite); + + // update icondir0 + outst->Position=icondir0ofs+0x0e; + outst->WriteBuffer(&numicons,2); + + // update data index + int maindatastart=0; + int icondataoffset=0; + for(i=0;iPosition= icondir0ofs+16+i*8+4; + int icondir1ofs=0; + outst->ReadBuffer(&icondir1ofs,4); + icondir1ofs=(icondir1ofs-0x80000000)+rsrcofs; + int pdataindex=0; + outst->Position=icondir1ofs+ 4+16; + outst->ReadBuffer(&pdataindex,4); + outst->Position=pdataindex+rsrcofs; + if(i==0) + { + outst->ReadBuffer(&maindatastart,4); // data offset + } + outst->Position=pdataindex+rsrcofs; + int v=maindatastart+icondataoffset; + outst->WriteBuffer(&v,4); // data offset + iconst->Position=i*16+6+0x08; + iconst->ReadBuffer(&v,4); // image size + outst->Position=pdataindex+rsrcofs+4; + outst->WriteBuffer(&v,4); // image size + icondataoffset+=v; + } + + // copy icon image data + maindatastart-=ofsbias; + for(i=0;iPosition=i*16+6+0x0c; + iconst->ReadBuffer(&ofs,4); + int size; + iconst->Position=i*16+6+0x08; + iconst->ReadBuffer(&size,4); + BYTE *data=new BYTE[size]; + iconst->Position=ofs; + iconst->ReadBuffer(data,size); + outst->Position=maindatastart; + outst->WriteBuffer(data,size); + delete [] data; + maindatastart+=size; + } + + // update group icon + outst->Position=grpicondir0ofs+16+4; // for first group icon ... + int grpicondir1ofs=0; + outst->ReadBuffer(&grpicondir1ofs,4); + grpicondir1ofs=(grpicondir1ofs-0x80000000)+rsrcofs; + int pdataindex=0; + outst->Position=grpicondir1ofs+4+16; + outst->ReadBuffer(&pdataindex,4); + outst->Position=pdataindex+rsrcofs; + int grpdatastart; + outst->ReadBuffer(&grpdatastart,4); + grpdatastart-=ofsbias; + outst->Position=pdataindex+rsrcofs+4; + v= 6+ numicons*14; + outst->WriteBuffer(&v,4); // size + outst->Position=grpdatastart+4; + v = numicons; + outst->WriteBuffer(&v,2); // count + for(i=0;iPosition=i*16+6; + iconst->ReadBuffer(buf,8); + int ofs; + iconst->Position=i*16+6+0x0c; + iconst->ReadBuffer(&ofs,4); + iconst->Position=ofs+0x0e; + int cc=0; + iconst->ReadBuffer(&cc,2); + buf[2]=(BYTE) ( (cc>=8) ? 0 : (1<Position=grpdatastart+ 6+ i*14; + outst->WriteBuffer(buf,8); + int size; + iconst->Position=i*16+6+0x08; + iconst->ReadBuffer(&size,4); + outst->Position=grpdatastart+ 6 + i*14 +8; + outst->WriteBuffer(&size,4); + outst->Position=grpdatastart+ 6 + i*14 +12; + v=i+1; + outst->WriteBuffer(&v,2); + } + + //finish + delete outst; + delete iconst; +} +#endif +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +void SplitAnsiString(AnsiString str, AnsiString splitter, std::vector & array) +{ + // split given string by given splitter letter. + array.clear(); + int splen = splitter.Length(); + int i; + while((i = str.AnsiPos(splitter)) != 0) + { + array.push_back(AnsiString(str.c_str(), i-1)); + str = str.c_str() + i + splen -1; + } + array.push_back(str); +} +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +AnsiString ReplaceAnsiStringAll(AnsiString str, AnsiString from, AnsiString to) +{ + while(true) + { + int pos = str.AnsiPos(from); + if(!pos) break; + AnsiString left = str.SubString(1, pos - 1); + AnsiString right = str.c_str() + pos + from.Length() - 1; + str = left + to + right; + } + return str; +} +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +static AnsiString GetRegistryValue(AnsiString key, AnsiString name) +{ + AnsiString s; + TRegistry *reg = new TRegistry(); + try + { + reg->RootKey = HKEY_CURRENT_USER; + reg->OpenKey(key, false); + s = reg->ReadString(name); + } + __finally + { + delete reg; + } + return s; +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// Static function for retrieving special folder path +//--------------------------------------------------------------------------- +static AnsiString AnsiGetSpecialFolderPath(int csidl) +{ + char path[MAX_PATH+1]; + if(!SHGetSpecialFolderPathA(NULL, path, csidl, false)) + return AnsiString(); + return AnsiString(path); +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// AnsiGetPersonalPath +//--------------------------------------------------------------------------- +static AnsiString AnsiGetPersonalPath() +{ + AnsiString path; + path = AnsiGetSpecialFolderPath(CSIDL_PERSONAL); + if(path.IsEmpty()) + path = AnsiGetSpecialFolderPath(CSIDL_APPDATA); + + if(path != "") + { + return path; + } + + return ""; +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// AnsiGetAppDataPath +//--------------------------------------------------------------------------- +static AnsiString AnsiGetAppDataPath() +{ + AnsiString path = AnsiGetSpecialFolderPath(CSIDL_APPDATA); + + if(path != "") + { + return path; + } + + return ""; +} +//--------------------------------------------------------------------------- + + + + + + + + + + + + + + + + + + +//--------------------------------------------------------------------------- +struct TOptionData +{ + AnsiString Category; + AnsiString Caption; + AnsiString Description; + AnsiString OptionName; + AnsiString OptionValueCaption; + AnsiString OptionValue; + AnsiString DefaultOptionValueCaption; + AnsiString DefaultOptionValue; + AnsiString OptionType; + bool Invisible; +}; +//--------------------------------------------------------------------------- + + + + + + + + + + + +//--------------------------------------------------------------------------- +__fastcall TConfMainFrame::TConfMainFrame(TComponent* Owner) + : TFrame(Owner) +{ + DescGot = false; + ExcludeOptions = NULL; + UserConfMode = false; + InitConfigData(); +} +//--------------------------------------------------------------------------- +__fastcall TConfMainFrame::~TConfMainFrame() +{ + FreeOptionsData(); + FreeConfigData(); + if(ExcludeOptions) delete ExcludeOptions; +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::SetUserConfMode() +{ + IconGroupBox->Visible = false; + ReleaseOptionGroupBox->Visible = false; + InvisibleCheckBox->Visible = false; + UserConfMode = true; + InitConfigData(); +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::RefIconButtonClick(TObject *Sender) +{ + if(OpenPictureDialog->Execute()) + { + try + { + IconImage->Picture->LoadFromFile(OpenPictureDialog->FileName); + } + catch(...) + { + OpenPictureDialog->FileName = ""; + throw; + } + ChangeIconCheck->Checked = true; + } + +} +//--------------------------------------------------------------------------- +const static char * OptionsParseError = "Options parse error"; +void __fastcall TConfMainFrame::OptionsTreeViewChange(TObject *Sender, + TTreeNode *Node) +{ + // currently only "select" and "string()" option type is supported + + if(!Node) + { + OptionValueComboBox->Items->Clear(); + OptionValueComboBox->Enabled = false; + InvisibleCheckBox->Enabled = false; + InvisibleCheckBox->Checked = false; + RestoreDefaultButton->Enabled = false; + OptionValueEdit->Visible = false; + OptionValueComboBox->Visible = true; + return; + } + + // find description + OptionDescMemo->Text = ""; + TTreeNode *node = Node; + while(true) + { + if(node->Data) + { + TOptionData * data = ((TOptionData*)node->Data); + if(data && data->Description != "") + { + AnsiString desc = data->Description; + if(((TOptionData*)Node->Data)->OptionName != "") + desc = "-" + ((TOptionData*)Node->Data)->OptionName + + "\r\n" + desc; + desc = ReplaceAnsiStringAll(desc, "[cr]", "\r\n"); + OptionDescMemo->Text = desc; + break; + } + } + node = node->Parent; + if(!node) break; + } + + // set option combo box + OptionValueComboBox->Items->Clear(); + + TOptionData *data = ((TOptionData*)Node->Data); + + if(data && data->OptionType != "") + { + int selectidx = -1; + std::vector array; + SplitAnsiString(data->OptionType, ",", array); + if(array[0] == "select") + { + + unsigned int i; + OptionValueComboBox->Items->BeginUpdate(); + for(i = 1; i < array.size(); i++) + { + AnsiString str = array[i]; + if(str.c_str()[0] == '*') str = str.c_str() + 1; + std::vector optarray; + SplitAnsiString(str, ";", optarray); + AnsiString value; + if(optarray.size() <= 1) + { + value = array[i]; + OptionValueComboBox->Items->Add(array[i]); + } + else + { + value = optarray[0]; + OptionValueComboBox->Items->Add(optarray[1] + " / " + optarray[0]); + } + if(value == data->OptionValue) selectidx = i -1; + } + OptionValueComboBox->Items->EndUpdate(); + OptionValueComboBox->ItemIndex = selectidx; + OptionValueComboBox->Enabled = true; + OptionValueEdit->Visible = false; + OptionValueComboBox->Visible = true; + } + else if(!strncmp(array[0].c_str(), "string(", 7)) + { + int limit = atoi(array[0].c_str() + 7); + OptionValueEdit->Text = data->OptionValue; + OptionValueEdit->Left = OptionValueComboBox->Left; + OptionValueEdit->Top = OptionValueComboBox->Top; + OptionValueEdit->Width = OptionValueComboBox->Width; + OptionValueEdit->Height = OptionValueComboBox->Height; + OptionValueEdit->Anchors = OptionValueComboBox->Anchors; + OptionValueEdit->MaxLength = limit; + OptionValueEdit->Visible = true; + OptionValueComboBox->Visible = false; + } + else throw Exception(OptionsParseError); + InvisibleCheckBox->Enabled = true; + InvisibleCheckBox->Checked = data->Invisible; + RestoreDefaultButton->Enabled = true; + } + else + { + OptionValueComboBox->Enabled = false; + InvisibleCheckBox->Enabled = false; + InvisibleCheckBox->Checked = false; + RestoreDefaultButton->Enabled = false; + OptionValueEdit->Visible = false; + OptionValueComboBox->Visible = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::OptionValueComboBoxChange(TObject *Sender) +{ + if(OptionsTreeView->Selected && OptionValueComboBox->ItemIndex != -1) + { + AnsiString opt = + OptionValueComboBox->Items->Strings[OptionValueComboBox->ItemIndex]; + std::vector array; + SplitAnsiString(opt, " / ", array); + if(array.size() <= 1) + SetNodeOptionValue(OptionsTreeView->Selected, opt, opt); + else + SetNodeOptionValue(OptionsTreeView->Selected, array[0], array[1]); + } +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::OptionValueEditChange(TObject *Sender) +{ + if(OptionsTreeView->Selected) + { + AnsiString opt = OptionValueEdit->Text; + SetNodeOptionValue(OptionsTreeView->Selected, opt, opt); + } +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::InvisibleCheckBoxClick(TObject *Sender) +{ + SetNodeInvisibleState(OptionsTreeView->Selected, InvisibleCheckBox->Checked); +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::RestoreDefaultButtonClick(TObject *Sender) +{ + if(OptionsTreeView->Selected) + { + SetNodeDefaultOptionValue(OptionsTreeView->Selected); + OptionsTreeViewChange(this, OptionsTreeView->Selected); + } +} +//--------------------------------------------------------------------------- +bool __fastcall TConfMainFrame::CheckOK() +{ + if(ChangeIconCheck->Checked && OpenPictureDialog->FileName == "") + { + RefIconButtonClick(this); + if(OpenPictureDialog->FileName == "") return false; + } + return true; +} +//--------------------------------------------------------------------------- +AnsiString __fastcall TConfMainFrame::GetPluginOptions(AnsiString module) +{ + static char has_option_sig[] = + " --has-option--)"; + has_option_sig[0] = '('; + + char buf[2048 + 20]; + ZeroMemory(buf, 2048 + 20); + TFileStream *fs = new TFileStream(module, fmOpenRead|fmShareDenyWrite); + try + { + fs->Read(buf, 2048); + } + catch(...) + { + delete fs; + return ""; + } + delete fs; + + int i; + for(i = 0; i < 2048; i++) + { + if(buf[i] == '(' && !memcmp(buf + i, has_option_sig, 16)) + { + // valid DLL + HMODULE mod = LoadLibrary(module.c_str()); + if(!mod) return ""; + wchar_t *(__stdcall *ptr)(); + ptr = (wchar_t *(__stdcall *)())GetProcAddress(mod, "GetOptionDesc"); + if(!ptr) + { + FreeLibrary(mod); + return ""; + } + AnsiString ret = ptr(); + FreeLibrary(mod); + return ret; + } + } + + return ""; +} +//--------------------------------------------------------------------------- +AnsiString __fastcall TConfMainFrame::SearchPluginOptions(AnsiString path, AnsiString ext) +{ + AnsiString exepath = + IncludeTrailingBackslash(ExtractFileDir(SourceExe)); + path = exepath + path; + AnsiString mask = path + "*." + ext; + + TSearchRec sr; + AnsiString ret; + if(FindFirst(mask, faAnyFile, sr) == 0) + { + do + { + try + { + ret += GetPluginOptions(path + sr.FindData.cFileName); + } + catch(...) + { + } + } while(FindNext(sr) == 0); + FindClose(sr); + } + + return ret; +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::ParseData() +{ + // cast into treeview + AnsiString optionsdata; + TFileStream *stream = NULL; + wchar_t * buf = NULL; + + try + { + stream = new TFileStream(OptionsFileName, + fmOpenRead|fmShareDenyWrite); + unsigned int size = stream->Size; + + buf = new wchar_t[size/2 + 1]; + + stream->ReadBuffer(buf, size); + buf[size/2] = 0; + } + catch(...) + { + DeleteFile(OptionsFileName); + if(stream) delete stream; + if(buf) delete [] buf; + } + + optionsdata = buf; + + optionsdata += SearchPluginOptions("\\", "dll"); + optionsdata += SearchPluginOptions("\\", "tpm"); + optionsdata += SearchPluginOptions("plugin\\", "dll"); + optionsdata += SearchPluginOptions("plugin\\", "tpm"); + + delete [] buf; + delete stream; + stream = NULL; + + try + { + stream = new TFileStream(OptionsFileName, + fmCreate|fmShareDenyWrite); + stream->WriteBuffer(optionsdata.c_str(), optionsdata.Length()); + } + catch(...) + { + DeleteFile(OptionsFileName); + if(stream) delete stream; + } + + delete stream; + + TStrings *strings = NULL; + try + { + strings = new TStringList(); + strings->LoadFromFile(OptionsFileName); + ParseOptionsData(strings); + } + catch(...) + { + if(strings) delete strings; + DeleteFile(OptionsFileName); + throw; + } + if(strings) delete strings; + DeleteFile(OptionsFileName); + + + OptionsGroupBox->Enabled = true; + OptionsGroupBox->Caption = OriginalOptionsGroupBoxLabel; +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::ParseOptionsData(TStrings *options) +{ + // parse options data stored in tree string + TTreeNode *node = NULL; +// TTreeNode *lastparent = NULL; + TOptionData * data = NULL; + OptionsTreeView->Items->BeginUpdate(); + try + { + for(int i = 0; iCount; i++) + { + // category:caption and description|option name|possible option values + AnsiString cap = options->Strings[i]; + std::vector array; + SplitAnsiString(cap, "|", array); + + AnsiString text, optionname, optiontype; + text = array[0]; + optionname = array.size() >= 2 ? array[1] : AnsiString(); + optiontype = array.size() >= 3 ? array[2] : AnsiString(); + + TOptionData * data = new TOptionData(); + data->Invisible = false; + + data->OptionName = optionname; + data->OptionType = optiontype; + + // retrieve default value + SplitAnsiString(data->OptionType, ",", array); + + unsigned int i; + for(i = 1; i < array.size(); i++) + { + if(array[i].c_str()[0] == '*') + { + // default + GetValueCaptionAndValue(array[i], + data->DefaultOptionValueCaption, + data->DefaultOptionValue); + } + } + + // set default value + DefaultConfigData.SetOptionValue(data->OptionName, data->DefaultOptionValue); + + // exclude invisible options + if(ExcludeOptions) + { + if(ExcludeOptions->Values[optionname] == "i") + { + if(UserConfMode) + { + delete data; + continue; + } + data->Invisible = true; + } + } + + // split caption and description + SplitAnsiString(text, ";", array); + AnsiString caption, category, desc; + if(array.size() >= 2) + { + caption = array[0]; + desc = array[1]; + } + else + { + caption = text; + } + + SplitAnsiString(caption, ":", array); + node = NULL; + if(array.size() >= 2) + { + // category found + caption = array[1]; + category = array[0]; + bool found = false; + for(int i = 0; i Items->Count; i++) + { + if(OptionsTreeView->Items->Item[i]->Text == category) + { + // parent found + for(int j = 0; j < OptionsTreeView->Items->Item[i]->Count; j++) + if(OptionsTreeView->Items->Item[i]->Item[j]->Data) + { + TOptionData* olddata = (TOptionData*) + OptionsTreeView->Items->Item[i]->Item[j]->Data; + if(olddata->Caption == caption) + { + node = OptionsTreeView->Items->Item[i]->Item[j]; + delete olddata; + } + } + if(!node) + node = OptionsTreeView->Items->AddChild(OptionsTreeView->Items->Item[i], ""); + found = true; + break; + } + } + if(!found) + { + // create new category + node = OptionsTreeView->Items->Add(OptionsTreeView->TopItem, category); + node = OptionsTreeView->Items->AddChild(node, ""); + } + } + else + { + category = text; + } + + if(node == NULL) + { + // add to root + node = OptionsTreeView->Items->Add(OptionsTreeView->TopItem, ""); + } + + data->Caption = caption; + data->Description = desc; + data->Category = category; + + + node->Data = data; + + // set default value + SetNodeDefaultOptionValue(node); + + data = NULL; + } + } + catch(...) + { + OptionsTreeView->Items->EndUpdate(); + if(data) delete data; + throw; + } + OptionsTreeView->FullExpand(); + OptionsTreeView->TopItem = OptionsTreeView->Items->Item[0]; + OptionsTreeView->Items->EndUpdate(); +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::FreeOptionsData() +{ + // free options data associated with tree nodes + if(!OptionsTreeView->Items->Count) return; + + TTreeNode *node; + node = OptionsTreeView->Items->Item[0]; + TOptionData * data; + do + { + data = (TOptionData*)node->Data; + delete data; + } while((node = node->GetNext())!=NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::GetValueCaptionAndValue(AnsiString str, + AnsiString &valuecaption, AnsiString &value) +{ + if(str.Length() >= 1 && str.c_str()[0] == '*') str = str.c_str() + 1; + std::vector array; + SplitAnsiString(str, ";", array); + if(array.size() <= 1) + { + valuecaption = array[0].c_str(); + value = array[0].c_str(); + } + else + { + valuecaption = array[1]; + value = array[0].c_str(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::SetOptionValue(AnsiString name, AnsiString value) +{ + if(!OptionsTreeView->Items->Count) return; + + TTreeNode *node; + node = OptionsTreeView->Items->Item[0]; + TOptionData * data; + AnsiString orgvalue = value; + do + { + data = (TOptionData*)node->Data; + + if(data && data->OptionName == name) + { + std::vector array; + SplitAnsiString(data->OptionType, ",", array); + std::vector::iterator i; + if(array.size() >= 2) + { + if(array[0] == "select") + { + for(i = array.begin() + 1; i != array.end(); i++) + { + AnsiString valcap; + AnsiString val; + GetValueCaptionAndValue(*i, valcap, val); + if(value == val) + { + SetNodeOptionValue(node, valcap, val); + return; + } + } + } + else if(!strncmp(array[0].c_str(), "string(", 7)) + { + SetNodeOptionValue(node, value, value); + return; + } + } + } + + } while((node = node->GetNext())!=NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::SetNodeOptionValue(TTreeNode *node, + AnsiString valuecaption, AnsiString value) +{ + TOptionData * data = (TOptionData*)node->Data; + if(!data) return; + if(data->OptionType == "") return; + data->OptionValue = value; + data->OptionValueCaption = valuecaption; + + AnsiString mark; + if(data->DefaultOptionValue != data->OptionValue) mark = "*"; + if(data->Invisible) mark += "!"; + if(mark != "") mark += " "; + node->Text = mark + data->Caption + " : " + data->OptionValueCaption; +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::SetNodeInvisibleState(TTreeNode *node, bool invisible) +{ + TOptionData * data = (TOptionData*)node->Data; + if(!data) return; + data->Invisible = invisible; + + AnsiString mark; + if(data->DefaultOptionValue != data->OptionValue) mark = "*"; + if(data->Invisible) mark += "!"; + if(mark != "") mark += " "; + node->Text = mark + data->Caption + " : " + data->OptionValueCaption; +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::SetNodeDefaultOptionValue(TTreeNode *node) +{ + // currently only "select" and "string()" option type is supported + + std::vector array; + TOptionData * data = (TOptionData*)node->Data; + if(data->OptionType == "") return; + SetNodeOptionValue(node, data->DefaultOptionValueCaption, data->DefaultOptionValue); +} +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::ReadOptionInfoFromExe(AnsiString exename) +{ + if(DescGot) return; + + if(!FileExists(exename)) return; + + // get temporary file name + char dir[MAX_PATH]; + dir[0] = 0; + GetTempPath(MAX_PATH, dir); + AnsiString eventname = AnsiString("krkrot") + + AnsiString((int)GetCurrentProcessId()); + OptionsFileName = dir + eventname; + DeleteFile(OptionsFileName); + + // create mutex object + HANDLE event = CreateEvent(NULL, FALSE, FALSE, eventname.c_str()); + + // execute krkr.exe to retrieve command line description + OriginalOptionsGroupBoxLabel = OptionsGroupBox->Caption; + OptionsGroupBox->Caption = ReadingOptionsLabel->Caption; + + if(WinExec(("\"" + exename + "\" -@cmddesc " + + AnsiString(reinterpret_cast(Handle)) + " \"" + + OptionsFileName + "\" \"" + eventname + "\"").c_str(), SW_HIDE) <= 31) + OptionsGroupBox->Caption = OptionsReadFailedLabel->Caption; + + if(WAIT_TIMEOUT == WaitForSingleObject(event, 10000)) + { + CloseHandle(event); + throw Exception("The program \"" + exename + "\" did not reply!"); + } + CloseHandle(event); + + ParseData(); + + DescGot = true; +} +//--------------------------------------------------------------------------- + + + + + + + + + + + + +//--------------------------------------------------------------------------- +void __fastcall TConfMainFrame::CopyExe() +{ +#ifndef TVP_ENVIRON + // copy specified exe file to destination, applying options. + if(ChangeIconCheck->Checked) + { + ChangeIcon(TargetExe, SourceExe, OpenPictureDialog->FileName); + } + else + { + TFileStream *src = NULL; + TFileStream *dest = NULL; + try + { + src = new TFileStream(SourceExe, fmOpenRead|fmShareDenyWrite); + dest = new TFileStream(TargetExe, fmCreate|fmShareDenyWrite); + dest->CopyFrom(src, 0); + + } + catch(...) + { + if(src) delete src; + if(dest) delete dest; + throw; + } + + if(src) delete src; + if(dest) delete dest; + } + + WriteOptions(TargetExe); +#endif +} +//--------------------------------------------------------------------------- + + + + + + + + +//--------------------------------------------------------------------------- +void TConfMainFrame::InitConfigData() +{ + if(UserConfMode) + { + UserConfigData.SetParent(&ConfigData); + ConfigData.SetParent(&EmbeddedConfigData); + EmbeddedConfigData.SetParent(&DefaultConfigData); + TargetConfigData = &UserConfigData; + } + else + { + ConfigData.SetParent(&EmbeddedConfigData); + EmbeddedConfigData.SetParent(&DefaultConfigData); + TargetConfigData = &ConfigData; + } + + if(!ExcludeOptions) ExcludeOptions = new TStringList(); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::FreeConfigData() +{ + delete ExcludeOptions, ExcludeOptions = NULL; +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ApplyReadDataToUI() +{ + // apply exclude options + if(OptionsTreeView->Items->Count) + { + for(int i = 0; i < ExcludeOptions->Count; i++) + { + AnsiString optionname = ExcludeOptions->Names[i]; + TTreeNode *node; + node = OptionsTreeView->Items->Item[0]; + TOptionData * data; + do + { + data = (TOptionData*)node->Data; + + if(data && data->OptionName == optionname) + { + SetNodeInvisibleState(node, true); + } + + } while((node = node->GetNext())!=NULL); + } + } + + // apply option values + TStringList * option_names = new TStringList(); + try + { + TargetConfigData->ListOptionNames(option_names); + for(int i = 0; i < option_names->Count; i++) + { + AnsiString value; + if(TargetConfigData->GetOptionValue(option_names->Strings[i], value)) + { + SetOptionValue(option_names->Strings[i], value); + } + } + } + catch(...) + { + delete option_names; + throw; + } + delete option_names; + +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ApplyUIDataToConfigData() +{ + // apply exclude options + ExcludeOptions->Clear(); + if(OptionsTreeView->Items->Count) + { + TTreeNode *node; + node = OptionsTreeView->Items->Item[0]; + TOptionData * data; + do + { + data = (TOptionData*)node->Data; + if(data && data->OptionType != "") + { + if(data->Invisible) + { + ExcludeOptions->Values[data->OptionName] = "i"; + } + } + } while((node = node->GetNext())!=NULL); + } + + // apply option values + if(OptionsTreeView->Items->Count) + { + TTreeNode *node; + node = OptionsTreeView->Items->Item[0]; + TOptionData * data; + do + { + data = (TOptionData*)node->Data; + + if(data && data->OptionType != "") + { + TargetConfigData->SetOptionValue(data->OptionName, data->OptionValue); + } + + } while((node = node->GetNext())!=NULL); + } +} +//--------------------------------------------------------------------------- +void TConfMainFrame::SetSourceAndTargetFileName(AnsiString source, AnsiString target) +{ + SourceExe = source; + TargetExe = target; +} +//--------------------------------------------------------------------------- +AnsiString TConfMainFrame::GetConfigFileName(AnsiString exename) +{ + return ChangeFileExt(exename, ".cf"); +} +//--------------------------------------------------------------------------- +AnsiString TConfMainFrame::GetDataPathDirectory(AnsiString datapath, AnsiString exename) +{ + if(datapath == "") datapath = "$(exepath)\\savedata"; + + AnsiString exepath = ExcludeTrailingBackslash(ExtractFileDir(exename)); + AnsiString personalpath = ExcludeTrailingBackslash(AnsiGetPersonalPath()); + AnsiString appdatapath = ExcludeTrailingBackslash(AnsiGetAppDataPath()); + if(personalpath == "") personalpath = exepath; + if(appdatapath == "") appdatapath = exepath; + + OSVERSIONINFO osinfo; + osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osinfo); + + bool vista_or_later = osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && + osinfo.dwMajorVersion >= 6; + + AnsiString vistapath = vista_or_later ? appdatapath : exepath; + + datapath = ReplaceAnsiStringAll(datapath, "$(exepath)", exepath); + datapath = ReplaceAnsiStringAll(datapath, "$(personalpath)", personalpath); + datapath = ReplaceAnsiStringAll(datapath, "$(appdatapath)", appdatapath); + datapath = ReplaceAnsiStringAll(datapath, "$(vistapath)", vistapath); + return IncludeTrailingBackslash(ExpandUNCFileName(datapath)); +} +//--------------------------------------------------------------------------- +AnsiString TConfMainFrame::GetUserConfigFileName(AnsiString datapath, AnsiString exename) +{ + // exepath, personalpath, appdatapath + return GetDataPathDirectory(datapath, exename) + ExtractFileName(ChangeFileExt(exename, ".cfu")); +} +//--------------------------------------------------------------------------- +unsigned int __fastcall TConfMainFrame::FindOptionAreaOffset(AnsiString target) +{ + static char xopt[] = " OPT_EMBED_AREA_"; + + xopt[0] = 'X'; + + TStream *stream = new TFileStream(target, fmOpenRead|fmShareDenyWrite); + unsigned char *buf = NULL; + + unsigned int offset; + bool found = false; + try + { + unsigned int size = stream->Size; + if(size > KRKR_MAX_SIZE) size = KRKR_MAX_SIZE; + buf = new unsigned char [size]; + stream->Read(buf, size); + + // search "XOPT_EMBED_AREA_" ( aligned by 16 ) + for(offset = 0; offset < size; offset += 16) + { + if(buf[offset] == 'X') + { + if(!memcmp(buf+offset, xopt, 16)) + { + found = true; + break; + } + } + } + } + catch(...) + { + if(buf) delete [] buf; + delete stream; + throw; + } + + delete [] buf; + delete stream; + + if(!found) + { + throw Exception(xopt + AnsiString(" not found in executable.")); + } + + return offset; +} +//--------------------------------------------------------------------------- +AnsiString TConfMainFrame::ReadOptionSectionFromExe(AnsiString filename, int section) +{ + unsigned int offset = FindOptionAreaOffset(filename); + + TStream *stream = NULL; + unsigned char *buf = NULL; + stream = new TFileStream(filename, fmOpenRead|fmShareDenyWrite); + + AnsiString opts; + + try + { + stream->Position = offset + 16; + + // read options area size + unsigned int size; + stream->Read(&size, sizeof(size)); + + // allocate buffer and read options + buf = new unsigned char[size]; + if(size) stream->Read(buf, size); + unsigned char * p = buf; + + while(true) + { + opts = (char*)p; + if(section == 0) break; + section --; + p += opts.Length() + 1; + } + } + catch(...) + { + if(buf) delete [] buf; + delete stream; + throw; + } + + delete [] buf; + delete stream; + + return opts; +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteOptionSectionToExe(AnsiString filename, int section, AnsiString content) +{ + unsigned int offset = FindOptionAreaOffset(filename); + + TStream *stream = NULL; + unsigned char *buf = NULL; + stream = new TFileStream(filename, fmOpenRead|fmShareDenyWrite); + + AnsiString opts; + + try + { + stream->Position = offset + 16; + + // read options area size + unsigned int size; + stream->Read(&size, sizeof(size)); + + // allocate buffer and read all options + std::vector array; + + buf = new unsigned char[size]; + if(size) stream->Read(buf, size); + unsigned char * p = buf; + + for(int i = 0; i < 2; i++) // 2 = max sections + { + AnsiString str = (char*)p; + array.push_back(str); + p += str.Length() + 1; + } + + // replace specified section + array[section] = content; + + // check total length + unsigned int new_size = 0; + for(std::vector::iterator i = array.begin(); + i != array.end(); i++) + { + new_size += i->Length() + 1; + } + + if(new_size > size) + throw Exception("Too large options string."); + + // write back to the buffer + p = buf; + for(std::vector::iterator i = array.begin(); + i != array.end(); i++) + { + strcpy((char*)p, i->c_str()); + p += i->Length() + 1; + } + + // write back to the file + delete stream, stream = NULL; + stream = new TFileStream(filename, fmOpenWrite|fmShareDenyWrite); + stream->Position = offset + 16 + sizeof(size); + stream->Write(buf, new_size); + + } + catch(...) + { + if(buf) delete [] buf; + delete stream; + throw; + } + + delete [] buf; + delete stream; +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadOptionsFromExe(TLayeredOption * dest, AnsiString filename) +{ + AnsiString opts = ReadOptionSectionFromExe(filename, 0); + dest->FromString(opts); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadOptionsFromConfFile(TLayeredOption * dest, AnsiString filename) +{ + if(FileExists(filename)) + dest->LoadFromFile(filename); + else + dest->Clear(); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadOptionsFromIni(TLayeredOption * dest, TMemIniFile * ini) +{ + dest->LoadFromIni(ini); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadExcludeOptionsFromString(AnsiString str) +{ + std::vector array; + SplitAnsiString(str, ",", array); + for(unsigned int i = 0; i Values[array[i]] = "i"; + } +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadExcludeOptionsFromExe(AnsiString filename) +{ + ReadExcludeOptionsFromString(ReadOptionSectionFromExe(filename, 1)); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadExcludeOptionsFromIni(TMemIniFile * ini) +{ + ReadExcludeOptionsFromString(ini->ReadString("Executable-exclude-options", "ExcludeOptions", "")); +} +//--------------------------------------------------------------------------- +int TConfMainFrame::GetSecurityOptionItem(const char *options, const char *name) +{ + size_t namelen = strlen(name); + const char *p = strstr(options, name); + if(!p) return 0; + if(p[namelen] == '(' && p[namelen + 2] == ')') + return p[namelen+1] - '0'; + return 0; +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadSecurityOptionsFromExe(AnsiString filename) +{ + TStream *stream = new TFileStream(filename, fmOpenRead|fmShareDenyWrite); + unsigned char *buf = NULL; + size_t read_size; + try + { + buf = new unsigned char [KRKR_MAX_SIZE]; + read_size = stream->Read(buf, KRKR_MAX_SIZE); + + for(unsigned int i = 0; i < read_size; i++) + { + if(buf[i] == '-' && buf[i+1] == '-') + { + if(!strncmp((const char *)(buf+i+2), " TVPSystemSecurityOptions", 25)) + { + DisableMessageMapCheckBox->Checked = + GetSecurityOptionItem((char*)(buf+i+25+2), "disablemsgmap") != 0; + ForceDataXP3CheckBox->Checked = + GetSecurityOptionItem((char*)(buf+i+25+2), "forcedataxp3") != 0; + } + } + } + } + catch(...) + { + delete stream; + delete [] buf; + throw; + } + delete stream; + delete [] buf; +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadSecurityOptionsFromIni(TMemIniFile * ini) +{ + DisableMessageMapCheckBox->Checked = + ini->ReadBool("Executable-security-options", "DisableMessageMap", false); + ForceDataXP3CheckBox->Checked = + ini->ReadBool("Executable-security-options", "ForceDataXP3", false); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadOptions(AnsiString exename) +{ + ReadExcludeOptionsFromExe(exename); + ReadOptionsFromExe(&EmbeddedConfigData, exename); + ReadOptionInfoFromExe(exename); + + if(UserConfMode) + { + ReadOptionsFromConfFile(&ConfigData, GetConfigFileName(exename)); + AnsiString datapath; + if(!ConfigData.GetOptionValue("datapath", datapath)) + datapath = ""; + ReadOptionsFromConfFile(&UserConfigData, GetUserConfigFileName(datapath, exename)); + } + else + { +#ifndef TVP_ENVIRON + ReadOptionsFromConfFile(&ConfigData, GetConfigFileName(exename)); + ReadSecurityOptionsFromExe(exename); + UserConfigData.Clear(); +#endif + } +} +//--------------------------------------------------------------------------- +void TConfMainFrame::ReadFromIni(TMemIniFile *ini) +{ + ReadOptionsFromIni(TargetConfigData, ini); + ReadExcludeOptionsFromIni(ini); + ReadSecurityOptionsFromIni(ini); + + ChangeIconCheck->Checked = ini->ReadBool("Executable", "ChangeIcon", false); + + OpenPictureDialog->FileName = ini->ReadString("Executable", "Icon", ""); + if(OpenPictureDialog->FileName != "") + { + try + { + IconImage->Picture->LoadFromFile(OpenPictureDialog->FileName); + } + catch(...) + { + OpenPictureDialog->FileName = ""; + } + } +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteOptionsToExe(const TLayeredOption * src, AnsiString filename) +{ + WriteOptionSectionToExe(filename, 0, src->ToString()); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteOptionsToConfFile(const TLayeredOption * src, AnsiString filename) +{ + src->SaveToFile(filename); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteOptionsToIni(const TLayeredOption * src, TMemIniFile * ini) +{ + src->SaveToIni(ini); +} +//--------------------------------------------------------------------------- +AnsiString TConfMainFrame::ConvertExcludeOptionsToString() +{ + AnsiString str; + for(int i = 0; i < ExcludeOptions->Count; i++) + { + if(ExcludeOptions->Values[ExcludeOptions->Names[i]] == "i") + { + if(str != "") str += ","; + str += ExcludeOptions->Names[i]; + } + } + return str; +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteExcludeOptionsToExe(AnsiString filename) +{ + // join with ',' + WriteOptionSectionToExe(filename, 1, ConvertExcludeOptionsToString()); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteExcludeOptionsToIni(TMemIniFile * ini) +{ + ini->WriteString("Executable-exclude-options", "ExcludeOptions", ConvertExcludeOptionsToString()); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::SetSecurityOptionItem(char *options, const char *name, int value) +{ + size_t namelen = strlen(name); + char *p = strstr(options, name); + if(!p) return; + if(p[namelen] == '(' && p[namelen + 2] == ')') + p[namelen+1] = (char)(value + '0'); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteSecurityOptionsToExe(AnsiString filename) +{ + TStream *stream = new TFileStream(filename, fmOpenRead|fmShareDenyWrite); + unsigned char *buf = NULL; + size_t read_size; + try + { + buf = new unsigned char [KRKR_MAX_SIZE]; + read_size = stream->Read(buf, KRKR_MAX_SIZE); + + for(unsigned int i = 0; i < read_size; i++) + { + if(buf[i] == '-' && buf[i+1] == '-') + { + if(!strncmp((const char *)(buf+i+2), " TVPSystemSecurityOptions", 25)) + { + SetSecurityOptionItem((char*)(buf+i+25+2), "disablemsgmap", + DisableMessageMapCheckBox->Checked ? 1:0); + SetSecurityOptionItem((char*)(buf+i+25+2), "forcedataxp3", + ForceDataXP3CheckBox->Checked ? 1:0); + } + } + } + delete stream; stream = NULL; + try + { + stream = new TFileStream(filename, fmOpenWrite|fmShareDenyWrite); + stream->WriteBuffer(buf, read_size); + } + catch(...) + { + // ignore open errors; + // this may occur if the config is to be stored in tof file + // (we should open the file if exe file embedding are enebled, because + // the exe file write permittion checking is already done) + // anyway we can not embed the security options into + // tof file + delete [] buf; + delete stream; stream = NULL; + return; + } + } + catch(...) + { + delete stream; + delete [] buf; + throw; + } + delete stream; + delete [] buf; +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteSecurityOptionsToIni(TMemIniFile * ini) +{ + ini->WriteBool("Executable-security-options", "DisableMessageMap", DisableMessageMapCheckBox->Checked); + ini->WriteBool("Executable-security-options", "ForceDataXP3", ForceDataXP3CheckBox->Checked); +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteOptions(AnsiString exename) +{ + ApplyUIDataToConfigData(); + if(UserConfMode) + { + AnsiString datapath; + if(!ConfigData.GetOptionValue("datapath", datapath)) + datapath = ""; + WriteOptionsToConfFile(&UserConfigData, GetUserConfigFileName(datapath, exename)); + } + else + { +#ifndef TVP_ENVIRON + WriteOptionsToConfFile(&ConfigData, GetConfigFileName(exename)); + WriteExcludeOptionsToExe(exename); + WriteSecurityOptionsToExe(exename); + if(ChangeIconCheck->Checked) + ChangeIcon(exename, exename, OpenPictureDialog->FileName); +#endif + } +} +//--------------------------------------------------------------------------- +void TConfMainFrame::WriteToIni(TMemIniFile *ini) +{ + WriteOptionsToIni(TargetConfigData, ini); + WriteExcludeOptionsToIni(ini); + WriteSecurityOptionsToIni(ini); + + ini->WriteBool("Executable", "ChangeIcon", ChangeIconCheck->Checked); + ini->WriteString("Executable", "Icon", OpenPictureDialog->FileName); +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/ConfMainFrameUnit.dfm b/tools/win32/krdevui/ConfMainFrameUnit.dfm new file mode 100644 index 0000000..de2ad23 --- /dev/null +++ b/tools/win32/krdevui/ConfMainFrameUnit.dfm @@ -0,0 +1,221 @@ +object ConfMainFrame: TConfMainFrame + Left = 0 + Top = 0 + Width = 585 + Height = 328 + TabOrder = 0 + object IconGroupBox: TGroupBox + Left = 0 + Top = 265 + Width = 585 + Height = 63 + Align = alBottom + Caption = 'アイコン(&I)' + TabOrder = 2 + object ChangeIconCheck: TCheckBox + Left = 8 + Top = 32 + Width = 121 + Height = 17 + Caption = 'アイコンを変更する' + TabOrder = 0 + end + object RefIconButton: TButton + Left = 168 + Top = 29 + Width = 75 + Height = 20 + Caption = '参照 ...' + TabOrder = 1 + OnClick = RefIconButtonClick + end + object IconPanel: TPanel + Left = 272 + Top = 16 + Width = 41 + Height = 41 + BevelInner = bvRaised + BevelOuter = bvLowered + TabOrder = 2 + object IconImage: TImage + Left = 2 + Top = 2 + Width = 37 + Height = 37 + Align = alClient + Center = True + Transparent = True + end + end + end + object OptionsGroupBox: TGroupBox + Left = 0 + Top = 0 + Width = 585 + Height = 206 + Align = alClient + Caption = 'オプション(&O)' + Enabled = False + TabOrder = 0 + object Label1: TLabel + Left = 8 + Top = 16 + Width = 109 + Height = 12 + Caption = 'オプションの名前(&N) :' + FocusControl = OptionsTreeView + end + object Label2: TLabel + Left = 363 + Top = 16 + Width = 97 + Height = 12 + Anchors = [akTop, akRight] + Caption = 'オプションの値(&V) :' + end + object OptionsReadFailedLabel: TLabel + Left = 120 + Top = 16 + Width = 210 + Height = 12 + Caption = 'オプション情報の読み込みに失敗しました' + Visible = False + end + object ReadingOptionsLabel: TLabel + Left = 232 + Top = 16 + Width = 155 + Height = 12 + Caption = 'オプション情報を読み込み中 ...' + Visible = False + end + object Label3: TLabel + Left = 360 + Top = 88 + Width = 93 + Height = 12 + Anchors = [akTop, akRight] + Caption = 'オプションの説明 :' + end + object OptionsTreeView: TTreeView + Left = 8 + Top = 32 + Width = 348 + Height = 159 + Anchors = [akLeft, akTop, akRight, akBottom] + HideSelection = False + Indent = 19 + ReadOnly = True + RowSelect = True + ShowRoot = False + TabOrder = 0 + OnChange = OptionsTreeViewChange + end + object OptionValueComboBox: TComboBox + Left = 363 + Top = 32 + Width = 209 + Height = 20 + Style = csDropDownList + Anchors = [akTop, akRight] + Enabled = False + ItemHeight = 12 + TabOrder = 1 + OnChange = OptionValueComboBoxChange + end + object OptionDescMemo: TMemo + Left = 363 + Top = 104 + Width = 209 + Height = 87 + Anchors = [akTop, akRight, akBottom] + BorderStyle = bsNone + Color = clBtnFace + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 2 + end + object RestoreDefaultButton: TButton + Left = 363 + Top = 56 + Width = 118 + Height = 20 + Anchors = [akTop, akRight] + Caption = 'デフォルトに戻す(&D)' + Enabled = False + TabOrder = 3 + OnClick = RestoreDefaultButtonClick + end + object InvisibleCheckBox: TCheckBox + Left = 508 + Top = 56 + Width = 65 + Height = 17 + Anchors = [akTop, akRight] + Caption = '非表示' + Enabled = False + TabOrder = 4 + OnClick = InvisibleCheckBoxClick + end + object OptionValueEdit: TEdit + Left = 363 + Top = 72 + Width = 209 + Height = 20 + Anchors = [akTop, akRight] + TabOrder = 5 + Visible = False + OnChange = OptionValueEditChange + end + end + object ReleaseOptionGroupBox: TGroupBox + Left = 0 + Top = 215 + Width = 585 + Height = 41 + Align = alBottom + Caption = 'リリースオプション(&R)' + TabOrder = 1 + object DisableMessageMapCheckBox: TCheckBox + Left = 8 + Top = 16 + Width = 345 + Height = 17 + Caption = 'メッセージマップファイル(msgmap.tjs)を読み込まない(&M)' + TabOrder = 0 + end + object ForceDataXP3CheckBox: TCheckBox + Left = 368 + Top = 16 + Width = 201 + Height = 17 + Caption = 'XP3アーカイブのみから実行(&3)' + TabOrder = 1 + end + end + object Panel1: TPanel + Left = 0 + Top = 206 + Width = 585 + Height = 9 + Align = alBottom + BevelOuter = bvNone + TabOrder = 3 + end + object Panel2: TPanel + Left = 0 + Top = 256 + Width = 585 + Height = 9 + Align = alBottom + BevelOuter = bvNone + TabOrder = 4 + end + object OpenPictureDialog: TOpenPictureDialog + Filter = 'アイコン (*.ico)|*.ico' + Options = [ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofEnableSizing] + Title = 'アイコンの指定' + Left = 88 + Top = 232 + end +end diff --git a/tools/win32/krdevui/ConfMainFrameUnit.h b/tools/win32/krdevui/ConfMainFrameUnit.h new file mode 100644 index 0000000..363ec10 --- /dev/null +++ b/tools/win32/krdevui/ConfMainFrameUnit.h @@ -0,0 +1,197 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + + +#ifndef ConfMainFrameUnitH +#define ConfMainFrameUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +//--------------------------------------------------------------------------- +class TLayeredOption +{ + TLayeredOption * Parent; // parent option + TStringList * Strings; // option strings + +public: + TLayeredOption(); + virtual ~TLayeredOption(); + + void Clear(); + + TLayeredOption * GetParent() const { return Parent; } + void SetParent(TLayeredOption * parent) { Parent = parent; } + + void FromString(const AnsiString & content); + void LoadFromIni(TMemIniFile * ini); + void LoadFromFile(const AnsiString & filename); + AnsiString ToString() const; + void SaveToFile(const AnsiString & filename) const; + void SaveToIni(TMemIniFile * ini) const; + + bool GetOptionValue(const AnsiString & key, AnsiString & value) const; + void SetOptionValue(const AnsiString & key, const AnsiString & value); + +private: + void InternalListOptionsNames(TStringList * dest) const; +public: + void ListOptionNames(TStringList * dest) const; +}; +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +class TConfMainFrame : public TFrame +{ +__published: // IDE 管理のコンポーネント + TGroupBox *IconGroupBox; + TCheckBox *ChangeIconCheck; + TButton *RefIconButton; + TPanel *IconPanel; + TImage *IconImage; + TGroupBox *OptionsGroupBox; + TOpenPictureDialog *OpenPictureDialog; + TTreeView *OptionsTreeView; + TLabel *Label1; + TComboBox *OptionValueComboBox; + TLabel *Label2; + TMemo *OptionDescMemo; + TLabel *OptionsReadFailedLabel; + TLabel *ReadingOptionsLabel; + TLabel *Label3; + TButton *RestoreDefaultButton; + TCheckBox *InvisibleCheckBox; + TEdit *OptionValueEdit; + TGroupBox *ReleaseOptionGroupBox; + TPanel *Panel1; + TPanel *Panel2; + TCheckBox *DisableMessageMapCheckBox; + TCheckBox *ForceDataXP3CheckBox; + void __fastcall RefIconButtonClick(TObject *Sender); + void __fastcall OptionsTreeViewChange(TObject *Sender, TTreeNode *Node); + void __fastcall OptionValueComboBoxChange(TObject *Sender); + void __fastcall RestoreDefaultButtonClick(TObject *Sender); + void __fastcall InvisibleCheckBoxClick(TObject *Sender); + void __fastcall OptionValueEditChange(TObject *Sender); +private: // ユーザー宣言 + bool DescGot; + +public: // ユーザー宣言 + AnsiString SourceExe; + AnsiString TargetExe; + + __fastcall TConfMainFrame(TComponent* Owner); + __fastcall ~TConfMainFrame(); + + void __fastcall SetUserConfMode(); + bool __fastcall GetUserConfMode() const { return UserConfMode; } + +protected: + + AnsiString OptionsFileName; + AnsiString OriginalOptionsGroupBoxLabel; + AnsiString OrgExcludeOptions; + bool UserConfMode; + +public: + bool __fastcall CheckOK(); +protected: + AnsiString __fastcall GetPluginOptions(AnsiString module); + AnsiString __fastcall SearchPluginOptions(AnsiString path, AnsiString ext); + void __fastcall ParseData(); + void __fastcall ParseOptionsData(TStrings *options); + void __fastcall FreeOptionsData(); + void __fastcall GetValueCaptionAndValue(AnsiString str, + AnsiString &valuecaption, AnsiString &value); + void __fastcall SetOptionValue(AnsiString name, AnsiString value); + void __fastcall SetNodeOptionValue(TTreeNode *node, AnsiString valuecaption, + AnsiString value); + void __fastcall SetNodeInvisibleState(TTreeNode *node, bool invisible); + void __fastcall SetNodeDefaultOptionValue(TTreeNode *node); + +public: + void __fastcall ReadOptionInfoFromExe(AnsiString exename); + +public: // load and store + void __fastcall CopyExe(); + +//-- + // options data +protected: + TLayeredOption UserConfigData; + TLayeredOption ConfigData; + TLayeredOption EmbeddedConfigData; + TLayeredOption DefaultConfigData; + TLayeredOption * TargetConfigData; + TStringList * ExcludeOptions; + +public: + // data mgn. + void InitConfigData(); + void FreeConfigData(); + + // data exchange between data and ui + void ApplyReadDataToUI(); + void ApplyUIDataToConfigData(); + + // filenames + void SetSourceAndTargetFileName(AnsiString source, AnsiString target); + + static AnsiString GetConfigFileName(AnsiString exename); + static AnsiString GetDataPathDirectory(AnsiString datapath, AnsiString exename); + static AnsiString GetUserConfigFileName(AnsiString datapath, AnsiString exename); + + // misc + unsigned int __fastcall FindOptionAreaOffset(AnsiString target); + + AnsiString ReadOptionSectionFromExe(AnsiString filename, int section); + void WriteOptionSectionToExe(AnsiString filename, int section, AnsiString content); + + // read stuff + void ReadOptionsFromExe(TLayeredOption * dest, AnsiString filename); + void ReadOptionsFromConfFile(TLayeredOption * dest, AnsiString filename); + void ReadOptionsFromIni(TLayeredOption * dest, TMemIniFile * ini); + void ReadExcludeOptionsFromString(AnsiString str); + void ReadExcludeOptionsFromExe(AnsiString filename); + void ReadExcludeOptionsFromIni(TMemIniFile * ini); + static int GetSecurityOptionItem(const char *options, const char *name); + void ReadSecurityOptionsFromExe(AnsiString filename); + void ReadSecurityOptionsFromIni(TMemIniFile * ini); + void ReadOptions(AnsiString exename); + void ReadOptions() { ReadOptions(SourceExe); } + void ReadFromIni(TMemIniFile *ini); + + // write stuff + void WriteOptionsToExe(const TLayeredOption * src, AnsiString filename); + void WriteOptionsToConfFile(const TLayeredOption * src, AnsiString filename); + void WriteOptionsToIni(const TLayeredOption * src, TMemIniFile * ini); + AnsiString ConvertExcludeOptionsToString(); + void WriteExcludeOptionsToExe(AnsiString filename); + void WriteExcludeOptionsToIni(TMemIniFile * ini); + static void SetSecurityOptionItem(char *options, const char *name, int value); + void WriteSecurityOptionsToExe(AnsiString filename); + void WriteSecurityOptionsToIni(TMemIniFile * ini); + void WriteOptions(AnsiString exename); + void WriteOptions() { WriteOptions(TargetExe); } + void WriteToIni(TMemIniFile *ini); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TConfMainFrame *ConfMainFrame; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/ConfSettingsUnit.cpp b/tools/win32/krdevui/ConfSettingsUnit.cpp new file mode 100644 index 0000000..d7012fa --- /dev/null +++ b/tools/win32/krdevui/ConfSettingsUnit.cpp @@ -0,0 +1,125 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef TVP_ENVIRON + #include + #pragma hdrstop +#else + #include "tjsCommHead.h" +#endif + +#include "ConfSettingsUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "ConfMainFrameUnit" +#pragma resource "*.dfm" +TConfSettingsForm *ConfSettingsForm; +//--------------------------------------------------------------------------- +#define SPACER 6 +__fastcall TConfSettingsForm::TConfSettingsForm(TComponent* Owner, bool userconf) + : TForm(Owner) +{ + // adjust components + ConfMainFrame->Left = SPACER; + ConfMainFrame->Top = SPACER; + OKButton->Left = ClientWidth - (OKButton->Width + SPACER + CancelButton->Width + + SPACER); + OKButton->Top = ClientHeight - OKButton->Height - SPACER; + CancelButton->Top = ClientHeight - CancelButton->Height - SPACER; + CancelButton->Left = ClientWidth - CancelButton->Width - SPACER; + IconChangeWarnLabel->Top = CancelButton->Top; + + ConfMainFrame->Width = ClientWidth - SPACER * 2; + ConfMainFrame->Height = ClientHeight - SPACER * 2 - SPACER - CancelButton->Height; + + if(userconf) + { + ConfMainFrame->SetUserConfMode(); + IconChangeWarnLabel->Visible = false; + } +} +//--------------------------------------------------------------------------- +bool __fastcall TConfSettingsForm::SelectFile() +{ + if(OpenDialog->Execute()) + { + return InitializeConfig(OpenDialog->FileName); + } + return false; +} +//--------------------------------------------------------------------------- +bool __fastcall TConfSettingsForm::InitializeConfig(AnsiString filename) +{ + // set source and target exe (will be the same) + ConfMainFrame->SetSourceAndTargetFileName(filename, filename); + + // ensure the program is TVP or TVP's descendant + try + { + ConfMainFrame->FindOptionAreaOffset(filename); + } + catch(...) + { + Application->MessageBox(SpecifiedFileIsNotKrKrLabel->Caption.c_str(), + Caption.c_str(), MB_OK|MB_ICONSTOP); + return false; + } + + if(!ConfMainFrame->GetUserConfMode()) + { + // ensure the program is not runnning + try + { + delete new TFileStream(filename, fmOpenReadWrite| + fmShareDenyWrite); + } + catch(...) + { + Application->MessageBox(ProgramMayRunningLabel->Caption.c_str(), + Caption.c_str(), MB_OK|MB_ICONSTOP); + return false; + } + } + + // load options and option information + try + { + ConfMainFrame->ReadOptions(); + } + catch(const Exception & e) + { + Application->MessageBox((SpecifiedFileIsNotKrKrLabel->Caption + "\r\n" + e.Message).c_str(), + Caption.c_str(), MB_OK|MB_ICONSTOP); + return false; + } + + // apply read data to the ui + ConfMainFrame->ApplyReadDataToUI(); + + return true; +} +//--------------------------------------------------------------------------- +void __fastcall TConfSettingsForm::OKButtonClick(TObject *Sender) +{ + try + { + if(ConfMainFrame->CheckOK()) + { + ConfMainFrame->WriteOptions(); + Application->MessageBox(FileWroteLabel->Caption.c_str(), Caption.c_str(), + MB_OK|MB_ICONINFORMATION); + ModalResult = mrOk; + } + } + catch(const Exception & e) + { + Application->MessageBox(e.Message.c_str(), + Caption.c_str(), MB_OK|MB_ICONSTOP); + } +} +//--------------------------------------------------------------------------- diff --git a/tools/win32/krdevui/ConfSettingsUnit.dfm b/tools/win32/krdevui/ConfSettingsUnit.dfm new file mode 100644 index 0000000..a23d053 --- /dev/null +++ b/tools/win32/krdevui/ConfSettingsUnit.dfm @@ -0,0 +1,128 @@ +object ConfSettingsForm: TConfSettingsForm + Left = 56 + Top = 447 + Width = 607 + Height = 406 + Caption = '設定' + Color = clBtnFace + Constraints.MinHeight = 389 + Constraints.MinWidth = 607 + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poDefaultPosOnly + PixelsPerInch = 96 + TextHeight = 12 + object SpecifiedFileIsNotKrKrLabel: TLabel + Left = 8 + Top = 328 + Width = 324 + Height = 12 + Caption = '指定されたファイルは吉里吉里実行可能ファイルではありません' + Visible = False + end + object IconChangeWarnLabel: TLabel + Left = 8 + Top = 337 + Width = 407 + Height = 12 + Anchors = [akLeft, akBottom] + Caption = + '※ 一度アイコンの変更を行うと別のアイコンに変更できなくなる可能' + + '性があります' + end + object FileWroteLabel: TLabel + Left = 8 + Top = 336 + Width = 98 + Height = 12 + Caption = '設定を保存しました' + Visible = False + end + object ProgramMayRunningLabel: TLabel + Left = 8 + Top = 344 + Width = 322 + Height = 12 + Caption = 'ファイルを開けません(プログラムが実行中の可能性があります)' + Visible = False + end + object OKButton: TButton + Left = 425 + Top = 344 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'OK' + Default = True + TabOrder = 0 + OnClick = OKButtonClick + end + object CancelButton: TButton + Left = 505 + Top = 344 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Cancel = True + Caption = 'キャンセル' + ModalResult = 2 + TabOrder = 1 + end + inline ConfMainFrame: TConfMainFrame + Left = 8 + Top = 8 + Width = 578 + Height = 323 + Anchors = [akLeft, akTop, akRight, akBottom] + TabOrder = 2 + inherited IconGroupBox: TGroupBox + Top = 260 + Width = 578 + TabOrder = 1 + end + inherited OptionsGroupBox: TGroupBox + Width = 578 + Height = 201 + inherited Label2: TLabel + Left = 360 + end + inherited OptionsTreeView: TTreeView + TabOrder = 2 + end + inherited OptionValueComboBox: TComboBox + Left = 360 + end + inherited OptionDescMemo: TMemo + TabOrder = 0 + end + inherited RestoreDefaultButton: TButton + Width = 121 + end + end + inherited ReleaseOptionGroupBox: TGroupBox + Top = 210 + Width = 578 + TabOrder = 2 + end + inherited Panel1: TPanel + Top = 201 + Width = 578 + end + inherited Panel2: TPanel + Top = 251 + Width = 578 + end + end + object OpenDialog: TOpenDialog + DefaultExt = 'exe' + Filter = '実行可能ファイル(*.exe)|*.exe|すべてのファイル(*.*)|*.*' + Options = [ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofNoReadOnlyReturn, ofEnableSizing] + Title = '吉里吉里 実行可能ファイルの選択' + Left = 384 + Top = 328 + end +end diff --git a/tools/win32/krdevui/ConfSettingsUnit.h b/tools/win32/krdevui/ConfSettingsUnit.h new file mode 100644 index 0000000..76722e8 --- /dev/null +++ b/tools/win32/krdevui/ConfSettingsUnit.h @@ -0,0 +1,44 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef ConfSettingsUnitH +#define ConfSettingsUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include "ConfMainFrameUnit.h" +#include +//--------------------------------------------------------------------------- +class TConfSettingsForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TButton *OKButton; + TButton *CancelButton; + TConfMainFrame *ConfMainFrame; + TOpenDialog *OpenDialog; + TLabel *SpecifiedFileIsNotKrKrLabel; + TLabel *IconChangeWarnLabel; + TLabel *FileWroteLabel; + TLabel *ProgramMayRunningLabel; + void __fastcall OKButtonClick(TObject *Sender); +private: // ユーザー宣言 +public: // ユーザー宣言 + __fastcall TConfSettingsForm(TComponent* Owner, bool userconf); + + bool __fastcall SelectFile(); + + bool __fastcall InitializeConfig(AnsiString filename); + +}; +//--------------------------------------------------------------------------- +extern PACKAGE TConfSettingsForm *ConfSettingsForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/FolderSelectorUnit.cpp b/tools/win32/krdevui/FolderSelectorUnit.cpp new file mode 100644 index 0000000..06e7779 --- /dev/null +++ b/tools/win32/krdevui/FolderSelectorUnit.cpp @@ -0,0 +1,224 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop +#include +#include + +#include "FolderSelectorUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "ShellCtrls" +#pragma resource "*.dfm" +TFolderSelectorForm *FolderSelectorForm; +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +#define SPACER 6 +__fastcall TFolderSelectorForm::TFolderSelectorForm(TComponent* Owner) + : TForm(Owner) +{ + ShellComboBox->Align = alTop; + + // adjust components + Label1->Left = SPACER; + Label1->Top = SPACER; + NoSelectButton->Left = SPACER; + NoSelectButton->Top = ClientHeight - NoSelectButton->Height - SPACER; + OKButton->Left = ClientWidth - OKButton->Width - CancelButton->Width - + SPACER*2- StatusBar1->Width ; + OKButton->Top = ClientHeight - OKButton->Height -SPACER; + CancelButton->Left = ClientWidth - CancelButton->Width - SPACER + - StatusBar1->Width ; + CancelButton->Top = ClientHeight - CancelButton->Height - SPACER; + ViewPanel->Left = SPACER; + ViewPanel->Top = SPACER + Label1->Height + 2; + ViewPanel->Width = ClientWidth - SPACER*2; + ViewPanel->Height = ClientHeight - ( SPACER + Label1->Height + SPACER + SPACER + + NoSelectButton->Height + Label2->Height + 2 ); + Label2->Left = SPACER; + Label2->Top = ViewPanel->Top + ViewPanel->Height + 2; + PageScroller->Top = Label2->Top; + PageScroller->Left = Label2->Left + Label2->Width; + PageScroller->Width = ClientWidth - (SPACER*2+Label2->Width); + StatusBar1->Left = ClientWidth - StatusBar1->Width; + StatusBar1->Top = ClientHeight - StatusBar1->Height; +} +//--------------------------------------------------------------------------- + +void __fastcall TFolderSelectorForm::FormResize(TObject *Sender) +{ + if(ShellTreeView->Width < 50) + { + ShellListView->Width = ViewPanel->Width - 50 - Splitter->Width; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFolderSelectorForm::FormDestroy(TObject *Sender) +{ + // delete some shell related components here to avoid undeleted threads' + // mischief. + delete ShellTreeView; + delete ShellListView; + delete ShellComboBox; +} +//--------------------------------------------------------------------------- +void __fastcall TFolderSelectorForm::ShellTreeViewChange(TObject *Sender, + TTreeNode *Node) +{ + if(ShellTreeView->Path != "" && DirectoryExists(ShellTreeView->Path)) + { + PlaceLabel->Caption = ShellTreeView->Path + FolderLabel->Caption; + Selected = ShellTreeView->Path; + OKButton->Enabled = true; + } + else + { + OKButton->Enabled = false; + Selected = ""; + PlaceLabel->Caption = NothingLabel->Caption; + } +} +//--------------------------------------------------------------------------- + +void __fastcall TFolderSelectorForm::ShellTreeViewClick(TObject *Sender) +{ + ShellTreeViewChange(Sender, NULL); +} +//--------------------------------------------------------------------------- + +void __fastcall TFolderSelectorForm::ShellListViewChange(TObject *Sender, + TListItem *Item, TItemChange Change) +{ + if(ShellListView->Selected) + { + TShellListView *slv = (TShellListView*)ShellListView; + AnsiString fn = + slv->FileList->FileItem[ShellListView->Selected->Index]->Path; + if(fn!="") + { + if(FileExists(fn)) + { + PlaceLabel->Caption = fn + FileLabel->Caption; + Selected = fn; + OKButton->Enabled= true; + return; + } + if(DirectoryExists(fn)) + { + PlaceLabel->Caption = fn + FolderLabel->Caption; + Selected = fn; + OKButton->Enabled= true; + return; + } + } + } + + if(ShellTreeView->Path != "" && DirectoryExists(ShellTreeView->Path)) + { + PlaceLabel->Caption = ShellTreeView->Path + FolderLabel->Caption; + Selected = ShellTreeView->Path; + OKButton->Enabled = true; + } + else + { + OKButton->Enabled = false; + Selected = ""; + PlaceLabel->Caption = NothingLabel->Caption; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFolderSelectorForm::ShellListViewClick(TObject *Sender) +{ + ShellListViewChange(Sender, NULL, TItemChange()); +} +//--------------------------------------------------------------------------- + +void __fastcall TFolderSelectorForm::ShellListViewShExecute( + TObject *Sender, TShellFileItem *Item, TShiftState Shift, + int SubItem, int X, int Y, bool &DefaultAction) +{ + if(FileExists(Item->Path)) + { + // selected item is a file + DefaultAction =false; + OKButton->Click(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFolderSelectorForm::SelectItemMenuItemClick( + TObject *Sender) +{ + if(OKButton->Enabled) OKButton->Click(); +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +extern "C" int _export PASCAL UIShowFolderSelectorForm(void *reserved, char *buf) +{ + TFolderSelectorForm *form = new TFolderSelectorForm(Application); + form->ShellTreeView->Path = buf; // initial directory + if(form->ShellTreeView->Selected) + { + form->ShellTreeView->Selected->Expanded = true; + TTreeNode * topnode = form->ShellTreeView->Selected; + if(topnode->Count >= 1) + { + TTreeNode * longestitem = NULL; + int longesttextsize = -1; + for(int i = 0; i < topnode->Count; i++) + { + TTreeNode *subnode = topnode->Item[i]; + TRect rect = subnode->DisplayRect(true); + if(rect.right > longesttextsize) + { + longesttextsize = rect.right; + longestitem = topnode->Item[i]; + } + } + if(longestitem) + longestitem->MakeVisible(); + +// form->ShellTreeView->Selected->MakeVisible(); +// INT min, max; +// ::GetScrollRange(form->ShellTreeView->Handle, SB_HORZ, &min, &max); +// ::SetScrollPos(form->ShellTreeView->Handle, SB_HORZ, max, true); +// form->ShellTreeView->Selected->MakeVisible(); +// TreeView_EnsureVisible(form->ShellTreeView->Selected->Handle, +// form->ShellTreeView->Selected->ItemId); + } + form->ShellTreeView->TopItem = topnode; + topnode->MakeVisible(); + } + + int res = form->ShowModal(); + if(res == mrOk) + { + if(DirectoryExists(form->Selected)) + { + form->Selected = IncludeTrailingBackslash(form->Selected); + } + strcpy(buf, form->Selected.c_str()); + } + delete form; + return res; +} +//--------------------------------------------------------------------------- + + + + + + diff --git a/tools/win32/krdevui/FolderSelectorUnit.dfm b/tools/win32/krdevui/FolderSelectorUnit.dfm new file mode 100644 index 0000000..2dfe212 --- /dev/null +++ b/tools/win32/krdevui/FolderSelectorUnit.dfm @@ -0,0 +1,1632 @@ +object FolderSelectorForm: TFolderSelectorForm + Left = 18 + Top = 6 + Width = 637 + Height = 435 + HorzScrollBar.Tracking = True + HorzScrollBar.Visible = False + VertScrollBar.Tracking = True + VertScrollBar.Visible = False + ActiveControl = ShellTreeView + Caption = 'フォルダ/アーカイブの選択' + Color = clBtnFace + Constraints.MinHeight = 225 + Constraints.MinWidth = 300 + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + Icon.Data = { + 000001000B00404000000100200028420000B600000040400000010008002816 + 0000DE4200004040100001000400680A0000065900003030000001002000A825 + 00006E6300002020000001002000A8100000168900002020000001000800A808 + 0000BE9900002020100001000400E802000066A2000020200200010001003001 + 00004EA500001010000001002000680400007EA6000010100000010008006805 + 0000E6AA00001010100001000400280100004EB0000028000000400000008000 + 0000010020000000000000420000000000000000000000000000000000000000 + 0000000000000000000000000000000000390000004500000015000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000010000000B0000 + 001B00000028000000320000003B000000400000004400000046000000450000 + 00420000003E000000370000002E000000240000001600000008000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000010000000000000000000000390000004700000044000000140000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000001000000130000002A00000040000000470000 + 0047000000470000004700000047000000470000004700000047000000470000 + 00470000004700000047000000470000004700000047000000460000003C0000 + 00270000000F0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000440000004E00000000000000390000004700000047000000440000 + 0012000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000004000000200000003D000000470000004700000047000000470000 + 0047000000470000004700000047000000470000004700000047000000470000 + 0047000000470000004700000047000000470000004700000047000000470000 + 0047000000470000003A0000001D000000020000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000004B000000F700000049000000390000004700000047000000470000 + 0043000000110000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000020000 + 001F00000041000000470000004700000047000000470000004A000000590000 + 0071000000860000008E0000009600000099000000920000008A0000007D0000 + 0067000000530000004800000047000000470000004700000047000000470000 + 00470000004700000047000000470000003F0000001B00000001000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000004B000000FF000000F5000000730000004700000047000000470000 + 0047000000430000001000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000110000003B0000 + 004700000047000000480000006D000000A1000000CB000000F1000000FE0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FC000000E8000000C30000009A0000006500000048000000470000 + 00470000004700000047000000470000004700000047000000360000000A0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000004B000000FF000000FF000000F70000007500000047000000470000 + 004700000047000000420000000F000000000000000000000000000000000000 + 0000000000000000000000000000000000010000002400000046000000470000 + 005E000000A8000000E8000000FF000000FF000000FF000000FF000000FF0501 + 01FF1A0607FF27090AFF330C0DFF370D0EFF2D0B0CFF220809FF110404FF0100 + 00FF000000FF000000FF000000FF000000FF000000FF000000E4000000A20000 + 005C000000470000004700000047000000470000004700000047000000430000 + 0018000000000000000000000000000000000000000000000000000000000000 + 00000000004B000000FF000000FF000000FF000000F500000072000000470000 + 00470000004700000047000000420000000E0000000000000000000000000000 + 0000000000000000000000000005000000330000004700000066000000C10000 + 00FC000000FF000000FF020101FF2E0C0DFF6E1C1FFFA82A2FFFD7353BFFF43D + 43FFFE3F46FFFF3F46FFFF3F46FFFF3F46FFFF4046FFFF4046FFFB3F45FFEC3B + 41FFCB3338FF99272BFF641A1CFF23090AFF010000FF000000FF000000FF0000 + 00FB000000BC0000006300000047000000470000004700000047000000470000 + 0046000000210000000000000000000000000000000000000000000000000000 + 00000000004B000000FF090303FF240A0BFF000000FF000000F40000006F0000 + 0047000000470000004700000047000000410000000C00000000000000000000 + 000000000000000000080000003B00000054000000B6000000FC000000FF0000 + 00FF1F0909FF842428FFD93B41FFFF454BFFFF454BFFFF454BFFFF454BFFFF45 + 4BFFFF454BFFFF454BFFFF454BFFFF454CFFFF454CFFFF454CFFFF454CFFFF45 + 4CFFFF454CFFFF454CFFFF454CFFFD454BFFD43A3FFF7D2225FF1C0808FF0000 + 00FF000000FF000000FB000000AC000000500000004700000047000000470000 + 0047000000470000002000000000000000000000000000000000000000000000 + 00000000004B000000FF110505FFE04146FF220A0BFF000000FF000000F30000 + 006C00000047000000470000004700000047000000400000000B000000000000 + 0000000000070000003D00000083000000EF000000FF000000FF2D0D0EFFAB32 + 36FFFC494FFFFF4A50FFFF4A51FFFF4A51FFFF4A51FFFF4A51FFFF4A51FFFF4A + 51FFFF4A51FFFF4A51FFFF4A51FFFF4A51FFFF4A51FFFF4A51FFFF4A51FFFF4A + 51FFFF4A51FFFF4A51FFFF4A51FFFF4A51FFFF4A51FFFF4A51FFFC4950FFA430 + 35FF290C0DFF000000FF000000FF000000E70000006F00000047000000470000 + 0047000000470000004700000018000000000000000000000000000000000000 + 00000000004B000000FF110506FFFD4E55FFDD454AFF1F0A0AFF000000FF0000 + 00F000000069000000470000004700000047000000470000003F0000000A0000 + 00050000003E000000B3000000FE000000FF140607FF9A3134FFFB4E54FFFF4F + 56FFFF4F56FFFF5056FFFF5056FFFF5056FFFF5056FFFF5056FFFF5056FFFF50 + 56FFFF5056FFFF5056FFFF5056FFFF5056FFFF5056FFFF5056FFFF5056FFFF50 + 56FFFF5056FFFF5056FFFF5056FFFF5056FFFF5056FFFF5056FFFF5056FFFF50 + 56FFF94E54FF8B2C30FF0D0404FF000000FF000000FA0000008E000000470000 + 00470000004700000047000000430000000A0000000000000000000000000000 + 00000000004B000000FF110606FFFD545AFFFF545BFFDA484EFF1C090AFF0000 + 00FF000000EF00000066000000470000004700000047000000470000003F0000 + 0041000000D1000000FF000000FF4C1A1BFFE84D53FFFF555BFFFF555BFFFF55 + 5BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF55 + 5BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF55 + 5BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF55 + 5BFFFF555BFFFF555BFFD8494EFF311112FF000000FF000000FE0000009B0000 + 0047000000470000004700000047000000330000000000000000000000000000 + 00000000004B000000FF110607FFFD595FFFFF5A60FFFF5A60FFD74C51FF1809 + 09FF000000FF000000ED00000064000000470000004700000047000000570000 + 00DE000000FF040101FF893134FFFD5A60FFFF5A60FFFF5A60FFFF5A60FFFF5A + 60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFFF5A + 60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFFF5B60FFFF5B60FFFF5B60FFFF5B + 60FFFF5B60FFFF5B61FFFF5B61FFFF5B61FFFF5B61FFFF5B61FFFF5B61FFFF5B + 61FFFF5B61FFFF5B61FFFF5B61FFF4575DFF4D1C1EFF000000FF000000FE0000 + 0091000000470000004700000047000000470000001200000000000000000000 + 00000000004B000000FF110607FFFD5E64FFFF5F65FFFF5F65FFFF5F65FFD24F + 54FF160809FF000000FF000000EA000000610000004700000052000000D90000 + 00FF080303FFAD4145FFFF6065FFFF6066FFFF6066FFFF6066FFFF6066FFFF60 + 66FFFF6066FFFF6066FFFF6066FFFF6066FFFF6066FFFF6066FFFF6066FFFF60 + 66FFFF6066FFFF6066FFFF6066FFFF6066FFFF6066FFFF6066FFFF6066FFFF60 + 66FFFF6066FFFF6066FFFF6066FFFF6066FFFF6066FFFF6066FFFF6066FFFF60 + 66FFFF6066FFFF6066FFFF6066FFFF6066FFF95E64FF4F1E20FF000000FF0000 + 00FA000000720000004700000047000000470000002F00000000000000000000 + 00000000004B000000FF110707FFFD646AFFFF656AFFFF656AFFFF656AFFFF65 + 6AFFCF5257FF130808FF000000FF000000E900000063000000CF000000FF0703 + 03FFB5484CFFFF656BFFFF656BFFFF656BFFFF656BFFFF656BFFFF656BFFFF65 + 6BFFFF656BFFFF656BFFFF656BFFFF656BFFFF656BFFFF656BFFFF656BFFFF65 + 6BFFFF656BFFFF656BFFFF656BFFFF656BFFFF666BFFFF666BFFFF666BFFFF66 + 6BFFFF666BFFFF666BFFFF666BFFFF666BFFFF666BFFFF666BFFFF666BFFFF66 + 6BFFFF666BFFFF666BFFFF666CFFFF666CFFFF666CFFF56267FF321415FF0000 + 00FF000000E50000004F00000047000000470000004300000002000000000000 + 00000000004B000000FF110708FFFD696FFFFF6A70FFFF6A70FFFF6A70FFFF6A + 70FFFF6A70FFCB5559FF110708FF000000FF000000F8000000FF030101FFA746 + 4AFFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6B70FFFF6B70FFFF6B70FFFF6B + 70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B + 70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B + 70FFFF6B71FFFF6B71FFFF6B71FFFF6B71FFFE6B70FFB64C50FF652A2CFF5A25 + 27FF963E42FFF7676DFFFF6B71FFFF6B71FFFF6B71FFFF6B71FFDA5C61FF0A04 + 04FF000000FF000000A20000004700000047000000470000000A000000000000 + 00000000004B000000FF110808FFFD6F74FFFF7075FFFF7075FFFF7075FFFF70 + 75FFFF7075FFFF7075FFC6575BFF0F0607FF000000FF000000FF80383BFFFF70 + 75FFFF7075FFFF7075FFFF7075FFFF7075FFFF7075FFFF7075FFFF7075FFFF70 + 75FFFF7075FFFF7075FFFF7075FFFF7076FFFF7076FFFF7076FFFF7076FFFF70 + 76FFFF7076FFFF7076FFFF7076FFFF7076FFFF7076FFFF7076FFFF7076FFFF70 + 76FFFF7076FFFF7076FFFF7076FFF86D72FF572628FF000000FF000000FF0000 + 00FF000000FF2B1213FFE26368FFFF7176FFFF7176FFFF7176FFFF7176FF7E38 + 3AFF000000FF000000F20000004F00000047000000470000000B000000000000 + 00000000004B000000FF110808FFFD7479FFFF757AFFFF757AFFFF757AFFFF75 + 7AFFFF757AFFFF757AFFFF757AFFC35A5EFF0D0606FF401D1FFFFC7479FFFF75 + 7AFFFF757AFFFF757AFFFF757BFFFF757BFFFF757BFFFF757BFFFF757BFFFF75 + 7BFFFF757BFFFF757BFFFF757BFFFF757BFFFF757BFFFF757BFFFF757BFFFF75 + 7BFFFF767BFFFF767BFFFF767BFFFF767BFFFF767BFFFF767BFFFF767BFFFF76 + 7BFFFF767BFFFF767BFFFF767BFF622D2FFF000000FF010000FF452022FF5E2C + 2EFF080404FF000000FF2D1516FFF57176FFFF767BFFFF767BFFFF767BFFED6E + 73FF0B0505FF000000FF00000086000000470000004400000003000000000000 + 00000000004B000000FF110809FFFD797FFFFF7A80FFFF7A80FFFF7A80FFFF7A + 80FFFF7A80FFFF7A80FFFF7B80FFFF7B80FFBF5C60FFDC6A6EFFFF7B80FFFF7B + 80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B + 80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B + 80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B + 80FFFF7B80FFFF7B80FFB8595CFF010101FF000000FF884245FFFE7B80FFFF7B + 81FFC25E62FF080404FF000000FF813E41FFFF7B81FFFF7B81FFFF7C81FFFF7C + 81FF4D2627FF000000FF000000B3000000470000003200000000000000000000 + 00000000004B000000FF110909FFFD7F84FFFF8085FFFF8085FFFF8085FFFF80 + 85FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF80 + 85FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF80 + 85FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF80 + 85FFFF8085FFFF8085FFFF8085FFFF8085FFFF8186FFFF8186FFFF8186FFFF81 + 86FFFF8186FFFF8186FF3A1D1EFF000000FF462425FFFE8085FFFF8186FFFF81 + 86FFFF8186FF7F4043FF000000FF110909FFF47B80FFFF8186FFFF8186FFFF81 + 86FF723A3CFF000000FF000000C6000000470000001600000000000000000000 + 00000000004B000000FF110909FFFD8489FFFF858AFFFF858AFFFF858AFFFF85 + 8AFFFF858AFFFF858AFFFF858AFFFF858AFFFE8589FFF88286FFFF858AFFFF85 + 8AFFFF858AFFFF858AFFFF858AFFFF858AFFFF868AFFFF868AFFFF868AFFFF86 + 8AFFFF868AFFFF868AFFFF868BFFFF868BFFFF868BFFFF868BFFFF868BFFFF86 + 8BFFFF868BFFFF868BFFFF868BFFFF868BFFFF868BFFFF868BFFFF868BFFFF86 + 8BFFFF868BFFFF868BFFB66064FF502B2CFFC6686CFFFF868BFFFF868BFFFF86 + 8BFFFF868BFFEE7D82FF351C1DFF8A494CFFF38084FFFF868BFFFF868BFFFF86 + 8BFF592F30FF000000FF000000B9000000380000000000000000000000000000 + 00000000004B000000FF11090AFFFD8A8EFFFF8B90FFFF8B90FFFF8B90FFFF8B + 90FFFF8B90FFFF8B90FFFF8B90FFFE8A8FFF6F3C3EFF6A393BFFFF8B90FFFF8B + 90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B + 90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B + 90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8C90FFFF8C + 90FFFF8C90FFFF8C90FFFF8C90FFFF8C90FFFF8C90FFFF8C90FFFF8C90FFFF8C + 90FFFF8C90FFFF8C90FFFF8C90FFFF8C90FFFF8C91FFFF8C91FFFF8C91FFF687 + 8BFF150B0CFF000000FF0000008F0000000E0000000000000000000000000000 + 00000000004B000000FF110A0AFFFD8F93FFFF9095FFFF9095FFFF9095FFFF90 + 95FFFF9095FFFF9095FFFD8F93FF6C3C3EFF000000FF020101FFB6676AFFFF90 + 95FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF9195FFFF9195FFFF91 + 95FFFF9195FFFF9195FFFF9195FFFF9195FFFF9195FFFF9195FFFF9195FFFF91 + 95FFFF9195FFFF9195FFFF9195FFFF9195FFFF9195FFFF9195FFFF9195FFFF91 + 95FFFF9195FFFF9195FFFF9196FFFF9196FFFF9196FFFF9196FFFF9196FFFF91 + 96FFFF9196FFFF9196FFFF9196FFFF9196FFFF9196FFFF9196FFFF9196FF9A58 + 5AFF000000FF000000FA0000002E000000000000000000000000000000000000 + 00000000004B000000FF110A0AFFFD9499FFFF959AFFFF969AFFFF969AFFFF96 + 9AFFFF969AFFFD9499FF693D3FFF000000FF000000FF000000FF140B0CFFDC81 + 85FFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF96 + 9AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF96 + 9AFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFFF96 + 9BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFFF96 + 9BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFED8C90FF180E + 0FFF000000FF0000009C00000000000000000000000000000000000000000000 + 00000000004B000000FF110B0BFFFD9A9EFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B + 9FFFFD999EFF663E3FFF000000FF000000FF0000009B000000E6000000FF2315 + 16FFE48B8EFFFF9B9FFFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9B + A0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9B + A0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9C + A0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9C + A0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFD9B9FFF553335FF0000 + 00FF000000EE0000001A00000000000000000000000000000000000000000000 + 00000000004B000000FF110B0BFFFD9FA3FFFFA0A4FFFFA0A4FFFFA0A4FFFC9E + A2FF633E3FFF000000FF000000FF0000008C0000000100000034000000F00000 + 00FF29191AFFE18D91FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1 + A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1 + A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1 + A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1 + A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A6FFFFA1A5FF7D4F51FF000000FF0000 + 00FE0000005E0000000000000000000000000000000000000000000000000000 + 00000000004B000000FF110B0CFFFDA5A9FFFFA6AAFFFFA6AAFFFCA4A8FF603E + 40FF000000FF000000FF000000890000000100000000000000000000003F0000 + 00F5000000FF1D1313FFCA8387FFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6 + AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6 + AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA7ABFFFFA7 + ABFFFFA7ABFFFFA7ABFFFFA7ABFFFFA7ABFFFFA7ABFFFFA7ABFFFFA7ABFFFFA7 + ABFFFFA7ABFFFFA7ABFFFFA7ABFFFEA6AAFF805355FF010101FF000000FF0000 + 0094000000010000000000000000000000000000000000000000000000000000 + 00000000004B000000FF110C0CFFFDAAAEFFFFABAFFFFBA8ACFF5E3F40FF0000 + 00FF000000FF0000008700000001000000000000000000000000000000000000 + 003D000000ED000000FF0A0607FF936365FFFEABAFFFFFACAFFFFFACAFFFFFAC + AFFFFFACAFFFFFACAFFFFFACAFFFFFACAFFFFFACB0FFFFACB0FFFFACB0FFFFAC + B0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFAC + B0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFAC + B0FFFFACB0FFFFACB0FFF4A5A8FF614142FF000000FF000000FF000000A80000 + 0003000000000000000000000000000000000000000000000000000000000000 + 00000000004B000000FF110C0CFFFDAFB3FFFAADB1FF5B3F40FF000000FF0000 + 00FE000000830000000100000000000000000000000000000000000000000000 + 000000000026000000D4000000FF000000FF442F30FFD69498FFFFB1B5FFFFB1 + B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1 + B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1 + B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1 + B5FFFFB1B5FFC4888BFF2B1E1EFF000000FF000000FF00000099000000050000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000004B000000FF110C0DFFF9B1B5FF593F40FF000000FF000000FF0000 + 0080000000010000000000000000000000000000000000000000000000000000 + 0000000000000000000C0000009A000000FE000000FF080505FF694A4CFFE3A2 + A5FFFFB6BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7 + BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7 + BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BBFFFFB7BBFFFFB7BBFFFFB7BBFFDA9C + 9FFF5E4344FF030202FF000000FF000000F70000006A00000001000000000000 + 0000000000000000000000000000000000000000000100000002000000000000 + 00000000004B000000FF0E0A0AFF553E3FFF000000FF000000FE0000007E0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000044000000D7000000FF000000FF0705 + 05FF573F40FFBD8A8DFFFAB8BCFFFFBCBFFFFFBCBFFFFFBCBFFFFFBCBFFFFFBC + BFFFFFBCBFFFFFBCBFFFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBC + C0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFAB8BCFFB78789FF533D3EFF0503 + 03FF000000FF000000FF000000C50000002E0000000000000000000000000000 + 0000000000000000000000000000000000010000002C0000000A000000000000 + 00000000004B000000FF000000FF000000FF000000FE0000007A000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000010000000E0000007A000000E80000 + 00FF000000FF000000FF181212FF634A4BFFA1797BFFD9A5A7FFF9BCC0FFFFC1 + C5FFFFC1C5FFFFC1C5FFFFC1C5FFFFC1C5FFFFC1C5FFFFC1C5FFFFC1C5FFFFC1 + C5FFF7BCBFFFD29FA2FF9D7779FF5C4546FF140F10FF000000FF000000FF0000 + 00FF000000D80000005D00000003000000000000000000000000000000000000 + 00000000000000000000000000010000002A000000470000000A000000000000 + 00000000004B000000FF000000FF000000FE0000007800000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000070000001C000000300000003F00000047000000470000004C0000 + 0086000000D1000000FE000000FF000000FF000000FF000000FF0D0A0BFF2A20 + 21FF4A393AFF584445FF644D4FFF695152FF604A4BFF574344FF433434FF251C + 1DFF0C0909FF000000FF000000FF000000FF000000FF000000FC000000B80000 + 0053000000050000000000000000000000000000000000000000000000000000 + 000000000000000000000000002800000047000000470000000A000000000000 + 00000000004B000000FF000000FE000000750000000000000000000000000000 + 0000000000000000000000000000000000000000000000000002000000190000 + 0035000000470000004700000047000000470000004700000047000000470000 + 0047000000470000005A00000093000000C6000000ED000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FE000000E2000000AC0000006200000019000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000280000007800000047000000470000000A000000000000 + 00000000004B000000FE00000071000000000000000000000000000000000000 + 0000000000000000000000000000000000020000001D0000003E000000470000 + 004700000047000000470000004700000047000000480000004C000000500000 + 005700000059000000520000004D00000049000000490000005F0000007B0000 + 0094000000A8000000B1000000BA000000BE000000B7000000B1000000A40000 + 008D000000570000001B00000002000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000026000000AB000000C000000047000000470000000A000000000000 + 0000000000490000006E00000000000000000000000000000000000000000000 + 00000000000000000000000000100000003A0000004700000047000000470000 + 004F000000750000009B000000BF000000D8000000ED000000FA000000FF0000 + 00FF000000FF000000FF000000FC000000F1000000DA000000C00000009C0000 + 00710000004D0000004700000047000000470000004700000047000000470000 + 0047000000470000003200000009000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0024000000A7000000FF000000C100000047000000470000000A000000000000 + 0000000000060000000000000000000000000000000000000000000000000000 + 000000000001000000230000004600000047000000510000008E000000C80000 + 00F7000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000F5000000BF000000820000004C0000004700000047000000470000 + 00470000004700000047000000440000001D0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000220000 + 00A4000000FF000000FF000000C100000047000000470000000A000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000300000031000000470000005F000000B4000000F5000000FF000000FF0000 + 00FF050101FF2E0B0DFF63181BFF892225FFA8292EFFC43035FFD03338FFDB36 + 3BFFDE363CFFD33439FFC73136FFAD2B2FFF8B2226FF64191BFF2C0B0CFF0301 + 01FF000000FF000000FF000000FF000000EB000000A200000053000000470000 + 0047000000470000004700000047000000470000002F00000003000000000000 + 00000000000000000000000000000000000000000000000000200000009E0000 + 00FF000000FF000000FF000000C100000047000000470000000A000000000000 + 0000000000000000000000000000000000000000000000000000000000030000 + 003600000054000000B3000000FB000000FF000000FF0E0404FF5F1A1CFFAD2E + 33FFF04046FFFF444AFFFF444AFFFF444AFFFF444AFFFF444AFFFF444AFFFF44 + 4AFFFF444AFFFF444AFFFF444AFFFF444AFFFF444AFFFF444AFFFF444AFFEC3F + 44FFA22B2FFF4E1517FF060202FF000000FF000000FF000000F20000009E0000 + 004D000000470000004700000047000000470000004700000039000000070000 + 0000000000000000000000000000000000000000001E0000009A000000FE0000 + 00FF090203FF000000FF000000C100000047000000470000000A000000000000 + 0000000000000000000000000000000000000000000000000001000000320000 + 0082000000EE000000FF000000FF230A0BFF982C30FFF0454BFFFF4950FFFF49 + 50FFFF4950FFFF494FFFFF494FFFFF494FFFFF494FFFFF494FFFFF494FFFFF49 + 4FFFFF494FFFFF494FFFFF494FFFFF494FFFFF494FFFFF494FFFFF494FFFFF49 + 4FFFFF494FFFFF494FFFE34147FF7E2427FF120506FF000000FF000000FF0000 + 00E20000007500000047000000470000004700000047000000470000003C0000 + 00070000000000000000000000000000001C00000096000000FE000000FF5518 + 1BFF681E20FF000000FF000000C100000047000000470000000A000000000000 + 0000000000000000000000000000000000000000000000000027000000AE0000 + 00FE000000FF110506FF962F32FFF94D53FFFF4F55FFFF4F55FFFF4F55FFFF4F + 55FFFF4F55FFFF4F55FFFF4F55FFFF4F55FFFF4F55FFFF4F55FFFF4F55FFFF4E + 55FFFF4E55FFFF4E55FFFF4E55FFFF4E55FFFF4E55FFFF4E55FFFF4E55FFFF4E + 55FFFF4E55FFFF4E55FFFF4E55FFFF4E55FFED494FFF792629FF070202FF0000 + 00FF000000FC000000A70000004A000000470000004700000047000000470000 + 003A00000005000000000000001B00000091000000FE000000FF4E181AFFF94D + 53FF6D2124FF000000FF000000C100000047000000470000000A000000000000 + 00000000000000000000000000000000000000000015000000C5000000FF0000 + 00FF4B191BFFE84D52FFFF545AFFFF545AFFFF545AFFFF545AFFFF545AFFFF54 + 5AFFFF545AFFFF545AFFFF545AFFFF545AFFFF545AFFFF545AFFFF545AFFFF54 + 5AFFFF545AFFFF545AFFFF545AFFFF545AFFFF545AFFFF545AFFFF545AFFFF54 + 5AFFFF545AFFFF545AFFFF545AFFFF545AFFFF545AFFFF545AFFD7474CFF3A14 + 15FF000000FF000000FF000000CB000000530000004700000047000000470000 + 0047000000350000001B0000008D000000FD000000FF4A191BFFF85158FFFF54 + 5AFF6D2427FF000000FF000000C100000047000000470000000A000000000000 + 000000000000000000000000000000000005000000B6000000FF010000FF7F2D + 30FFFC595FFFFF5960FFFF5960FFFF5960FFFF5960FFFF5960FFFF5960FFFF59 + 60FFFF5960FFFF5960FFFF5960FFFF5960FFFF5960FFFF5960FFFF5960FFFF59 + 60FFFF5960FFFF5960FFFF5960FFFF5960FFFF595FFFFF595FFFFF595FFFFF59 + 5FFFFF595FFFFF595FFFFF595FFFFF595FFFFF595FFFFF595FFFFF595FFFFA57 + 5DFF7B2C2EFF020101FF000000FF000000DD0000005900000047000000470000 + 0047000000470000008A000000FD000000FF45191AFFF5565CFFFF595FFFFF59 + 5FFF6D2629FF000000FF000000C100000047000000470000000A000000000000 + 000000000000000000000000000000000091000000FF010101FF94373BFFFF5F + 65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F + 65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F + 65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F + 65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F65FFFF5F + 65FFFF5F65FFA83F43FF080303FF000000FF000000DF00000055000000470000 + 004700000086000000FC000000FF40181AFFF45B60FFFF5F65FFFF5F65FFFF5F + 65FF6D292BFF000000FF000000C100000047000000470000000A000000000000 + 0000000000000000000000000051000000FE000000FF813336FFFF646AFFFF64 + 6AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF64 + 6AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF64 + 6AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF64 + 6AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF646AFFFF64 + 6AFFFF646AFFFF646AFFBA4A4EFF0A0404FF000000FF000000D7000000500000 + 0082000000FB000000FF3C1819FFF25F65FFFF646AFFFF646AFFFF646AFFFF64 + 6AFF6D2B2DFF000000FF000000C100000047000000470000000A000000000000 + 0000000000000000000B000000E3000000FF4B1F21FFFC696FFFFF6A70FFFF6A + 70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A + 70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A + 70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A + 70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A70FFFF6A + 70FFFF6A70FFFF6A70FFFF6A6FFFB24A4EFF050202FF000000FF000000D40000 + 00FA000000FF371718FFF06369FFFF6A6FFFFF6A6FFFFF6A6FFFFF6A6FFFFF6A + 6FFF6D2D30FF000000FF000000C100000047000000470000000A000000000000 + 00000000000000000073000000FF0C0506FFE26368FFFF7075FFFF7075FFFF70 + 75FFFF7075FFEB676CFF83393BFF582628FF743235FFD95F63FFFF7075FFFF70 + 75FFFF7075FFFF7075FFFF7075FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F + 75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F + 75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F + 75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FF994346FF010000FF000000FF0000 + 00FF331718FFEE686DFFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F + 75FF6D3032FF000000FF000000C100000047000000470000000A000000000000 + 000000000002000000D8000000FF733537FFFF757AFFFF757AFFFF757AFFFF75 + 7AFFDE656AFF1D0D0EFF000000FF000000FF000000FF0B0505FFBC565AFFFF75 + 7AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF75 + 7AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF75 + 7AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF75 + 7AFFFF757AFFFF757AFFFF757AFFFF757AFFFE747AFF5D2B2DFF000000FF3016 + 17FFEB6C71FFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF757AFFFF75 + 7AFF6D3234FF000000FF000000C100000047000000470000000A000000000000 + 000000000025000000FF010000FFD4666AFFFF7B80FFFF7B80FFFF7B80FFFF7B + 80FF532729FF000000FF000000FF000000FF000000FF000000FF211010FFFD7A + 7FFFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B80FFFF7B + 80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFFF7A + 80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFFF7A + 80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFFF7A80FFEE7277FF472324FFE970 + 75FFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A + 7FFF6D3437FF000000FF000000C100000047000000470000000A000000000000 + 00000000004D000000FF120909FFFC7F84FFFF8085FFFF8085FFFF8085FFFC7F + 84FF100808FF000000FF000000FF000000FF000000FF000000FF000000FFD96D + 71FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF80 + 85FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF80 + 85FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF80 + 85FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF80 + 85FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF8085FFFF80 + 85FF6D3739FF000000FF000000C100000047000000470000000A000000000000 + 00000000004A000000FF0F0808FFFA8388FFFF868BFFFF868BFFFF868BFFFE85 + 8AFF160B0CFF000000FF000000FF000000FF000000FF000000FF000000FFE075 + 79FFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF85 + 8AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF85 + 8AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF85 + 8AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF85 + 8AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF85 + 8AFF6D393BFF000000FF000000C100000047000000470000000A000000000000 + 000000000020000000FE000000FFCC6F73FFFF8B90FFFF8B90FFFF8B90FFFF8B + 90FF66383AFF000000FF000000FF000000FF000000FF000000FF341C1DFFFF8B + 90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B90FFFF8B + 90FFFF8B90FFFF8B90FFFF8B90FFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B + 8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B + 8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFEA7F84FF7D4346FFFE8A + 8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B8FFFFF8B + 8FFF6D3B3DFF000000FF000000C100000047000000470000000A000000000000 + 000000000001000000CF000000FF663A3BFFFF9195FFFF9095FFFF9095FFFF90 + 95FFEF878CFF392122FF000000FF000000FF000000FF1F1212FFD6797DFFFF90 + 95FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF90 + 95FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF90 + 95FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF90 + 95FFFF9095FFFF9095FFFF9095FFFF9095FFFE9094FF573132FF000000FF683A + 3CFFFC8F93FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF9095FFFF90 + 95FF6D3E40FF000000FF000000C100000047000000470000000A000000000000 + 00000000000000000067000000FF070404FFD87F82FFFF969BFFFF969BFFFF96 + 9BFFFF969BFFFA9398FFAF686BFF844E51FFA15F62FFF18E92FFFF969BFFFF96 + 9BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969BFFFF969AFFFF96 + 9AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF96 + 9AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF96 + 9AFFFF969AFFFF969AFFFF969AFFFF969AFF96585AFF000000FF000000FF0000 + 00FF663B3DFFFC9499FFFF969AFFFF969AFFFF969AFFFF969AFFFF969AFFFF96 + 9AFF6D4042FF000000FF000000C100000047000000470000000A000000000000 + 00000000000000000006000000D9000000FF3D2526FFFA989CFFFF9CA0FFFF9C + A0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9C + A0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9CA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9B + A0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9B + A0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9B + A0FFFF9BA0FFFF9BA0FFFF9BA0FFB26C6FFF050303FF000000FF000000DA0000 + 00FF000000FF623B3DFFFC999EFFFF9BA0FFFF9BA0FFFF9BA0FFFF9BA0FFFF9B + A0FF6D4244FF000000FF000000C100000047000000470000000A000000000000 + 0000000000000000000000000041000000FB000000FF6D4446FFFEA0A4FFFFA1 + A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1 + A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1 + A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1 + A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1 + A5FFFFA1A5FFFFA1A5FFBA7578FF0A0606FF000000FF000000C80000000D0000 + 0087000000FF000000FF603C3DFFFB9EA2FFFFA1A5FFFFA1A5FFFFA1A5FFFFA1 + A5FF6D4547FF000000FF000000C100000047000000470000000A000000000000 + 000000000000000000000000000000000080000000FF000000FF7E5153FFFFA6 + AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6 + AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6 + AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6 + AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6 + AAFFFFA6AAFFA76C6FFF080505FF000000FF000000D300000014000000000000 + 000100000084000000FF000000FF5D3C3DFFFBA4A8FFFFA6AAFFFFA6AAFFFFA6 + AAFF6D4749FF000000FF000000C100000047000000470000000A000000000000 + 0000000000000000000000000000000000020000009E000000FF000000FF6846 + 47FFF9A8ABFFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFAC + B0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFAC + B0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFAC + B0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFFFACB0FFF8A7 + ABFF754E50FF010101FF000000FF000000CF0000001900000000000000000000 + 00000000000100000081000000FF000000FF593C3DFFFAA8ACFFFFACAFFFFFAC + AFFF6D4A4BFF000000FF000000C100000047000000470000000A000000000000 + 000000000000000000000000000000000000000000050000009C000000FF0000 + 00FF3A2829FFDA989BFFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1 + B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1 + B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1 + B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFFFB1B5FFD09093FF3524 + 25FF000000FF000000FF000000B5000000110000000000000000000000000000 + 000000000000000000010000007F000000FE000000FF573C3DFFF9ADB1FFFFB1 + B5FF6D4C4DFF000000FF000000C100000047000000470000000A000000000000 + 00000000000000000000000000000000000000000000000000020000007A0000 + 00FB000000FF0A0707FF825C5EFFF2AEB1FFFFB7BAFFFFB7BAFFFFB7BAFFFFB7 + BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7 + BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7 + BAFFFFB7BAFFFFB7BAFFFFB7BAFFFFB7BAFFE6A5A8FF6C4D4FFF050404FF0000 + 00FF000000FA0000008000000004000000000000000000000000000000000000 + 00000000000000000000000000000000007B000000FF000000FF543B3DFFFAB3 + B6FF6D4E50FF000000FF000000C100000047000000470000000A000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0040000000DB000000FF000000FF161010FF846062FFE4A8ABFFFFBCC0FFFFBC + C0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBC + C0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBCC0FFFFBC + C0FFFFBCC0FFFFBCC0FFD39B9EFF6C4F50FF0B0808FF000000FF000000FF0000 + 00CF000000380000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000078000000FE000000FF513C + 3DFF664B4DFF000000FF000000BA00000046000000470000000A000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000B00000081000000F1000000FF000000FF060505FF4A3839FF9873 + 74FFDFA9ACFFFDC1C4FFFFC2C5FFFFC2C5FFFFC2C5FFFFC2C5FFFFC2C5FFFFC2 + C5FFFFC2C5FFFFC2C5FFFFC2C5FFFFC2C5FFFFC2C5FFFFC2C5FFFCBFC3FFD3A0 + A3FF886768FF372A2AFF020202FF000000FF000000FF000000E50000006C0000 + 0005000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000076000000FE0000 + 00FF070505FF000000FF000000A80000001D000000460000000A000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000001400000083000000E5000000FF000000FF0000 + 00FF000000FF191313FF4B3A3BFF715859FF907071FFA98486FFB48C8FFFBE94 + 96FFC09598FFB48C8EFFA88385FF8F6F71FF6D5556FF463637FF120E0EFF0000 + 00FF000000FF000000FF000000FF000000D40000006B0000000A000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000720000 + 00FE000000FF000000FF000000A8000000000000001C00000009000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000060000004E0000009F0000 + 00E6000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FF000000FF000000FF0000 + 00FD000000DD0000008E0000003B000000020000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0070000000FD000000FF000000A8000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00040000002A0000005E0000008F000000B0000000CE000000E6000000F00000 + 00F9000000FB000000F0000000E4000000CF000000AC00000089000000580000 + 0020000000010000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000006E000000FE000000A800000000000000000000000000000000F1FF + FFFE0003FFFFF0FFFFF000003FFF907FFFC000000FFF803FFF00000003FF801F + FC00000000FF800FF8000000007F8007F0000000003F8003E0000000001F8001 + C0000000000F8000800000000007800000000000000780000000000000038000 + 0000000000038000000000000003800000000000000180000000000000018000 + 0000000000038000000000000003800000000000000380000000000000078000 + 000000000007800000000000000F800000000000001F800000000000001F8004 + 00000000003F800E00000000007F801F0000000000FF803F8000000001FF807F + C000000003FF80FFF000000007F981FFF80000001FF183FFC00000007FE187FE + 00000001FFC18FF80000001FFF819FE00000001FFF01FFC000000007FE01FF80 + 00000003FC01FF0000000001F801FE0000000000F001FC00000000006001F800 + 000000000001F800000000000001F000000000000001E000000000000001C000 + 000000000001C000000000000001C00000000000000180000000000000018000 + 00000000000180000000000000018000000000000001C000000000000001C000 + 000000000001E000000000000001E000000000000001F000000000018001F800 + 00000003C001FC0000000007E001FE000000001FF001FF000000003FF801FF80 + 000000FFFC01FFE0000001FFFE0BFFFC00000FFFFF0FFFFF80007FFFFF8F2800 + 0000400000008000000001000800000000000012000000000000000000000000 + 00000000000000000000683619006936190069371E006D3B2200733B20006F3C + 2200793C1F00714026007340260072412700734128007C44250077442A007B44 + 270076452B0077462C0078462D008048290079482E007B482E0083492B00834A + 2B00844B2C007C4B31007D4C3200804D3300874E2F00804F35008C5032009451 + 2E00955430008753390086553B0087563C00A8552B00A4572F0089583E008B58 + 3D008A593F008C593E00A35C36009C5B3900A55D3700A55D3800965F3F00A55E + 3800A65E3A00A65F3900975F4200A7603A009960410093604500A7613C00A861 + 3B0092614700A8613B00A8623D00A7623C00A9623C00A8623C00AF623A009562 + 4700A9633E00A8633D00A3634200AA633D00A9633D00A9643E00AA643F00A863 + 4000A9644000AA653F00A964410098654A00AA6641009C654800AB664000AB66 + 42009D654A00AB674200AC674100AB6842009A674C00AC684300AC694300AB68 + 44009F694B009F674C00AD6944009F6A4B00AC694500AD6A44009C694E00AE6A + 4500A16A4C00AD6A46009D6B5000AF6B4600AF6B4800AF6C4800B06C4900A06D + 5200B16D4A00B16F4B00B1704B00B0714C00B1704C00B2704C00B1704C00B170 + 4D00A3705500B2714D00A9725200A6725500A4725500B3724E00B3734E00B372 + 4F00A5725700B4734F00B4755000B5745000B5745100B5765100AA755A00B676 + 5300B6755300B6775200B5785400B6775400B6785500B7785500B5795500B778 + 5500B77A5800AC7A5D00B77B5700AD7B5E00B27C5E00BA7D5900BA7D5B00BA7C + 5B00BB7D5A00BA7E5A00BC7F5D00BB7F5D00BC7E5D00BC805E00B37F6400B280 + 6300BB815E00BD806000BC816000B6816400BC825F00BC816000BE826000BD82 + 6100BD836000BB836100BE836200BE846300B6846700BF856400C0866600C188 + 6800BF886800C1896700C08A6800C0896900C18A6A00C18A6A00BC8A6D00C38A + 6B00C38C6C00C38B6C00C28C6C00C48D6D00C38C6E00C38E6F00C48D6F00C48F + 7000C58E7000C58F7100C28E7300C4907100C5907100C5917100C6917200C591 + 7200C3907300C6917400C6927500C7947500C8947700C9957800C8967800C895 + 7800CA967900C9967900FFFFFF00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000F0F + 23234242424242423A3A3A3A3A3A4242232319190F0F00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000F0F + 23234242424242423A3A3A3A3A3A4242232319190F0F00000000000000000000 + 000000000000000000002121000000000000000000000000191917174E4E4E4E + 424242424242424242423A3A3A3A3A3A42424242424242422323020200000000 + 000000000000000000002121000000000000000000000000191917174E4E4E4E + 424242424242424242423A3A3A3A3A3A42424242424242422323020200000000 + 000000000000000000005D5D3E3E00000000000019191D1D5C5C5C5C42424E4E + 4242424242424242424242424242424242424242424242424E4E424223230202 + 000000000000000000005D5D3E3E00000000000019191D1D5C5C5C5C42424E4E + 4242424242424242424242424242424242424242424242424E4E424223230202 + 00000000000000000000AFAF4F4F2121000019197575676764645C5C5C5C4E4E + 4E4E4E4E4E4E424242424E4E42424242424242424E4E4E4E4E4E42425C5C1414 + 28280000000000000000AFAF4F4F2121000019197575676764645C5C5C5C4E4E + 4E4E4E4E4E4E424242424E4E42424242424242424E4E4E4E4E4E42425C5C1414 + 28280000000000000000B9B9AFAF4F4F34344C4C7F7F7575676767675C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C4E4E0C0C00000000000000001A1A7575 + 7F7F2828000000000000B9B9AFAF4F4F34344C4C7F7F7575676767675C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C4E4E0C0C00000000000000001A1A7575 + 7F7F2828000000000000C1C1C1C1AFAF4F4FA2A28E8E8B8B7F7F757575756767 + 75756767676775757575757567676767757500000F0F5D5D6161020200008585 + 8E8E7171000000000000C1C1C1C1AFAF4F4FA2A28E8E8B8B7F7F757575756767 + 75756767676775757575757567676767757500000F0F5D5D6161020200008585 + 8E8E7171000000000000C7C7C7C7C1C1B9B9AFAFADADA2A2A2A29B9B8E8E8E8E + 8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E00002D2D8E8EA2A20F0F0000ADAD + AFAF3E3E000000000000C7C7C7C7C1C1B9B9AFAFADADA2A2A2A29B9B8E8E8E8E + 8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E8E00002D2D8E8EA2A20F0F0000ADAD + AFAF3E3E000000000000C7C7C7C7ADAD3E3EC1C1C1C1C1C1B9B9AFAFAFAFAFAF + AFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF00007373B9B9C1C17D7D0202C3C3 + C7C70202000000000000C7C7C7C7ADAD3E3EC1C1C1C1C1C1B9B9AFAFAFAFAFAF + AFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF00007373B9B9C1C17D7D0202C3C3 + C7C70202000000000000C7C7C7C7191900000F0FADADC7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C1C1 + 28280000000000000000C7C7C7C7191900000F0FADADC7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C1C1 + 28280000000000000000C7C795950000000000000F0F7373C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C1C195952828 + 00000000000000000000C7C795950000000000000F0F7373C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C1C195952828 + 0000000000000000000095950F0F000000000000000000000F0F3E3E8888C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C79595282800000000 + 0000000000000000000095950F0F000000000000000000000F0F3E3E8888C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C79595282800000000 + 000000000000000000000F0F0000000000000000000000000000000000000000 + 0F0F28282323C1C1C7C7C7C7C7C7C1C19A9A3E3E282800000000000000000000 + 000000000000000000000F0F0000000000000000000000000000000000000000 + 0F0F28282323C1C1C7C7C7C7C7C7C1C19A9A3E3E282800000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000090921215D5D + 29292929292929295D5D28280909000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000090921215D5D + 29292929292929295D5D28280909000000000000000000000000000000000000 + 000000000000000000000000000000000000000002024F4F2F2F29292A2A2A2A + 2929292929292F2F2A2A2A2A292907075D5D0202000000000000000000000000 + 191900000000000000000000000000000000000002024F4F2F2F29292A2A2A2A + 2929292929292F2F2A2A2A2A292907075D5D0202000000000000000000000000 + 1919000000000000000000000000000021215D5D42422A2A2F2F2F2F29292929 + 2929292929292929292929292323232329291E1E111100000000000000001919 + 0505000000000000000000000000000021215D5D42422A2A2F2F2F2F29292929 + 2929292929292929292929292323232329291E1E111100000000000000001919 + 05050000000000000000000028285D5D4E4E4141424242422F2F2F2F29292F2F + 2F2F2929292929292F2F2F2F292929292F2F42421F1F14140000000019192A2A + 5C5C0000000000000000000028285D5D4E4E4141424242422F2F2F2F29292F2F + 2F2F2929292929292F2F2F2F292929292F2F42421F1F14140000000019192A2A + 5C5C00000000000000002828757567675C5C4E4E4E4E424242423A3A42424242 + 3A3A3A3A3A3A3A3A42423A3A3A3A3A3A3A3A2F2F42424242141402020C0C6464 + 676700000000000000002828757567675C5C4E4E4E4E424242423A3A42424242 + 3A3A3A3A3A3A3A3A42423A3A3A3A3A3A3A3A2F2F42424242141402020C0C6464 + 676700000000000028288585757517170909090917175C5C5C5C4E4E5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C64644141737375757F7F + 7F7F00000000000028288585757517170909090917175C5C5C5C4E4E5C5C5C5C + 5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C5C64644141737375757F7F + 7F7F0000000000006F6F9B9B8E8E0909000000000F0F757575757F7F7F7F7F7F + 8585858585858585858585857F7F85857F7F7F7F7F7F7F7F85857F7F7F7F8E8E + 9B9B0000000000006F6F9B9B8E8E0909000000000F0F757575757F7F7F7F7F7F + 8585858585858585858585857F7F85857F7F7F7F7F7F7F7F85857F7F7F7F8E8E + 9B9B0000000000006F6FA5A5A2A211110000000004048E8E8E8E9B9B85858E8E + 9B9B9B9BA2A29B9B9B9BA2A29B9B9B9B9B9BA2A29B9BA2A29B9B9B9BA2A2A2A2 + A2A20000000000006F6FA5A5A2A211110000000004048E8E8E8E9B9B85858E8E + 9B9B9B9BA2A29B9B9B9BA2A29B9B9B9B9B9BA2A29B9BA2A29B9B9B9BA2A2A2A2 + A2A200000000000028288888AFAF5F5F020209095D5DAFAFA8A8AFAFAFAFAFAF + AFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF + AFAF00000000000028288888AFAF5F5F020209095D5DAFAFA8A8AFAFAFAFAFAF + AFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF + AFAF000000000000000028289A9AB9B9B9B9C1C1C1C1C1C1C1C1C1C1C1C1C1C1 + C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C173735D5DC1C1C1C1 + C1C1000000000000000028289A9AB9B9B9B9C1C1C1C1C1C1C1C1C1C1C1C1C1C1 + C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C173735D5DC1C1C1C1 + C1C10000000000000000000028288888C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7191900000909B9B9C7C7 + C7C70000000000000000000028288888C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7191900000909B9B9C7C7 + C7C700000000000000000000000000001A1A8888C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7888819190000000000001A1AC7C7 + C7C700000000000000000000000000001A1A8888C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7888819190000000000001A1AC7C7 + C7C700000000000000000000000000000000000028288888C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7888819190202000000000000000000001A1A + 888800000000000000000000000000000000000028288888C7C7C7C7C7C7C7C7 + C7C7C7C7C7C7C7C7C7C7C7C7C7C7888819190202000000000000000000001A1A + 8888000000000000000000000000000000000000000000000000040421214F4F + 8888C7C7C7C7C7C788884F4F2121040400000000000000000000000000000000 + 1A1A000000000000000000000000000000000000000000000000040421214F4F + 8888C7C7C7C7C7C788884F4F2121040400000000000000000000000000000000 + 1A1A000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000CFFFFF000000FFFFC7FFF80000001FFFC3FFC000000003FFC1FF + 0000000000FFC0FC00000000003FC07800000000001FC03000000000000FC000 + 000000000007C000000000000003C000000000000001C000000000000000C000 + 000000000000C000000000000000C000000000000000C000000000000000C000 + 000000000000C000000000000000C000000000000000C000000000000001C000 + 000000000003C000000000000007C01000000000000FC03800000000001FC03C + 00000000003FC07F0000000000FFC0FFC000000003FFC1FFFC0000001FFFC3FF + FFC00000FFFFC7FFFFFFFFFFFFFFCFFFFFFFFFFFFFFFFFFFF00000FFFFF3FFFF + 8000001FFFE3FFFC00000003FFC3FFF000000001FF83FFC000000000FF03FF00 + 000000007E03FC00000000003C03F800000000000003F000000000000003E000 + 000000000003C000000000000003800000000000000300000000000000030000 + 0000000000030000000000000003000000000000000300000000000000030000 + 000000000003000000000000000300000000000000038000000000000003C000 + 000000000003E000000000000003F000000000000003F800000000000003FC00 + 000000003003FF00000000007803FFC000000000FC03FFF000000001FE03FFFC + 00000003FF03FFFF8000000FFF83FFFFF000003FFFC3FFFFFFFFFFFFFFE3FFFF + FFFFFFFFFFF32800000040000000800000000100040000000000000A00000000 + 0000000000000000000000000000000000000000800000800000008080008000 + 00008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF00 + 0000FF00FF00FFFF0000FFFFFF00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000EEEEEE + EEEEEEE000000000000000000000000000000000000000000000EEEEEEEEEEEE + EEEEEEEEEEEE00000000000000000000E0000000000000000EEEEEEEEEEEEEEE + EEEEEEEEEEEEEEE00000000000000000EE000000000000EEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEE00000000000000EEE0000000000EEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEE000000000000EEEE000000EEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEE0000000000EEEEE0000EEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEE000000000EEEEEE00EEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE00000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEE00000000EEEEEEE0000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEE00000000EEEEEEE0000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEE00EEEEEEEE00EEEEE0000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEE00EEEEEEEE00EEEEEE000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEE00EEEEEEEE00EEEEEE000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEE00EEEEEEEE00EEEEE0000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEE0000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEEE0000000EEEEEE00EEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE00000000EEEEE0000EEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEE000000000EEEE000000EEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEE0000000000EEEE00000000EEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEE000000000000EEE00000000000EEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEE00000000000000EEE000000000000000EEEEEEEEEEEEEE + EEEEEEEEEEEEEEE00000000000000000EE00000000000000000000EEEEEEEEEE + EEEEEEEEEEE000000000000000000000E000000000000000000000000000EEEE + EEEE000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000EEEEEEEEE0 + 000000000000000000000000000000000000000000000000EEEEEEEEEEEEEEEE + EEEE00000000000000000000000000000000000000000EEEEEEEEEEEEEEEEEEE + EEEEEEE0000000000000000E000000000000000000EEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEE000000000000EE0000000000000000EEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEE0000000000EEE00000000000000EEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEE00000000EEEE000000000000EEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEE000000EEEEE0000000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEE0000EEEEEE000000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE00000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE0000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE0000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE000000EEEEEEEE0000EEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE000000EEEEEEEE0000EEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE000000EEEEEEEE0000EEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE000000EEEEEEEE0000EEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE0000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE0000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE00000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE000000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEEEEEEEEEEEE0000000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEEE00EEEEEEEE000000000000EEEEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEEE0000EEEEEEE00000000000000EEEEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEEE000000EEEEEE0000000000000000EEEEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEEE00000000EEEEE000000000000000000EEEEEEEEEEEEEEEEEEEEEE + EEEEEEEEEE0000000000EEEE000000000000000000000EEEEEEEEEEEEEEEEEEE + EEEEEEEE0000000000000EEE000000000000000000000000EEEEEEEEEEEEEEEE + EEEEEE0000000000000000EE0000000000000000000000000000000000000000 + 00000000000000000000000E0000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000CFFFFF000000FFFFC7FFF80000000FFFC3FF + C000000003FFC1FF0000000000FFC0FC00000000003FC07800000000001FC030 + 00000000000FC000000000000007C000000000000003C000000000000001C000 + 000000000000C000000000000000C000000000000000C000000000000000C000 + 000000000000C000000000000000C000000000000000C000000000000000C000 + 000000000001C000000000000003C000000000000007C03000000000000FC038 + 00000000001FC03C00000000003FC07F0000000000FFC0FFC000000003FFC1FF + FC0000001FFFC3FFFFC00000FFFFC7FFFFFFFFFFFFFFCFFFFFFFFFFFFFFFFFFF + F00000FFFFF3FFFF8000001FFFE3FFFC00000003FFC3FFF000000001FF83FFC0 + 00000000FF03FF00000000007E03FC00000000003C03F800000000001803F000 + 000000000003E000000000000003C00000000000000380000000000000030000 + 0000000000030000000000000003000000000000000300000000000000030000 + 0000000000030000000000000003000000000000000300000000000000038000 + 000000000003C000000000000003E000000000000003F000000000000003F800 + 000000000003FC00000000003003FF00000000007803FFC000000000FC03FFF0 + 00000001FE03FFFC00000003FF03FFFF8000000FFF83FFFFF000003FFFC3FFFF + FFFFFFFFFFF3FFFFFFFFFFFFFFF3280000003000000060000000010020000000 + 0000802500000000000000000000000000000000000000000000000000000000 + 00000000003D0000003700000004000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000060000001800000028000000340000 + 003D000000420000004600000046000000430000003E000000360000002B0000 + 001D0000000C0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000280000 + 00000000003D0000004700000036000000030000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000020000001900000034000000460000004700000047000000470000 + 0047000000470000004700000047000000470000004700000047000000470000 + 0047000000470000003E00000025000000090000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000B30000 + 00560000003D0000004700000047000000340000000300000000000000000000 + 0000000000000000000000000000000000000000000000000000000000010000 + 001C0000003F000000470000004700000047000000520000006A0000007A0000 + 0081000000840000007C000000720000005C0000004B00000047000000470000 + 0047000000470000004700000047000000460000002C00000008000000000000 + 0000000000000000000000000000000000000000000000000000000000B80000 + 00F90000007E0000004700000047000000470000003300000002000000000000 + 000000000000000000000000000000000000000000000000000D000000390000 + 0047000000530000008A000000BE000000E7000000FD000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000F7000000D6000000AD0000 + 00770000004B00000047000000470000004700000047000000430000001D0000 + 0000000000000000000000000000000000000000000000000000000000B80000 + 00FF000000FA0000007E00000047000000470000004700000031000000020000 + 0000000000000000000000000000000000000000001D000000450000006A0000 + 00BB000000F9000000FF020101FF290A0BFF5C1719FF7F1F22FF982529FFA428 + 2CFFA8292DFF9D262AFF8D2226FF6E1B1EFF471213FF140505FF000000FF0000 + 00FF000000EC000000A600000057000000470000004700000047000000470000 + 002D000000020000000000000000000000000000000000000000000000B80501 + 02FF140606FF000000F90000007A000000470000004700000047000000300000 + 0001000000000000000000000001000000280000005C000000C1000000FE0000 + 00FF3D1112FF9A2A2EFFE83E44FFFF444BFFFF444BFFFF444BFFFF444BFFFF44 + 4BFFFF444BFFFF444BFFFF444BFFFF444BFFFF444BFFFD444AFFCF383DFF8023 + 26FF21090AFF000000FF000000F6000000A10000004C00000047000000470000 + 0047000000320000000200000000000000000000000000000000000000B80D04 + 04FFCD3C42FF130606FF000000F8000000760000004700000047000000470000 + 002F00000001000000000000002A00000090000000F6010000FF4E1719FFCE3D + 42FFFF4B51FFFF4B51FFFF4B51FFFF4B51FFFF4B51FFFF4B51FFFF4B51FFFF4B + 51FFFF4B51FFFF4B52FFFF4B52FFFF4B52FFFF4B52FFFF4B52FFFF4B52FFFF4B + 52FFFD4B51FFAB3337FF290D0EFF000000FF000000DE00000065000000470000 + 0047000000470000002A00000000000000000000000000000000000000B80D04 + 04FFFE5158FFCB4146FF100506FF000000F70000007300000047000000470000 + 00470000002D00000029000000BC000000FF200A0BFFB83C40FFFF5258FFFF52 + 58FFFF5258FFFF5258FFFF5258FFFF5259FFFF5259FFFF5259FFFF5259FFFF52 + 59FFFF5259FFFF5259FFFF5259FFFF5259FFFF5259FFFF5359FFFF5359FFFF53 + 59FFFF5359FFFF5359FFF95157FF812B2EFF040102FF000000F4000000750000 + 0047000000470000004700000016000000000000000000000000000000B80D05 + 05FFFE585EFFFF595FFFC6464AFF0E0505FF000000F500000070000000470000 + 004700000050000000D0000000FF4F1C1EFFEE5459FFFF595FFFFF595FFFFF59 + 5FFFFF595FFFFF595FFFFF595FFFFF595FFFFF5960FFFF5A60FFFF5A60FFFF5A + 60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFFF5A + 60FFFF5A60FFFF5A60FFFF5A60FFFF5A60FFBB4347FF100606FF000000F70000 + 007100000047000000470000003D000000010000000000000000000000B80D05 + 05FFFE6065FFFF6066FFFF6066FFC24A4EFF0C0505FF000000F30000006D0000 + 004C000000CD000000FF6D2A2CFFFC6065FFFF6166FFFF6166FFFF6166FFFF61 + 67FFFF6167FFFF6167FFFF6167FFFF6167FFFF6167FFFF6167FFFF6167FFFF61 + 67FFFF6167FFFF6167FFFF6167FFFF6167FFFF6167FFFF6167FFFF6167FFFF61 + 67FFFF6167FFFF6167FFFF6167FFFF6167FFFF6167FFC74C51FF0C0505FF0000 + 00ED000000580000004700000047000000150000000000000000000000B80D05 + 06FFFE676CFFFF686DFFFF686DFFFF686DFFBD4D51FF0A0404FF000000F20000 + 00C8000000FF672A2DFFFE676DFFFF686DFFFF686DFFFF686DFFFF686DFFFF68 + 6DFFFF686EFFFF686EFFFF686EFFFF686EFFFF686EFFFF686EFFFF686EFFFF68 + 6EFFFF686EFFFF686EFFFF686EFFFF686EFFFF686EFFFF686EFFFF686EFFFE68 + 6EFFD2565AFFC85156FFFA666CFFFF686EFFFF686EFFFF696EFFA64548FF0000 + 00FF000000C00000004700000047000000270000000000000000000000B80D06 + 06FFFE6E73FFFF6F74FFFF6F74FFFF6F74FFFF6F74FFB85154FF080404FF0000 + 00FF4A2022FFFC6E73FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F + 75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F75FFFF6F + 75FFFF6F75FFFF6F75FFFF7075FFFF7075FFFF7075FFFF7075FFE9666BFF401B + 1DFF000000FF000000FF251011FFD05B5FFFFF7075FFFF7075FFFF7075FF4C22 + 23FF000000FE00000068000000470000002C0000000000000000000000B80D06 + 06FFFE757AFFFF767BFFFF767BFFFF767BFFFF767BFFFF767BFFB45457FF1E0E + 0FFFEB6D72FFFF767BFFFF767BFFFF767BFFFF767BFFFF767BFFFF767BFFFF76 + 7BFFFF767BFFFF767BFFFF767CFFFF767CFFFF767CFFFF767CFFFF767CFFFF76 + 7CFFFF767CFFFF777CFFFF777CFFFF777CFFFF777CFFFA757AFF381A1BFF0100 + 00FF602E30FF78393BFF080404FF1A0C0CFFEA6D72FFFF777CFFFF777CFFC55C + 60FF000000FF000000AB00000047000000210000000000000000000000B80D06 + 07FFFE7C81FFFF7D82FFFF7D82FFFF7D82FFFF7D82FFFF7D82FFFF7D82FFF076 + 7BFFFF7D82FFFF7D82FFFF7D82FFFF7D82FFFF7D82FFFF7D83FFFF7D83FFFF7D + 83FFFF7D83FFFF7E83FFFF7E83FFFF7E83FFFF7E83FFFF7E83FFFF7E83FFFF7E + 83FFFF7E83FFFF7E83FFFF7E83FFFF7E83FFFF7E83FF984B4EFF000000FF7339 + 3BFFFF7E83FFFF7E83FFA15053FF000000FF703739FFFF7E83FFFF7E83FFFD7D + 82FF0E0707FF000000CF000000460000000A0000000000000000000000B80D07 + 07FFFE8388FFFF8489FFFF8489FFFF8489FFFF8489FFFF8489FFFF8489FFFA82 + 87FFFF8489FFFF8489FFFF8589FFFF8589FFFF8589FFFF8589FFFF858AFFFF85 + 8AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFFF85 + 8AFFFF858AFFFF858AFFFF858AFFFF858AFFFF858AFFAA595DFF402223FFF37F + 83FFFF858AFFFF858AFFFE8489FF462526FF814446FFFF858AFFFF858AFFFB83 + 88FF0C0606FF000000CD0000002F000000000000000000000000000000B80D07 + 07FFFE8B90FFFF8C90FFFF8C90FFFF8C90FFFF8C90FFFF8C90FFD77579FF2E19 + 19FFE67E82FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C + 91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C + 91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C91FFFF8C + 91FFFF8C91FFFF8C91FFFF8D91FFFF8C91FFFF8D91FFFF8D91FFFF8D91FFBB67 + 6AFF000000FF000000A000000008000000000000000000000000000000B80D08 + 08FFFE9296FFFF9397FFFF9397FFFF9397FFFF9397FFD57A7EFF190E0FFF0000 + 00FF452728FFFC9196FFFF9398FFFF9398FFFF9398FFFF9398FFFF9398FFFF93 + 98FFFF9398FFFF9398FFFF9398FFFF9398FFFF9398FFFF9398FFFF9398FFFF93 + 98FFFF9398FFFF9498FFFF9498FFFF9498FFFF9498FFFF9498FFFF9498FFFF94 + 98FFFF9498FFFF9498FFFF9498FFFF9498FFFF9498FFFF9498FFFE9398FF3F24 + 26FF000000FB0000002F00000000000000000000000000000000000000B80D08 + 08FFFE999DFFFF9A9EFFFF9A9EFFFF9A9EFFD37F83FF170E0EFF000000F90000 + 00BE000000FF653C3EFFFE9A9EFFFF9A9FFFFF9A9FFFFF9A9FFFFF9A9FFFFF9B + 9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B + 9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B + 9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFFFF9B9FFF955A5DFF0000 + 00FF000000990000000000000000000000000000000000000000000000B80D08 + 08FFFEA0A4FFFFA1A5FFFFA1A5FFD18487FF160D0EFF000000F8000000500000 + 0006000000B7000000FF684143FFFC9FA3FFFFA1A6FFFFA2A6FFFFA2A6FFFFA2 + A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2 + A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2 + A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFFFA2A6FFB97578FF070404FF0000 + 00DD000000100000000000000000000000000000000000000000000000B80D09 + 09FFFEA7ABFFFFA8ACFFD0898CFF140D0EFF000000F80000004E000000000000 + 00000000000B000000BB000000FF492F31FFEB9B9FFFFFA9ADFFFFA9ADFFFFA9 + ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9 + ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9 + ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFAA7073FF090606FF000000ED0000 + 002D000000000000000000000000000000000000000000000000000000B80D09 + 09FFFEAFB2FFCD8D90FF140D0EFF000000F70000004B00000000000000000000 + 000000000000000000070000009C000000FF1A1212FFAC7679FFFEB0B3FFFFB0 + B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB0 + B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB0B4FFFFB1 + B4FFFFB1B4FFFFB1B4FFF2A7ABFF6D4B4DFF020101FF000000E7000000320000 + 0000000000000000000000000000000000000000000000000000000000B80D09 + 0AFFCA9093FF130D0DFF000000F6000000490000000000000000000000000000 + 00000000000000000000000000010000005D000000EE000000FF3F2D2EFFBD87 + 8AFFFDB6BAFFFFB7BBFFFFB7BBFFFFB7BBFFFFB7BBFFFFB7BBFFFFB8BBFFFFB8 + BBFFFFB8BBFFFFB8BBFFFFB8BBFFFFB8BBFFFFB8BBFFFFB8BBFFFFB8BBFFFFB8 + BBFFF6B2B5FF986C6FFF1D1415FF000000FF000000C10000001D000000000000 + 0000000000000000000000000000000000070000000000000000000000B80503 + 03FF110C0DFF000000F600000047000000000000000000000000000000000000 + 000000000000000000000000000000000000000000170000009B000000FA0000 + 00FF2A1F1FFF846163FFD29C9FFFFCBCC0FFFFBFC2FFFFBFC2FFFFBFC2FFFFBF + C2FFFFBFC2FFFFBFC2FFFFBFC2FFFFBFC2FFFFBFC2FFF6B8BBFFBB8B8EFF6C50 + 51FF140F0FFF000000FF000000E9000000690000000300000000000000000000 + 00000000000000000000000000190000002A0000000000000000000000B80000 + 00FF000000F50000004400000000000000000000000000000000000000000000 + 000000000000000000000000000D00000022000000320000003F0000005F0000 + 00AD000000F2000000FF000000FF110D0DFF403132FF634C4EFF7D6062FF896A + 6BFF8D6D6FFF846667FF755A5BFF574344FF312626FF060505FF000000FF0000 + 00FF000000D6000000700000000C000000000000000000000000000000000000 + 00000000000000000017000000460000002B0000000000000000000000B80000 + 00F4000000420000000000000000000000000000000000000000000000000000 + 0004000000210000003D00000047000000470000004700000047000000470000 + 00470000004B00000079000000AB000000D5000000F3000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FD000000E3000000B2000000780000 + 002E000000000000000000000000000000000000000000000000000000000000 + 0000000000160000007F000000470000002B0000000000000000000000AB0000 + 003F000000000000000000000000000000000000000000000001000000200000 + 004200000047000000470000004F0000006F000000880000009E000000A80000 + 00B0000000AE000000A6000000970000007E0000005F00000056000000660000 + 006E000000710000006B000000610000004A0000002400000003000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0015000000A6000000D0000000470000002B0000000000000000000000160000 + 0000000000000000000000000000000000000000000B00000039000000470000 + 0063000000A1000000D7000000FA000000FF000000FF000000FF000000FF0000 + 00FF000000FF000000FF000000FF000000FF000000FE000000EB000000B80000 + 007B0000004A000000470000004700000047000000470000003D000000100000 + 0000000000000000000000000000000000000000000000000000000000130000 + 00A1000000FF000000D0000000470000002B0000000000000000000000000000 + 0000000000000000000000000000000000120000004300000078000000D00000 + 00FE000000FF110405FF4E1416FF832125FFAA2B2FFFC93237FFDB363CFFE539 + 3FFFE2383EFFD6353BFFBD2F34FF9A272BFF681A1DFF2A0B0CFF010000FF0000 + 00FF000000E7000000980000004E000000470000004700000047000000460000 + 001F0000000000000000000000000000000000000000000000120000009C0000 + 00FF000000FF000000D0000000470000002B0000000000000000000000000000 + 00000000000000000000000000110000005C000000CA000000FF060202FF5919 + 1CFFBB3439FFF9454BFFFF464DFFFF464DFFFF464DFFFF464DFFFF464DFFFF46 + 4DFFFF464DFFFF464DFFFF464DFFFF464DFFFF464DFFFF464DFFD83C41FF7D23 + 26FF180707FF000000FF000000EA000000830000004700000047000000470000 + 0047000000280000000000000000000000000000001000000097000000FF300E + 0FFF0C0304FF000000D0000000470000002B0000000000000000000000000000 + 000000000000000000080000007D000000F4010000FF5D1D1FFFDF444AFFFF4E + 54FFFF4E54FFFF4E54FFFF4E54FFFF4E54FFFF4E54FFFF4E54FFFF4E54FFFF4E + 54FFFF4E54FFFF4E54FFFF4E54FFFF4E54FFFF4E54FFFF4E54FFFF4E54FFFF4E + 54FFF64B51FF8E2C30FF110506FF000000FF000000C000000052000000470000 + 00470000004700000027000000000000000F00000092000000FE2C0E0FFFEA47 + 4DFF120506FF000000D0000000470000002B0000000000000000000000000000 + 00000000000000000081000000FE180809FFB93E43FFFF555BFFFF555BFFFF55 + 5BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF55 + 5BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF555BFFFF55 + 5BFFFF555BFFFF555BFFE94E53FF521C1EFF000000FF000000E2000000610000 + 00470000004700000047000000280000008D000000FE290E0FFFE84D53FFFF55 + 5BFF120606FF000000D0000000470000002B0000000000000000000000000000 + 00000000005F000000FE290F10FFE15257FFFF5C62FFFF5C62FFFF5C62FFFF5C + 62FFFF5C62FFFF5C62FFFF5C62FFFF5C62FFFF5C62FFFF5C62FFFF5C62FFFF5C + 62FFFF5C62FFFF5C62FFFF5C62FFFF5C62FFFF5C62FFFF5C62FFFF5C62FFFF5C + 62FFFF5C62FFFF5C62FFFF5C62FFFE5C62FF8F3438FF040102FF000000ED0000 + 006500000047000000470000008E000000FD250E0FFFE45358FFFF5C62FFFF5C + 62FF120707FF000000D0000000470000002B0000000000000000000000000000 + 002D000000F61F0C0DFFE55A5FFFFF6469FFFF6469FFFF6469FFFF6469FFFF64 + 69FFFF6469FFFF6469FFFF6469FFFF6469FFFF6469FFFF6469FFFF6469FFFF63 + 69FFFF6369FFFF6369FFFF6369FFFF6369FFFF6369FFFF6369FFFF6369FFFF63 + 69FFFF6369FFFF6369FFFF6369FFFF6369FFFF6369FFAC4347FF060202FF0000 + 00EA0000005D0000008A000000FD220D0EFFE1585DFFFF6369FFFF6369FFFF63 + 69FF120707FF000000D0000000470000002B0000000000000000000000010000 + 00C3040202FFC75458FFFF6B71FFFF6B71FFFF6B71FFFF6B70FFFA696EFFFF6B + 70FFFF6B71FFFF6B71FFFF6B71FFFF6B71FFFF6B71FFFF6B71FFFF6B71FFFF6B + 71FFFF6B71FFFF6B71FFFF6B71FFFF6B71FFFF6B71FFFF6B70FFFF6B70FFFF6B + 70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFFF6B70FFA44549FF0301 + 01FF000000E7000000FC1F0D0EFFDE5D62FFFF6B70FFFF6B70FFFF6B70FFFF6B + 70FF120808FF000000D0000000470000002B00000000000000000000003F0000 + 00FF672F31FFFF7278FFFF7278FFFF7278FFCA5A5EFF311516FF090404FF3B1A + 1BFFD86065FFFF7278FFFF7278FFFF7278FFFF7278FFFF7278FFFF7278FFFF72 + 78FFFF7278FFFF7278FFFF7278FFFF7278FFFF7278FFFF7278FFFF7278FFFF72 + 78FFFF7278FFFF7278FFFF7278FFFF7278FFFF7277FFFF7277FFFF7277FF7D38 + 3BFF000000FF1B0C0DFFDB6267FFFF7277FFFF7277FFFF7277FFFF7277FFFF72 + 77FF120808FF000000D0000000470000002B0000000000000000000000940000 + 00FFD46569FFFF7A7FFFFF7A7FFFF6757AFF180B0CFF000000FF000000FF0000 + 00FF2A1314FFFE797EFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A + 7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A7FFFFF7A + 7FFFFF797FFFFF797FFFFF797FFFFF797FFFFF797FFFFF797FFFFF797FFFFB78 + 7DFF4F2628FFD8676BFFFF797FFFFF797FFFFF797FFFFF797FFFFF797FFFFF79 + 7FFF120909FF000000D0000000470000002B0000000000000000000000BA0E07 + 07FFFD8085FFFF8186FFFF8186FFC86569FF000000FF000000FF000000FF0000 + 00FF000000FFE17276FFFF8186FFFF8186FFFF8186FFFF8186FFFF8186FFFF81 + 86FFFF8186FFFF8186FFFF8186FFFF8186FFFF8186FFFF8186FFFF8186FFFF81 + 86FFFF8186FFFF8186FFFF8186FFFF8186FFFF8186FFFF8186FFFF8186FFFF81 + 86FFFF8186FFFF8186FFFF8186FFFF8186FFFF8186FFFF8085FFFF8085FFFF80 + 85FF12090AFF000000D0000000470000002B0000000000000000000000A90502 + 03FFEF7F84FFFF888DFFFF888DFFE47A7EFF040202FF000000FF000000FF0000 + 00FF0B0606FFF58388FFFF888DFFFF888DFFFF888DFFFF888DFFFF888DFFFF88 + 8DFFFF888DFFFF888DFFFF888DFFFF888DFFFF888DFFFF888DFFFF888DFFFF88 + 8DFFFF888DFFFF888DFFFF888DFFFF888DFFFF888DFFFF888DFFFF888DFFFF88 + 8DFFDF777BFFFF888DFFFF888DFFFF888DFFFF888DFFFF888DFFFF888DFFFF88 + 8DFF120A0AFF000000D0000000470000002B0000000000000000000000670000 + 00FF9A5659FFFF9094FFFF9094FFFF9094FF81494BFF010101FF000000FF0302 + 02FF985659FFFF9094FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F + 94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F + 94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFCF74 + 78FF0B0606FFA85E61FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F94FFFF8F + 94FF120A0BFF000000D0000000470000002B00000000000000000000000F0000 + 00ED1F1213FFF39094FFFF979BFFFF979BFFFF979BFFD07B7FFFA46265FFD880 + 84FFFF979BFFFF979BFFFF979BFFFF979BFFFF979BFFFF979BFFFF979BFFFF97 + 9BFFFF979BFFFF979BFFFF979BFFFF979BFFFF979BFFFF979BFFFF979BFFFF97 + 9BFFFF979BFFFF979BFFFF979BFFFF979BFFFF979BFFFF979BFFEE8C91FF2717 + 17FF000000FF040203FFA56164FFFF979BFFFF979BFFFF979BFFFF979BFFFF97 + 9BFF120B0BFF000000D0000000470000002B0000000000000000000000000000 + 006D000000FF613B3DFFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9E + A2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9E + A2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9E + A2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFFF9EA2FFF4979BFF3B2425FF0000 + 00FF0000008A000000E2040202FFA26467FFFF9EA2FFFF9EA2FFFF9EA2FFFF9E + A2FF120B0CFF000000D0000000470000002B0000000000000000000000000000 + 0003000000B5000000FF7D5052FFFFA5A9FFFFA6AAFFFFA6AAFFFFA6AAFFFFA6 + AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6 + AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6AAFFFFA6 + AAFFFFA6AAFFFFA5A9FFFFA5A9FFFFA5A9FFEB989CFF3B2627FF000000FF0000 + 008B0000000000000023000000E1030202FF9F6769FFFFA5A9FFFFA5A9FFFFA5 + A9FF120C0CFF000000D0000000470000002B0000000000000000000000000000 + 00000000000F000000CB000000FF684647FFF8A8ACFFFFADB1FFFFADB1FFFFAD + B1FFFFADB1FFFFADB1FFFFADB1FFFFADB1FFFFADB1FFFFADB1FFFFADB1FFFFAD + B1FFFFADB1FFFFADB1FFFFADB1FFFFADB1FFFFADB1FFFFADB1FFFFACB0FFFFAC + B0FFFFACB0FFFFACB0FFFFACB0FFC78689FF211616FF000000FF0000008A0000 + 0001000000000000000000000021000000DF020202FF9C696BFFFFACB0FFFFAC + B0FF120C0DFF000000D0000000470000002B0000000000000000000000000000 + 0000000000000000000F000000BC000000FF322324FFCA8E91FFFFB4B8FFFFB4 + B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4 + B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4B8FFFFB4 + B8FFFFB4B8FFF0A9ADFF735052FF040303FF000000F600000065000000000000 + 000000000000000000000000000000000020000000DD020102FF996B6DFFFFB4 + B7FF120D0DFF000000D0000000470000002B0000000000000000000000000000 + 000000000000000000000000000400000083000000F9030202FF563F40FFC993 + 96FFFEBBBEFFFFBBBFFFFFBBBFFFFFBBBFFFFFBBBFFFFFBBBFFFFFBBBFFFFFBB + BFFFFFBBBFFFFFBBBFFFFFBBBFFFFFBBBFFFFFBBBFFFFFBBBFFFFFBBBFFFE6A9 + ACFF825E60FF130E0EFF000000FF000000C90000002D00000000000000000000 + 0000000000000000000000000000000000000000001E000000DB020101FF966E + 70FF120D0EFF000000CD000000470000002B0000000000000000000000000000 + 0000000000000000000000000000000000000000002D000000B4000000FE0000 + 00FF2D2222FF7B5D5FFFBD9092FFEEB6B8FFFEC2C6FFFFC3C6FFFFC3C6FFFFC3 + C6FFFFC3C6FFFFC3C6FFFFC3C6FFFABFC2FFD19FA2FF957173FF483637FF0705 + 05FF000000FF000000DD00000061000000030000000000000000000000000000 + 000000000000000000000000000000000000000000000000001D000000DA0201 + 01FF020202FF000000BE0000001E0000002A0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000310000 + 0095000000EA000000FF000000FF030202FF191414FF372B2BFF463738FF503E + 3FFF4C3B3CFF403233FF271F1FFF0A0808FF000000FF000000FF000000F80000 + 00B6000000530000000500000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000001B0000 + 00D9000000FF000000BE00000000000000090000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000030000003900000072000000A5000000C8000000E4000000F30000 + 00FC000000F8000000EC000000D6000000B4000000890000004F000000100000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 001A000000D7000000BE000000000000000000000000E7FFFE000FFF0000A3FF + F00003FF000081FFC00000FF000080FF0000003F0000807E0000001F0000803C + 0000000F00008018000000070000800000000003000080000000000300008000 + 0000000100008000000000010000800000000001000080000000000100008000 + 0000000100008000000000030000800000000007000080000000000700008000 + 0000000F000080200000000F000080600000001F000080F80000003F000081FC + 0000007F000083FE000001F9000087F8000003F100008FE000001FE100009F80 + 0000FFC10000BE0000003F810000FC0000001F010000F80000000E010000F800 + 000004010000F000000000010000E000000000010000C000000000010000C000 + 0000000100008000000000010000800000000001000080000000000100008000 + 00000001000080000000000100008000000000010000C000000000010000E000 + 000010010000E000000038010000F00000007C010000FC000000FE010000FE00 + 0003FF010000FF80000FFF870000FFF0003FFFC7000028000000200000004000 + 0000010020000000000080100000000000000000000000000000000000000000 + 000000000000000000400000001B000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000F000000250000 + 00340000003F0000004400000046000000440000003D00000032000000230000 + 000E000000000000000000000000000000000000000000000000000000000000 + 00240000006300000040000000460000001A0000000000000000000000000000 + 0000000000000000000000000000000000190000003B000000470000004C0000 + 00610000006D0000006E00000065000000520000004700000047000000470000 + 0047000000390000001700000000000000000000000000000000000000000000 + 0025000000FC0000008A00000047000000460000001800000000000000000000 + 000000000000000000090000003600000065000000A7000000DB000000FB0802 + 02FF170506FF190607FF0D0303FF000000FE000000EA000000BF000000850000 + 004C000000470000004700000033000000060000000000000000000000000000 + 0025020101FF090203FD00000087000000470000004600000017000000000000 + 00000000001200000061000000C9080202FE58181AFFA62C31FFDF3A40FFFC41 + 48FFFF4249FFFF4249FFFE4249FFED3E44FFBF3337FF7D2225FF260A0BFF0000 + 00ED0000009400000049000000470000003D0000000800000000000000000000 + 0025090303FFB7373CFF080203FC000000830000004700000045000000150000 + 00130000009C050202FB712326FFE9474CFFFF4D53FFFF4D53FFFF4D53FFFF4D + 53FFFF4D53FFFF4D53FFFF4D53FFFF4D53FFFF4D53FFFF4D53FFFE4D53FFB137 + 3BFF260C0DFF000000D400000059000000470000003A00000002000000000000 + 0025090303FFFE575DFFB33E42FF060202FB0000007F00000047000000490000 + 00BC230D0DFFCC474CFFFF585EFFFF585EFFFF585EFFFF585EFFFF585EFFFF58 + 5EFFFF585EFFFF585EFFFF585EFFFF585EFFFF585EFFFF585EFFFF585EFFFF58 + 5EFFF5555BFF5C2123FF000000E60000005A0000004700000023000000000000 + 0025090304FFFE6267FFFF6268FFAE4347FF050202FA0000007D000000BE3113 + 15FFEA5B60FFFF6268FFFF6268FFFF6268FFFF6368FFFF6368FFFF6368FFFF63 + 68FFFF6368FFFF6369FFFF6369FFFF6369FFFF6369FFFF6369FFFF6369FFFF63 + 69FFFF6369FFFE6268FF5D2527FF000000D40000004900000040000000000000 + 0025090404FFFE6C72FFFF6D73FFFF6D73FFA8494CFF040202FD210E0FFFE964 + 69FFFF6D73FFFF6D73FFFF6D73FFFF6D73FFFF6D73FFFF6D73FFFF6D73FFFF6D + 73FFFF6D73FFFF6D73FFFF6E73FFFF6E73FFFF6E73FFD35A5FFF471D1FFF3C19 + 1AFFC05256FFFF6E73FFF66A6FFF220F10FF0000008B00000047000000050000 + 0025090404FFFE777CFFFF787DFFFF787DFFFF787DFFA34E51FFC65D61FFFF78 + 7DFFFF787DFFFF787DFFFF787DFFFF787DFFFF787DFFFF787DFFFF787DFFFF78 + 7EFFFF787EFFFF787EFFFF787EFFFF787EFFED7075FF190B0CFF73373AFF8A42 + 45FF0D0606FFDD686DFFFF797EFF914548FF000000CE00000041000000010000 + 0025090405FFFE8287FFFF8387FFFF8387FFFF8388FFFF8287FFFD8287FFFF83 + 88FFFF8388FFFF8388FFFF8388FFFF8388FFFF8388FFFF8388FFFF8388FFFF83 + 88FFFF8388FFFF8388FFFF8388FFFF8388FFBB6165FF572E2FFFFF8388FFFF83 + 88FF683638FFA05356FFFF8488FFB25C5FFF000000DF00000025000000000000 + 0025090505FFFE8D92FFFF8D92FFFF8D92FFFE8D92FF764143FF884B4EFFFF8E + 92FFFF8E92FFFF8E92FFFF8E92FFFF8E92FFFF8E93FFFF8E93FFFF8E93FFFF8E + 93FFFF8E93FFFF8E93FFFF8E93FFFF8E93FFFF8E93FFFF8E93FFFF8E93FFFF8E + 93FFFF8E93FFFF8E93FFFF8E93FF693A3CFF000000AE00000003000000000000 + 0025090505FFFE989CFFFF989DFFFE989CFF734446FF000000E6050303F9B96E + 71FFFF989DFFFF989DFFFF999DFFFF999DFFFF999DFFFF999DFFFF999DFFFF99 + 9DFFFF999DFFFF999DFFFF999DFFFF999DFFFF999DFFFF999DFFFF999DFFFF99 + 9EFFFF999EFFFF999EFFD07C80FF060404FB0000002E00000000000000000000 + 0025090606FFFEA2A7FFFEA3A7FF704748FF000000E100000024000000590A06 + 07FCB27174FFFFA3A7FFFFA3A7FFFFA3A8FFFFA3A8FFFFA4A8FFFFA4A8FFFFA4 + A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4 + A8FFFFA4A8FFDF8F92FF201414FF0000007C0000000000000000000000000000 + 0025090606FFFDACB0FF6D494BFF000000E00000002200000000000000000000 + 0054030202F4754F51FFF5A7ABFFFFAEB2FFFFAEB2FFFFAEB2FFFFAEB2FFFFAE + B2FFFFAEB2FFFFAEB2FFFFAFB2FFFFAFB2FFFFAFB2FFFFAFB3FFFFAFB3FFFFAF + B3FFB87D80FF181011FF00000091000000010000000000000000000000000000 + 0025080606FF694B4DFF000000DE000000200000000000000000000000000000 + 00000000002A000000C61C1414FF906769FFEDACAFFFFFB9BDFFFFB9BDFFFFB9 + BDFFFFB9BDFFFFB9BDFFFFB9BDFFFFB9BDFFFFB9BDFFFEB9BCFFC28C8FFF4F39 + 3AFF010101F0000000640000000000000000000000000000000B000000030000 + 0025000000FF000000DD0000001F000000000000000000000000000000000000 + 000200000013000000250000007D000000D5060405FF413132FF785B5CFF9C77 + 79FFAF8587FFB2888AFFA67E81FF8A696AFF5C4547FF1C1515FF000000ED0000 + 008C000000180000000000000000000000000000000A00000040000000050000 + 0025000000DB0000001D00000000000000000000000000000008000000280000 + 004200000047000000470000004B000000500000006300000091000000B60000 + 00CE000000DA000000DD000000D5000000B90000007F00000044000000060000 + 00000000000000000000000000000000000A0000008300000047000000050000 + 00140000001C0000000000000000000000000000001E00000046000000790000 + 00AF000000D6000000F1000000FE000000FF000000FE000000F2000000D60000 + 00AC000000740000004800000047000000470000003200000007000000000000 + 00000000000000000000000000080000009B000000E000000047000000050000 + 00000000000000000000000000010000002F00000095000000EA1B0708FF691C + 1FFFA42B2FFFCC353AFFE53B40FFEE3D43FFE63B41FFCE353AFFA32B2FFF641B + 1DFF150606FF000000E30000008B000000480000004700000041000000110000 + 0000000000000000000800000096020101FF000000E000000047000000050000 + 0000000000000000000000000042000000DB2A0D0EFFAD3439FFFB4B51FFFF4C + 52FFFF4C52FFFF4C52FFFF4C52FFFF4C52FFFF4C52FFFF4C52FFFF4C52FFFF4C + 52FFF84A50FF9F3034FF200A0BFF000000D40000006000000047000000440000 + 00110000000700000090140607FF89292CFF000000E000000047000000050000 + 00000000000000000034000000F072282AFFF9555BFFFF575DFFFF575DFFFF57 + 5DFFFF575DFFFF575DFFFF575DFFFF575DFFFF575DFFFF575DFFFF575DFFFF57 + 5DFFFF575DFFFF575DFFF55359FF6C2628FF010000F200000074000000470000 + 00430000008B110607FFCE464BFFB63E42FF000000E000000047000000050000 + 000000000014000000E3853437FFFF6267FFFF6267FFFF6267FFFF6267FFFF62 + 67FFFF6267FFFF6267FFFF6267FFFF6267FFFF6267FFFF6267FFFF6267FFFF62 + 67FFFF6267FFFF6267FFFF6267FFFF6267FF9A3C3FFF030101F7000000710000 + 00930F0606FEC94E52FFFF6167FFB6464AFF000000E000000047000000050000 + 0000000000984E2224FFFE6D72FFFF6D72FFDB5D62FFB34B4FFFF6696EFFFF6D + 72FFFF6D72FFFF6D72FFFF6D72FFFF6D72FFFF6D72FFFF6D72FFFF6D72FFFF6D + 72FFFF6D72FFFF6D72FFFF6D72FFFF6D72FFFF6D72FF944043FF000000F40D06 + 06FEC55459FFFF6C72FFFF6C72FFB64D51FF000000E000000047000000050000 + 000A000000F5D16367FFFF787DFFCC5F63FF070303FF000000FF3A1B1CFFFF78 + 7DFFFF787DFFFF787DFFFF787DFFFF787DFFFF787DFFFF787DFFFF787DFFFF78 + 7DFFFF787DFFFF787DFFFF787DFFFF787DFFFF787DFFFF777DFF653032FFC15B + 5FFFFF787DFFFF787DFFFF787DFFB65559FF000000E000000047000000050000 + 0026080404FFFD8287FFFF8388FF884648FF000000FF000000FF000000FFEE7A + 7EFFFF8388FFFF8388FFFF8388FFFF8387FFFF8387FFFF8387FFFF8387FFFF83 + 87FFFF8287FFFF8287FFFF8287FFFF8287FFFF8287FFFF8287FFFF8287FFFF82 + 87FFFF8287FFFF8287FFFF8287FFB65D61FF000000E000000047000000050000 + 0008000000F3CC7175FFFF8E92FFD5777BFF0E0808FF000000FF4A2A2BFFFF8E + 92FFFF8E92FFFF8E92FFFF8E92FFFF8E92FFFF8E92FFFF8E92FFFF8E92FFFF8E + 92FFFF8E92FFFF8D92FFFF8D92FFFF8D92FFFF8D92FFFF8D92FF703D3FFFD877 + 7BFFFF8D92FFFF8D92FFFF8D92FFB66568FF000000E000000047000000050000 + 000000000091472A2BFFFE989CFFFF999DFFEA8C90FFC9797DFFFC979BFFFF99 + 9DFFFF999DFFFF999DFFFF999DFFFF999DFFFF999DFFFF999DFFFF999DFFFF99 + 9DFFFF999DFFFF999DFFFF999DFFFF989DFFFF989DFF93575AFF000000F6190F + 0FFFD68083FFFF989DFFFF989DFFB66D70FF000000E000000047000000050000 + 000000000010000000DE7A4E50FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4 + A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA4 + A8FFFFA4A8FFFFA4A8FFFFA4A8FFFFA3A8FF9A6264FF030202F40000003A0000 + 0083180F0FFFD5888BFFFFA3A8FFB67578FF000000E000000047000000050000 + 00000000000000000029000000E6674547FFF6A8ACFFFFAFB2FFFFAFB2FFFFAF + B2FFFFAFB2FFFFAFB2FFFFAFB2FFFFAFB2FFFFAFB2FFFFAFB2FFFFAEB2FFFFAE + B2FFFFAEB2FFFFAEB2FFF3A6AAFF694648FF000000ED0000003E000000000000 + 000000000080160F0FFFD28F92FFB67D7FFF000000E000000047000000050000 + 000000000000000000000000001F000000C5231919FFA37577FFF8B4B8FFFFBA + BDFFFFBABDFFFFBABDFFFFBABDFFFFBABDFFFFBABDFFFFBABDFFFFB9BDFFFFB9 + BDFFF4B1B5FF976D6FFF1C1415FF000000C00000002100000000000000000000 + 0000000000000000007D150F0FFF886264FF000000DE00000047000000050000 + 00000000000000000000000000000000000300000062000000D9140F0FFF5E47 + 48FF987476FFC09395FFD7A5A8FFDFABAEFFD7A5A7FFBF9294FF957173FF5742 + 43FF0E0B0BFF000000CF00000057000000010000000000000000000000000000 + 000000000000000000000000007A020101FF000000D400000020000000050000 + 00000000000000000000000000000000000000000000000000010000003B0000 + 0085000000BB000000DF000000F5000000FD000000F4000000DE000000B80000 + 007F000000320000000100000000000000000000000000000000000000000000 + 000000000000000000000000000000000077000000D30000000000000000CFFC + 007F07F0001F03E0000F01800007000000030000000100000001000000010000 + 0001000000010000000300000003000000070300000F0780001D0F8000391E00 + 01F1380003F1F00000E1E0000041C00000018000000180000001000000010000 + 0001800000018000000180000001C0000181E00003C1F8000FE1FE003FF32800 + 0000200000004000000001000800000000008004000000000000000000000000 + 00000000000000000000683619006936190069371E006D3B2200733B20006F3C + 2200793C1F00714026007340260072412700734128007C44250077442A007B44 + 270076452B0077462C0078462D008048290079482E007B482E0083492B00834A + 2B00844B2C007C4B31007D4C3200804D3300874E2F00804F35008C5032009451 + 2E00955430008753390086553B0087563C00A8552B00A4572F0089583E008B58 + 3D008A593F008C593E00A35C36009C5B3900A55D3700A55D3800965F3F00A55E + 3800A65E3A00A65F3900975F4200A7603A009960410093604500A7613C00A861 + 3B0092614700A8613B00A8623D00A7623C00A9623C00A8623C00AF623A009562 + 4700A9633E00A8633D00A3634200AA633D00A9633D00A9643E00AA643F00A863 + 4000A9644000AA653F00A964410098654A00AA6641009C654800AB664000AB66 + 42009D654A00AB674200AC674100AB6842009A674C00AC684300AC694300AB68 + 44009F694B009F674C00AD6944009F6A4B00AC694500AD6A44009C694E00AE6A + 4500A16A4C00AD6A46009D6B5000AF6B4600AF6B4800AF6C4800B06C4900A06D + 5200B16D4A00B16F4B00B1704B00B0714C00B1704C00B2704C00B1704C00B170 + 4D00A3705500B2714D00A9725200A6725500A4725500B3724E00B3734E00B372 + 4F00A5725700B4734F00B4755000B5745000B5745100B5765100AA755A00B676 + 5300B6755300B6775200B5785400B6775400B6785500B7785500B5795500B778 + 5500B77A5800AC7A5D00B77B5700AD7B5E00B27C5E00BA7D5900BA7D5B00BA7C + 5B00BB7D5A00BA7E5A00BC7F5D00BB7F5D00BC7E5D00BC805E00B37F6400B280 + 6300BB815E00BD806000BC816000B6816400BC825F00BC816000BE826000BD82 + 6100BD836000BB836100BE836200BE846300B6846700BF856400C0866600C188 + 6800BF886800C1896700C08A6800C0896900C18A6A00C18A6A00BC8A6D00C38A + 6B00C38C6C00C38B6C00C28C6C00C48D6D00C38C6E00C38E6F00C48D6F00C48F + 7000C58E7000C58F7100C28E7300C4907100C5907100C5917100C6917200C591 + 7200C3907300C6917400C6927500C7947500C8947700C9957800C8967800C895 + 7800CA967900C9967900FFFFFF00000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000F234242423A3A3A4223190F0000 + 00000000000000002100000000000019174E4E42424242423A3A3A4242424223 + 02000000000000005D3E000000191D5C5C424E4242424242424242424242424E + 4223020000000000AF4F2100197567645C5C4E4E4E4E42424E424242424E4E4E + 425C142800000000B9AF4F344C7F7567675C5C5C5C5C5C5C5C5C5C4E0C000000 + 001A757F28000000C1C1AF4FA28E8B7F757567756767757575676775000F5D61 + 0200858E71000000C7C7C1B9AFADA2A29B8E8E8E8E8E8E8E8E8E8E8E002D8EA2 + 0F00ADAF3E000000C7C7AD3EC1C1C1B9AFAFAFAFAFAFAFAFAFAFAFAF0073B9C1 + 7D02C3C702000000C7C719000FADC7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C7C7C12800000000C7950000000F73C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7 + C195280000000000950F00000000000F3E88C7C7C7C7C7C7C7C7C7C7C7C7C795 + 28000000000000000F000000000000000000000F2823C1C7C7C7C19A3E280000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000009215D292929295D2809000000000000 + 00000000000000000000000000024F2F292A2A2929292F2A2A29075D02000000 + 0000001900000000000000215D422A2F2F29292929292929292323291E110000 + 000019050000000000285D4E4142422F2F292F2F2929292F2F29292F421F1400 + 00192A5C000000002875675C4E4E42423A42423A3A3A3A423A3A3A3A2F424214 + 020C6467000000288575170909175C5C4E5C5C5C5C5C5C5C5C5C5C5C5C5C6441 + 73757F7F0000006F9B8E0900000F75757F7F7F8585858585857F857F7F7F7F85 + 7F7F8E9B0000006FA5A2110000048E8E9B858E9B9BA29B9BA29B9B9BA29BA29B + 9BA2A2A20000002888AF5F02095DAFA8AFAFAFAFAFAFAFAFAFAFAFAFAFAFAFAF + AFAFAFAF00000000289AB9B9C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C173 + 5DC1C1C100000000002888C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C7C71900 + 09B9C7C7000000000000001A88C7C7C7C7C7C7C7C7C7C7C7C7C7C7C788190000 + 001AC7C70000000000000000002888C7C7C7C7C7C7C7C7C7C7C7881902000000 + 00001A8800000000000000000000000004214F88C7C7C7884F21040000000000 + 0000001A00000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000BFF000FF9F80001F8E0000078400000380000001800000008000 + 000080000000800000008000000184000003860000078F80001F9FF800FFBFFF + FFFFFFC00FFDFE0001F9F80000F1E0000061C000000180000001000000010000 + 0001000000010000000180000001C0000001E0000041F80000E1FE0001F1FFC0 + 07F9FFFFFFFD2800000020000000400000000100040000000000800200000000 + 0000000000000000000000000000000000000000800000800000008080008000 + 00008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF00 + 0000FF00FF00FFFF0000FFFFFF00000000000000000000000000000000000000 + 00000000ECECECECECEC0000000000C000000ECECECECECECECECEC0000000EC + 000CECECECECECECECECECECE00000CEC0CECECECECECECECECECECECE0000EC + ECECECECECECECECECE0000CECE000CECECECECECECECECECE0ECEC0CEC000EC + ECECECECECECECECEC0CECE0ECE000CECECECECECECECECECE0ECEC0CEC000EC + E0ECECECECECECECECECECECEC0000CE000ECECECECECECECECECECEC00000EC + 00000CECECECECECECECECE0000000C0000000000ECECECECECE000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000CECECECECE0000000000000000 + 000CECECECECECECECE000000C0000000ECECECECECECECECECE0000CE00000C + ECECECECECECECECECECE00CEC0000CECECECECECECECECECECECECECE000CEC + ECECECECECECECECECECECECEC000ECEC00ECECECECECECECECECECECE000CEC + E00CECECECECECECECECECECEC000ECECECECECECECECECECECECECECE0000EC + ECECECECECECECECECECECECEC00000ECECECECECECECECECECEC0CECE000000 + 0CECECECECECECECECEC000CEC000000000ECECECECECECECEC00000CE000000 + 000000ECECECECECE00000000C00000000000000000000000000000000000000 + 0000000000000000000000000000BFF000FF9F80001F8E000007840000038000 + 0001800000008000000080000000800000008000000184000003860000078F80 + 001F9FF800FFBFFFFFFFFFC00FFDFE0001F9F80000F1E0000061C00000018000 + 00010000000100000001000000010000000180000001C0000001E0000041F800 + 00E1FE0001F1FFC007F9FFFFFFFD280000002000000040000000010001000000 + 0000000100000000000000000000000000000000000000000000FFFFFF000000 + 0000000FFF00207FFFE031FFFFF83BFFFFFC3FFFFFFE3FFFFF3E3FFFFEDE3FFF + FEDE3BFFFFFC31FFFFF8307FFFE02007FF00000000000000000000000000003F + F00001FFFE0407FFFF0C1FFFFF9C3FFFFFFC7FFFFFFC73FFFFFC73FFFFFC7FFF + FFFC3FFFFFFC1FFFFFBC07FFFF1C01FFFE0C003FF8040000000000000000BFF0 + 00FF9F80001F8E00000784000003800000018000000080000000800000008000 + 00008000000184000003860000078F80001F9FF800FFBFFFFFFFFFC00FFDFE00 + 01F9F80000F1E0000061C0000001800000010000000100000001000000010000 + 000180000001C0000001E0000041F80000E1FE0001F1FFC007F9FFFFFFFD2800 + 0000100000002000000001002000000000004004000000000000000000000000 + 0000000000000000002200000038000000060000000000000000000000000000 + 0015000000320000005000000058000000460000003900000023000000060000 + 00000000000001000092040101950000003B00000006000000050000005A1F09 + 09C2651B1DF5862326FF892327FF6D1D20FA320E0FD100000085000000420000 + 001300000000080203929C3438FE030101910000003B0F05069A913134FEFA51 + 57FFFF5258FFFF5259FFFF5359FFFF5359FFFF5359FFB33C40FF1E0B0BC40000 + 00480000000908030392FF676DFF973F42FE0B0505CEC15054FFFF686DFFFF68 + 6EFFFF686EFFFF686EFFFF686EFFFF686EFFC64F54FFBF4C50FFD4585DFF0D06 + 06AA0000002308040492FF7D82FFFF7D82FFD96C70FFFF7D82FFFF7D83FFFF7E + 83FFFF7E83FFFF7E83FFFF7E83FFEA7378FF783D3FFF804143FFDF6E72FF582C + 2DEB0000001A08040492FF9397FFDC7E81FF432526F7ED888DFFFF9398FFFF93 + 98FFFF9398FFFF9398FFFF9398FFFF9498FFFF9498FFFF9498FFF38D91FF2716 + 17B50000000108050592DA8F92FF271819B90000001F3A2526D1DA8F93FFFFA9 + ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFFFA9ADFFED9DA1FF4E3233E40000 + 001F0000000003020392251A1BB60000000800000000000000100C08089A6549 + 4AF4AE8082FFD29C9EFFD59EA1FFB9888BFF79585AFA1F1617A5000000190000 + 0003000000150000004C00000007000000080000003C00000084000000A00000 + 00AC000000C4000000B2000000900000006C0000001400000000000000020000 + 0082000000260000000000000011100505A8732225FAC3383CFFEC4248FFF444 + 4AFFDC3E43FF9C2D31FF381112DB0000007100000037000000060903038B250B + 0CEF00000026000000052C1112C2DA5055FFFF5C62FFFF5C62FFFF5C62FFFF5C + 62FFFF5C62FFFF5C62FFFD5B61FF833134FC0100008906030398AA3F43FF6123 + 25EF0000002600000066C75A5EFFAB4B4FFF793436FFFF7278FFFF7278FFFF72 + 78FFFF7278FFFF7278FFFF7278FFFF7277FF7F3A3DFCA54B4FFFFF7277FF612B + 2DEF0000002604020288F28185FF5B3133FF130A0BFFFB868BFFFF888DFFFF88 + 8DFFFF888DFFFF888DFFFF888DFFFF888DFFDB7478FFF58287FFFF888DFF6134 + 36EF0000002600000028734648F7FA9B9FFFF1969AFFFF9EA2FFFF9EA2FFFF9E + A2FFFF9EA2FFFF9EA2FFFF9EA2FFE68E91FF301C1DC94B2D2EE0F4979BFF613C + 3EEF00000026000000000000004C664547F1E6A2A5FFFFB4B8FFFFB4B8FFFFB4 + B8FFFFB4B8FFFCB2B6FFA97578FF25191AB30000001000000020493233DE553B + 3DEF000000260000000000000000000000190A0707854C393ACF6A5153F46F55 + 56FC5E4849E5261C1DAC0000004A0000000000000000000000000000001E0100 + 00C7000000093C07000018010000000100000000000000000000000100000001 + 000030020000600C000080080000800000000000000000000000000000008000 + 0000C03900002800000010000000200000000100080000000000400100000000 + 0000000000000000000000000000181818008442210042424200AD6B4200BD7B + 5A00C68C7B00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF + FF00FFFFFF00FFFFFF00FFFFFF00020000000002020202020202000000000202 + 0002020103030303030102020000020402010303030404040404030102000204 + 0404040404040404010000010402020404040404040404040004040004020204 + 0205050505050505050505050200020200030305050505050503030300000200 + 0000000303030303030300000000000000000202020202020200000000020000 + 0202010303030303010202000202000204010104040404030303010204020204 + 0100000104040404040404040402020401000001040404040404040404020002 + 0501010505050505050505020402000003030305050505050503030002020000 + 0000030303030303030000000002780F00002003000000010000000000000000 + 00000001000020030000780F0000F01E0000C004000080000000000000000000 + 000080000000C0040000F01E0000280000001000000020000000010004000000 + 0000C00000000000000000000000000000000000000000000000000080000080 + 000000808000800000008000800080800000C0C0C000808080000000FF0000FF + 000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0000000000000000000000 + 0EECECEC00000E0ECECECECECE000CECECECECE00CE00ECECECECE0EC0C00C0C + ECECECECEC0000000ECECECE0000000000000000000000000000000000000000 + ECECECE0000000CECECECECEC0C00CE00CECECECECE00EC00ECECECECEC000EC + ECECECECE0E00000CECECEC000000000000000000000780F0000200300000001 + 000000000000000000000001000020030000780F0000F01E0000C00400008000 + 0000000000000000000080000000C0040000F01E0000} + OldCreateOrder = False + Position = poScreenCenter + OnDestroy = FormDestroy + OnResize = FormResize + PixelsPerInch = 96 + TextHeight = 12 + object Label1: TLabel + Left = 8 + Top = 8 + Width = 216 + Height = 12 + Caption = 'フォルダ/アーカイブを選択してください(&F) :' + FocusControl = ShellTreeView + end + object Label2: TLabel + Left = 8 + Top = 356 + Width = 42 + Height = 12 + Anchors = [akLeft, akBottom] + Caption = '選択中 :' + end + object FileLabel: TLabel + Left = 120 + Top = 384 + Width = 53 + Height = 12 + Caption = ' (ファイル)' + Visible = False + end + object FolderLabel: TLabel + Left = 208 + Top = 384 + Width = 55 + Height = 12 + Caption = ' (フォルダ)' + Visible = False + end + object NothingLabel: TLabel + Left = 296 + Top = 384 + Width = 28 + Height = 12 + Caption = '(なし)' + Visible = False + end + object ViewPanel: TPanel + Left = 8 + Top = 24 + Width = 611 + Height = 329 + Anchors = [akLeft, akTop, akRight, akBottom] + BevelOuter = bvNone + TabOrder = 3 + object Splitter: TSplitter + Left = 244 + Top = 0 + Width = 3 + Height = 329 + Cursor = crHSplit + ResizeStyle = rsUpdate + end + object ShellListView: TShellListView + Left = 247 + Top = 0 + Width = 364 + Height = 329 + Align = alClient + TabOrder = 1 + ViewStyle = vsList + OnChange = ShellListViewChange + OnClick = ShellListViewClick + ShellPopupMenu = ShellListPopupMenu + ShVirtuaItems = [itNetWork] + OnShExecute = ShellListViewShExecute + end + object ShellTreeView: TShellTreeView + Left = 0 + Top = 0 + Width = 244 + Height = 329 + Align = alLeft + Checkboxes = False + Indent = 19 + TabOrder = 0 + OnChange = ShellTreeViewChange + OnClick = ShellTreeViewClick + ShellComboBox = ShellComboBox + ShellListView = ShellListView + ShellPopupMenu = ShellTreePopupMenu + ShVirtuaItems = [itNetWork] + end + object ShellComboBox: TShellComboBox + Left = 120 + Top = 40 + Width = 145 + Height = 24 + TabOrder = 2 + end + end + object OKButton: TButton + Left = 442 + Top = 376 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'OK' + Default = True + ModalResult = 1 + TabOrder = 0 + end + object CancelButton: TButton + Left = 530 + Top = 376 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Cancel = True + Caption = 'キャンセル' + ModalResult = 2 + TabOrder = 1 + end + object NoSelectButton: TButton + Left = 8 + Top = 376 + Width = 81 + Height = 25 + Anchors = [akLeft, akBottom] + Caption = '選択しない(&N)' + ModalResult = 3 + TabOrder = 2 + end + object PageScroller: TPageScroller + Left = 56 + Top = 356 + Width = 560 + Height = 12 + Anchors = [akLeft, akRight, akBottom] + AutoScroll = False + Control = PlaceLabel + TabOrder = 4 + object PlaceLabel: TStaticText + Left = 0 + Top = 0 + Width = 560 + Height = 12 + Caption = 'PlaceLabel' + TabOrder = 0 + end + end + object StatusBar1: TStatusBar + Left = 608 + Top = 381 + Width = 21 + Height = 19 + Align = alNone + Anchors = [akRight, akBottom] + Panels = < + item + Bevel = pbNone + Width = 50 + end> + SimplePanel = False + end + object ShellListPopupMenu: TShellPopupMenu + AutoPopup = False + InsertPos = 2 + Left = 288 + Top = 192 + object SelectItemMenuItem: TMenuItem + Caption = '吉里吉里で実行' + Default = True + OnClick = SelectItemMenuItemClick + end + object N2: TMenuItem + Caption = '-' + end + end + object ShellTreePopupMenu: TShellPopupMenu + AutoPopup = False + InsertPos = 2 + Left = 184 + Top = 192 + object SelectFolderMenuItem: TMenuItem + Caption = '吉里吉里で実行' + OnClick = SelectItemMenuItemClick + end + object N3: TMenuItem + Caption = '-' + end + end +end diff --git a/tools/win32/krdevui/FolderSelectorUnit.h b/tools/win32/krdevui/FolderSelectorUnit.h new file mode 100644 index 0000000..2b8e5d7 --- /dev/null +++ b/tools/win32/krdevui/FolderSelectorUnit.h @@ -0,0 +1,66 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef FolderSelectorUnitH +#define FolderSelectorUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include "ShellCtrls.hpp" +#include +#include +#include +//--------------------------------------------------------------------------- +class TFolderSelectorForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TPanel *ViewPanel; + TButton *OKButton; + TButton *CancelButton; + TLabel *Label1; + TShellListView *ShellListView; + TSplitter *Splitter; + TShellTreeView *ShellTreeView; + TButton *NoSelectButton; + TShellComboBox *ShellComboBox; + TShellPopupMenu *ShellListPopupMenu; + TLabel *Label2; + TLabel *FileLabel; + TLabel *FolderLabel; + TLabel *NothingLabel; + TPageScroller *PageScroller; + TStaticText *PlaceLabel; + TMenuItem *SelectItemMenuItem; + TMenuItem *N2; + TShellPopupMenu *ShellTreePopupMenu; + TStatusBar *StatusBar1; + TMenuItem *SelectFolderMenuItem; + TMenuItem *N3; + void __fastcall FormResize(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall ShellTreeViewChange(TObject *Sender, TTreeNode *Node); + void __fastcall ShellListViewChange(TObject *Sender, TListItem *Item, + TItemChange Change); + void __fastcall ShellTreeViewClick(TObject *Sender); + void __fastcall ShellListViewClick(TObject *Sender); + void __fastcall ShellListViewShExecute(TObject *Sender, + TShellFileItem *Item, TShiftState Shift, int SubItem, int X, + int Y, bool &DefaultAction); + void __fastcall SelectItemMenuItemClick(TObject *Sender); +private: // ユーザー宣言 +public: // ユーザー宣言 + AnsiString Selected; + __fastcall TFolderSelectorForm(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFolderSelectorForm *FolderSelectorForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/FontMakerUnit.cpp b/tools/win32/krdevui/FontMakerUnit.cpp new file mode 100644 index 0000000..7ad6b05 --- /dev/null +++ b/tools/win32/krdevui/FontMakerUnit.cpp @@ -0,0 +1,467 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "FontMakerUnit.h" +#include "FontMakerWriteUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TFontMakerForm *FontMakerForm; + +DWORD WINAPI (*procGetFontUnicodeRanges)(HDC, LPGLYPHSET); + // GetFontUnicodeRanges function ( only supporter on Win2000 or later ) + +DWORD WINAPI (*procGetGlyphIndicesW)(HDC, LPCWSTR, int, LPWORD, DWORD); + // GetGlyphIndicesW + +DWORD WINAPI (*procGetGlyphOutlineW)(HDC, UINT, UINT, LPGLYPHMETRICS, DWORD, LPVOID, CONST MAT2 *); + // GetGlyphOutlineW function ( WinNT or Win9x ( but 95 is not supported ) ) + +BOOL WINAPI (*procTextOutW)(HDC, int, int, LPCWSTR, int); + // TextOutW + +BOOL APIENTRY (*procGetTextExtentPoint32W)(HDC, LPCWSTR, int, LPSIZE); + // GetTextExtentPoint32W + +//--------------------------------------------------------------------------- +int CALLBACK FontEnumProc( + ENUMLOGFONTEX *lpelfe, // pointer to logical-font data + NEWTEXTMETRICEX *lpntme, // pointer to physical-font data + int FontType, // type of font + LPARAM userdata) +{ + TFontMakerForm *form = reinterpret_cast(userdata); + + // enumerate fonts + // true type only + bool is_outline = + (lpntme->ntmTm.ntmFlags & NTM_PS_OPENTYPE) || + (lpntme->ntmTm.ntmFlags & NTM_TT_OPENTYPE) || + (FontType & TRUETYPE_FONTTYPE); + if(!is_outline) return 1; + + if(!form->ShowAllFontsCheckBox->Checked) + { + if(lpelfe->elfLogFont.lfCharSet != SHIFTJIS_CHARSET) return 1; + } + + if(form->FontSelectComboBox->Items->IndexOf(lpelfe->elfLogFont.lfFaceName) == -1) + form->FontSelectComboBox->Items->Add(lpelfe->elfLogFont.lfFaceName); + + return 1; +} + +//--------------------------------------------------------------------------- +__fastcall TFontMakerForm::TFontMakerForm(TComponent* Owner) + : TForm(Owner) +{ + FontPreviewForm = NULL; + CharacterListInvalidated = true; + CharacterList = new wchar_t [65536*2]; + PrivRefControl = new TPrivRefControl(this); + PrivRefControl->Parent = this; + PrivRefControl->Left = -1; + PrivRefControl->Top = -1; + PrivRefControl->Width = 1; + PrivRefControl->Height = 1; + PrivRefControl->Visible = true; + + HMODULE gdi32dll = GetModuleHandle("gdi32.dll"); + *(void**)&procGetFontUnicodeRanges = + GetProcAddress(gdi32dll, "GetFontUnicodeRanges"); + *(void**)&procGetGlyphIndicesW = + GetProcAddress(gdi32dll, "GetGlyphIndicesW"); + *(void**)&procGetGlyphOutlineW = + GetProcAddress(gdi32dll, "GetGlyphOutlineW"); + *(void**)&procTextOutW = + GetProcAddress(gdi32dll, "TextOutW"); + *(void**)&procGetTextExtentPoint32W = + GetProcAddress(gdi32dll, "GetTextExtentPoint32W"); + + if(Win32Platform != VER_PLATFORM_WIN32_NT) + procGetGlyphOutlineW = NULL; // ?? this cannot be used ... + + if(!procTextOutW || !procGetTextExtentPoint32W) + throw Exception("Windows95 (or OS which does not support wide character code API) is not supported on this tool!"); + + BoldCheckBox->Enabled = (Win32Platform == VER_PLATFORM_WIN32_NT); + IncludeAllFontCharsCheckBox->Enabled = + (procGetFontUnicodeRanges && procGetGlyphOutlineW && procGetGlyphIndicesW); + IncludePrivateCharsCheckBox->Enabled = + (procGetFontUnicodeRanges && procGetGlyphOutlineW && procGetGlyphIndicesW); + + EnumFonts(); + + LOGFONT font; + SetFontToCanvas(font); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::FormDestroy(TObject *Sender) +{ + if(FontPreviewForm) delete FontPreviewForm; + delete [] CharacterList; + delete PrivRefControl; +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::EnumFonts() +{ + FontSelectComboBox->Items->Clear(); + + LOGFONT l; + l.lfHeight = -12; + l.lfWidth = 0; + l.lfEscapement = 0; + l.lfOrientation = 0; + l.lfWeight = 400; + l.lfItalic = FALSE; + l.lfUnderline = FALSE; + l.lfStrikeOut = FALSE; + l.lfCharSet = DEFAULT_CHARSET; + l.lfOutPrecision = OUT_DEFAULT_PRECIS; + l.lfQuality = DEFAULT_QUALITY; + l.lfPitchAndFamily = 0; + l.lfFaceName[0] = '\0'; + + ::EnumFontFamiliesEx(Canvas->Handle, &l, (FONTENUMPROC)FontEnumProc, + reinterpret_cast(this), 0); + + TStringList *list = new TStringList(); + list->Assign(FontSelectComboBox->Items); + list->Sort(); + FontSelectComboBox->Items->Assign(list); + delete list; + + int n = FontSelectComboBox->Items->IndexOf(Canvas->Font->Name); + if(n!=-1) + { + FontSelectComboBox->ItemIndex = n; + } + else + { + int n = FontSelectComboBox->Items->IndexOf(CreateButton->Font->Name); + if(n != -1) + FontSelectComboBox->ItemIndex = n; + else + FontSelectComboBox->ItemIndex = 0; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::OutputRefButtonClick(TObject *Sender) +{ + if(SaveDialog->Execute()) + { + OutputEdit->Text = SaveDialog->FileName; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::CreateButtonClick(TObject *Sender) +{ + if(FontSelectComboBox->ItemIndex == -1) return; + + if(OutputEdit->Text == "") + { + OutputRefButtonClick(this); + if(OutputEdit->Text == "") return; + } + + // create font + LOGFONT font; + SetFontToCanvas(font); + + // call process dialog + TFontMakerWriteForm *form = new + TFontMakerWriteForm(Application, OutputEdit->Text, Canvas, PrivRefControl->Canvas, + AntialiasedCheckBox->Checked, font.lfFaceName[0] == '@', + GetCharacterList(), GetCharacterListCount()); + form->ShowModal(); + delete form; +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::CancelButtonClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::ShowAllFontsCheckBoxClick(TObject *Sender) +{ + EnumFonts(); + NotifyFontChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::ShowSampleButtonClick(TObject *Sender) +{ + if(!FontPreviewForm) + { + FontPreviewForm = new TFontPreviewForm(this, Canvas, + PrivRefControl->Canvas); + NotifyFontChanged(); + FontPreviewForm->Visible = true; + } + else + { + NotifyFontChanged(); + FontPreviewForm->Visible = true; + FontPreviewForm->BringToFront(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::FontSelectComboBoxChange(TObject *Sender) +{ + CharacterListInvalidated = true; + NotifyFontChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::SizeEditChange(TObject *Sender) +{ + NotifyFontChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::BoldCheckBoxClick(TObject *Sender) +{ + NotifyFontChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::AntialiasedCheckBoxClick(TObject *Sender) +{ + NotifyFontChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::IncludeAllFontCharsCheckBoxClick( + TObject *Sender) +{ + CharacterListInvalidated = true; + NotifyFontChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::IncludePrivateCharsCheckBoxClick( + TObject *Sender) +{ + CharacterListInvalidated = true; + NotifyFontChanged(); +} +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::SetFontToCanvas(LOGFONT & font) +{ + // create font object + SetPrivFontToPrivCanvas(); + + ::GetObject(Canvas->Font->Handle, sizeof(font), &font); + font.lfHeight = -SizeUpDown->Position; + AnsiString fontname = FontSelectComboBox->Items->Strings[FontSelectComboBox->ItemIndex]; + strcpy(font.lfFaceName, fontname.c_str()); + font.lfEscapement = font.lfOrientation = font.lfFaceName[0] == '@' ? 2700:0; + font.lfWeight = BoldCheckBox->Checked ? 700:400; + font.lfCharSet = DEFAULT_CHARSET; + Canvas->Font->Handle = CreateFontIndirect(&font); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::SetPrivFontToPrivCanvas() +{ + // create font object for private (GAIJI) area + LOGFONT font; + ::GetObject(PrivRefControl->Canvas->Font->Handle, sizeof(font), &font); + font.lfHeight = -SizeUpDown->Position; + AnsiString fontname = FontSelectComboBox->Items->Strings[FontSelectComboBox->ItemIndex]; + strcpy(font.lfFaceName, (fontname.c_str()[0] == '@' ? AnsiString('@') + CreateButton->Font->Name : + CreateButton->Font->Name).c_str()); + font.lfEscapement = font.lfOrientation = font.lfFaceName[0] == '@' ? 2700:0; + font.lfWeight = BoldCheckBox->Checked ? 700:400; + font.lfCharSet = DEFAULT_CHARSET; + PrivRefControl->Canvas->Font->Handle = CreateFontIndirect(&font); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::NotifyFontChanged() +{ + LOGFONT font; + SetFontToCanvas(font); + if(FontPreviewForm) FontPreviewForm->NotifyFontChanged(AntialiasedCheckBox->Checked); +} +//--------------------------------------------------------------------------- +int __cdecl TFontMakerForm::CodeComparison(const void *s1, const void *s2) +{ + const wchar_t *c1 = (const wchar_t *)s1; + const wchar_t *c2 = (const wchar_t *)s2; + if(*c1 < *c2) return -1; + if(*c1 == *c2) return 0; + return 1; +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::PushDBCSCharacter(int code) +{ + // "code" is in DBCS(MBCS) character code + if(CharacterListCount >= 65536*2) return; + + char ch[3]; + int insize; + if(code < 256) + ch[0] = code, ch[1] = 0, insize = 1; + else + ch[0] = code >> 8, ch[1] = code, ch[2] = 0, insize = 2; + + wchar_t wch[10]; + int res = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS|MB_PRECOMPOSED, + ch, insize, wch, 10); + + if(res == 1) + { + if(!(!IncludePrivateCharsCheckBox->Checked && (wch[0] >= 0xe000 && wch[0] <= 0xf8ff))) + CharacterList[CharacterListCount++] = wch[0]; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::PushCharacterRange(int base, int count) +{ + int i; + int lim = count + base; + for(i = base; i < lim; i++) + { + if(CharacterListCount >= 65536*2) return; + if(i >= 0x20 && i <= 0xfffd) + CharacterList[CharacterListCount++] = i; + } +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerForm::CreateCharacterList() +{ + if(!CharacterListInvalidated) return; + + LOGFONT lf; + SetFontToCanvas(lf); + + CharacterListCount = 0; + + // DBCS + for(int i = 0x20; i <= 0xffff; i++) PushDBCSCharacter(i); + + // UNICODE + if(IncludeAllFontCharsCheckBox->Checked && procGetFontUnicodeRanges) + { + GLYPHSET * gs; + DWORD size = procGetFontUnicodeRanges(Canvas->Handle, NULL); + gs = (GLYPHSET*) new char[size]; + ZeroMemory(gs, size); + gs->cbThis = size; + procGetFontUnicodeRanges(Canvas->Handle, gs); + if(gs->cGlyphsSupported<=65536 && gs->cRanges >= 1) + { + for(unsigned int i = 0; i < gs->cRanges; i++) + { + PushCharacterRange(gs->ranges[i].wcLow, gs->ranges[i].cGlyphs); + } + } + delete [] (char*)gs; + } + + // sort + qsort(CharacterList, CharacterListCount, sizeof(wchar_t), CodeComparison); + + // purge duplicates + wchar_t *dp = CharacterList; + wchar_t *sp = CharacterList; + wchar_t *splim = CharacterList + CharacterListCount; + int current = -1; + while(sp < splim) + { + if(*sp != current && *sp && *sp <= 0xfffd) + *(dp++) = current = *(sp++); + else + sp++; + } + CharacterListCount = dp - CharacterList; + + // Check existence of glyphs and purge non-existence glyphs + if(procGetGlyphIndicesW) + { + WORD *indices = new WORD[CharacterListCount]; + int cnt = procGetGlyphIndicesW(Canvas->Handle, CharacterList, + CharacterListCount, indices, GGI_MARK_NONEXISTING_GLYPHS); + + if(cnt != -1) + { + WORD *ip = indices; + sp = CharacterList; + dp = CharacterList; + splim = CharacterList + cnt; + + while(sp < splim) + { + if(*sp >= 0xe000 && *sp <= 0xf8ff && IncludePrivateCharsCheckBox->Checked) + { + // private area + *(dp++) = *sp; + } + else + { + // other unicodes + if(*ip != 0xffff && *sp >= 0x20 && *sp <= 0xfffd) *(dp++) = *sp; + } + ip++; + sp++; + } + + delete [] indices; + + CharacterListCount = dp - CharacterList; + } + } + + // down the flag + CharacterListInvalidated = false; +} +//--------------------------------------------------------------------------- +int __fastcall TFontMakerForm::GetCharacterListCount() +{ + CreateCharacterList(); + return CharacterListCount; +} +//--------------------------------------------------------------------------- +const wchar_t * __fastcall TFontMakerForm::GetCharacterList() +{ + CreateCharacterList(); + return CharacterList; +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +extern "C" void _export PASCAL UIExecFontMaker() +{ + try + { + TFontMakerForm *form = new TFontMakerForm(Application); + form->ShowModal(); + delete form; + } + catch(Exception &e) + { + Application->ShowException(&e); + } + ExitProcess(0); +} +//--------------------------------------------------------------------------- + + + + + + + + + + + + + + diff --git a/tools/win32/krdevui/FontMakerUnit.dfm b/tools/win32/krdevui/FontMakerUnit.dfm new file mode 100644 index 0000000..56d531f --- /dev/null +++ b/tools/win32/krdevui/FontMakerUnit.dfm @@ -0,0 +1,778 @@ +object FontMakerForm: TFontMakerForm + Left = 3 + Top = 100 + BorderIcons = [biSystemMenu, biMinimize] + BorderStyle = bsSingle + Caption = 'レンダリング済みフォントデータ作成' + ClientHeight = 257 + ClientWidth = 395 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + Icon.Data = { + 0000010005003030000001002000A8250000560000002020000001002000A810 + 0000FE250000101000000100200068040000A63600002020000001000800A808 + 00000E3B0000101000000100080068050000B643000028000000300000006000 + 0000010020000000000080250000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000150000001700000017000000170000001700000017000000170000 + 0017000000170000001700000017000000170000001700000017000000170000 + 0008000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000F00000017000000170000 + 0017000000170000001700000017000000170000001700000017000000170000 + 0017000000170000001700000017000000170000001700000017000000170000 + 0000000000350000003800000038000000380000003800000038000000380000 + 0038000000380000003800000038000000380000003800000038000000380000 + 001300000000D6D6D60ACDCDCD23C3C3C3210000000600000000000000000000 + 0000000000000000000000000000000000000000002400000038000000380000 + 0038000000380000003800000038000000380000003800000038000000380000 + 0038000000380000003800000038000000380000003800000038000000380000 + 00870000009F000000A1000000A1000000A1000000A1000000A1000000A10000 + 00A1000000A1000000A1000000A1000000A1000000A10000005E050505399A9A + 9D34A7A7E17A9595DCC28585D3E09191C3E49C9CA8BF828282615F5F5F170000 + 00010000000000000000000000000000005F00000098000000A1000000A10000 + 00A1000000A1000000A1000000A1000000A1000000A1000000A1000000A10000 + 00A1000000A1000000A1000000A1000000A1000000A00000003B000000380000 + 01FF00004CFF00007FFF000084FF000084FF000084FF000084FF000084FF0000 + 84FF000084FF000084FF000068FF00003FFF00000FFF000000756A6A733C9898 + E0909696E6AE7D7DE3E65D5DE7F36868DCF28282CCF39999AEED838384A24242 + 4230000000050000000000000000000000B41B070AFF401219FF6B212BFF7427 + 2FFF762A30FF772E32FF793133FF7A3535FF7C3836FF7D3C37FF7F3F39FF8143 + 3AFF82463BFF844A3DFF6B3D31FF381F1AFF010000FE0000002E000000220000 + 009B000000D000000FFD00006BFF0000EEFF0000FFFF0000FFFF0000FFFF0000 + FFFF0000AAFF000027FF000000EA000000BE000000A200000034000000010000 + 000100000002C5C5D34E9999DBE18080E9EB8D8DDCED9B9BCFEBA1A1ABF27D7D + 7DAD3434343100000002000000000000006A000000A8000000CD0C0405FC7828 + 31FFE3525EFFE65960FFE95F63FFEC6665FFEF6D68FFF2746BFFF57B6DFFF881 + 70FFC66B5AFF41241EFF010101EE000000B80000009900000005000000000000 + 0000000000000000001C0000009A000034FF0000F5FF0000FFFF0000FFFF0000 + C6FF000003ED000000680000001B000000000000000000000000000000000000 + 00000000000000000000BBBBC972A3A3DFEBA9A9EAE5BDBDDBE6C8C8CEE59B9B + 9BF45C5C5C7D4C4C4C20000000000000000000000000000000000000001F0000 + 00D69A3940FFE65A61FFE96063FFEC6766FFEF6E68FFF2756BFFF57C6EFFAC5A + 4EFF060303F20000007D00000009000000000000000000000000000000000000 + 0000000000000000000000000001000000A4000067FF0000FFFF0000FFFF0000 + 78FF0000009C0000003800000026000000000000000000000000000000000000 + 00000000000000000000C4C4C40FB6B6C4B9C7C7E7E3E0E0EADEDBDBDCE3C2C2 + C2EA808080E22222223F00000008000000000000000000000000000000000000 + 006F5E2327FFE75B61FFEA6264FFED6966FFF06F69FFF3766BFFD76D60FF0E07 + 06F9000000620000001000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000F000002E50000C6FF0000FFFF0000 + 8BFF000000AB0000003800000036000000030000000000000000000000000000 + 0000000000000000000000000000B8B8B82CB8B8BACFDCDCDCE1EDEDEDDAE0E0 + E0E1979797F75A5A5A843B3B3B2B000000070000000000000000000000000000 + 0086722B2FFFE85D62FFEB6364FFEE6A67FFF17169FFF3776CFF4D2722FF0000 + 0098000000290000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000006000003CFF0000FFFF0000 + CDFF000000E40000003900000038000000190000000000000000000000000000 + 000000000000000000000000000000000000ACACAC26A6A6A6B5BABABAEAE9E9 + E9DACACACAE57B7B7BE60F0F0F4A000000390000000B00000000000000000000 + 00CBAA4247FFE95F63FFEB6565FFEE6C68FFF1736AFFBC5D53FF010000E80000 + 003F0000000D0000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000003000000D80000BEFF0000 + FEFF00002AFF0000006A00000038000000310000000100000000000000000000 + 00000000000000000000000000000000000000000000000000069696967E9E9E + 9EF1D9D9D9DC3A3A3CFA08080CCC00000041000000380000000A000000281508 + 09FEE3595FFFE96163FFEC6766FFEF6E68FFF2756BFF46231FFF000000880000 + 002B000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000064000047FF0000 + FFFF000094FF000000BF00000038000000380000001200000000000000000000 + 0000000000000000000000000000000000000000000000000000000000006E6E + 6E882B2B2DFEA5A5BAFF666692FF020204B10000003D00000036000000956C29 + 2DFFE85D62FFEB6364FFED6A67FFF07069FFC86158FF010101EC0000003E0000 + 0012000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000007000001E60000 + D1FF0000F3FF000011FD00000053000000380000002B00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00030B0B0BADB3B3BBFFC3C3E5FF4F4F73FF0000009300000047040101F3CA4F + 55FFE96063FFEC6665FFEF6C68FFF1736AFF5F2E2AFF00000099000000310000 + 0001000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000007C0500 + 5CFF1800E7FF120064FF000000A900000038000000380000000C000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000A181819CBCCCCD5FFB6B6DFFF383853FD000000C04B1D1FFFE85D + 62FFEA6364FFED6967FFF06F69FFDF6C63FF090404F900000049000000190000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000150300 + 05F6750071FF83005EFF040001F5000000440000003800000025000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000001A2B2B2EE3DBDBE6FFA7A7D5FF242436FF6F2B2EFFE25D + 60FFEC6665FFEE6C68FFF1726AFF803E39FF000000B400000035000000040000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 009A600120FFC00440FF440217FF000000930000003800000037000000260000 + 0026000000260000002600000026000000260000002600000026000000260000 + 0026000000260000002600000055434347F6E2E2EFFF9595C7FF281D28FF9F43 + 44FFEA6865FFF07069FFEE7369FF1B0D0CFF0000005E00000021000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 002A110106FEBD0B41FF9D0A36FF000000E80000003C00000038000000380000 + 0038000000380000003800000038000000380000003800000038000000380000 + 003800000038000000380000003800000077636368FEDEDEF0FF8282B4FF2D1A + 1EFFB3524EFFF1736AFFA14F47FF000000CF0000003800000009000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000B77A0B2BFFC71446FF310511FF000000DF000000D8000000D80000 + 00D8000000D8000000D8000000D8000000D8000000D8000000D8000000D80000 + 00D8000000D8000000D8000000D8000000D8060202FE87878EFFD4D4ECFF6E6E + 9CFF3C1E1EFFC56057FF371C19FF0000008D0000002A00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000004624040DFFCA1B49FFB71A42FFA3193BFFA31B3CFFA41D3DFFA51F + 3EFFA6213EFFA82440FFA92741FFAA2A42FFAC2D43FFAD3144FFAF3446FFB038 + 47FFB23C49FFB4404AFFB6444CFFB8484DFFC85255FF5D292AFFA9A9B1FFC8C8 + E6FF57577EFF391C19FF000000ED0000006A0000003600000001000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000001000000D4961937FFCF244CFF71142AFF5A1021FF5A1122FF5B12 + 22FF5B1423FF5C1523FF5D1724FF5D1824FF5E1A25FF5F1C26FF601E26FF6120 + 27FF612228FF622429FF63262AFF65292BFFE16060FFE76764FF482828FFC4C4 + CDFFBBBBE1FF40405EFF000000BD000000610000003D00000027000000010000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000643C0C17FFD22B4FFF74192CFF000000E4000000900000 + 00900000007D0000007000000070000000700000007000000070000000700000 + 00700000007000000070000000B3411C1CFFED6966FFEF6E68FFDF6A62FF402F + 30FFD7D7E1FFACACD9FF2B2B41FA000000730000003D0000003D000000240000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000009010000E9B32A45FFC9314EFF0C0305FC000000500000 + 00380000002A0000000000000000000000000000000000000000000000000000 + 00000000000000000000000000CDA84B49FFEF6E68FFF1736AFFF4786CFFCF69 + 5DFF463E41FFE0E0EDFF9B9BCDFF1C1C2AED000000540000003D0000003D0000 + 0022000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000081571722FFD93B55FF611B26FF000000A50000 + 0038000000380000000B00000000000000000000000000000000000000000000 + 0000000000000000003D241010FFEE6E68FFF2736AFFF4786CFFF67D6EFFF17E + 6DFF170C0AFE57575BFCE0E0F0FF8989BBFF101018DC000000470000003D0000 + 003D0000001F0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000018090304F8CB3D51FFC13C4DFF040101F30000 + 0043000000380000002400000000000000000000000000000000000000000000 + 000000000000000000AC8A413DFFF2746BFFF4786CFFF67D6EFFF88270FF9D54 + 47FF000000C90000008A7A7A80FFD8D8EDFF7575A4FF07070AC50000003F0000 + 003D0000003D0000001C00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000009F74262FFFE04B5BFF4B1A1FFF0000 + 008F000000380000003700000006000000000000000000000000000000000000 + 00000000001F0F0707FBE66F66FFF4796DFFF67E6EFFF88370FFFA8772FF321B + 17FF0000007300000027030303919E9EA5FFCCCCE8FF5F5F89FF010102A80000 + 003D0000003D0000003D00000019000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000002F17080AFEDE505CFFB2424AFF0000 + 00E50000003B000000380000001E000000000000000000000000000000000000 + 00000000008A6C3530FFF57B6DFFF77F6FFFF98471FFFB8872FFC16B58FF0000 + 00E20000003A0000000E000000030D0D0EB6BCBCC4FFBFBFE3FF484869FF0000 + 008A0000003D0000003D0000003D000000170000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000BC92393DFFE75B61FF3415 + 16FF0000007A0000003800000034000000030000000000000000000000000000 + 000B030201EED56C5FFFF88170FFF98571FFFB8973FFFD8E74FF542F27FF0000 + 008D0000002E00000000000000000000000E1D1D1FD3D1D1DBFFB1B1DCFF3232 + 4AFB0000006E0000003D0000003D0000003C0000001400000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000004C2E1313FFEA6264FF9E43 + 44FF000000D20000003800000038000000180000000000000000000000000000 + 00694D2823FFF88370FFFA8772FFFC8B73FFFE8F75FFE07F67FF040202F40000 + 00430000001600000000000000000000000000000021313135E9DEDEEAFFA1A1 + D1FF212131F0000000560000003D0000003D0000003C00000012000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000002000000D8B24F4DFFEB6A + 66FF1F0E0EFF0000006400000038000000300000000100000000000000010000 + 00D6BA6455FFFB8973FFFD8D74FFFE8F75FFFE9075FF764336FF000000A80000 + 003400000002000000000000000000000000000000000000003B4C4C50F7E1E1 + F0FF8F8FC1FF14141EDD000000440000003D0000003D0000003B000000100000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000694A2321FFF173 + 6AFF88423CFF000000BC00000038000000380000001200000000000000472E19 + 15FFFC8B73FFFE8F75FFFE9075FFFE9075FFF48A70FF130B09FD000000540000 + 001E0000000000000000000000000000000000000000000000000000005C6E6E + 73FEDBDBEFFF7C7CADFF0A0A0FC3000000390000003D00000039000000120000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000B030101EDD268 + 5DFFE87568FF0F0807FC00000051000000380000002A00000000000000B69C58 + 48FFFE9075FFFE9075FFFE9075FFFE9075FF985646FF000000C3000000370000 + 0006000000000000000000000000000000000000000000000000000000000101 + 0183929299FFD0D0EAFF676793FF030304A10000002A00000008000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000876937 + 2FFFF88370FF713C33FF000000A7000000380000003800000033150C0AFDF68B + 71FFFE9075FFFE9075FFFE9075FFFD8F75FF2B1814FF0000006D000000250000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000109090AAAB2B2BAFFC4C4E5FF505074FF0000007300000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000001C0C07 + 06F9EB816CFFDE7B66FF040302F40000004300000038000000AA7B4638FFFE90 + 75FFFE9075FFFE9075FFFE9075FFBA6A56FF000000DD000000390000000D0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000A171718CACBCBD4FFB6B6DFFF393954FC0000004D000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00A48A4E3FFFFE9075FF573128FF0000009100000044060303F5E38169FFFE90 + 75FFFE9075FFFE9075FFFE9075FF4D2B23FF000000870000002D000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000192A2A2CE2BABAC3FF252530E900000045000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00341E110EFFF98D73FFC8715CFF000000E600000095593329FFFE9075FFFE90 + 75FFFE9075FFFE9075FFDA7C64FF030101F10000004000000014000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000031010101B30000001A00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000C2A75F4DFFFE9075FF3B221BFF000000F9C7715CFFFE9075FFFE90 + 75FFFE9075FFFE9075FF6F3F33FF000000A20000003300000001000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000051371F19FFFE9075FFAD624FFF38201AFFFE9075FFFE9075FFFE90 + 75FFFE9075FFF0886FFF0F0807FC0000004F0000001C00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000003000000DCC56F5AFFFB8E74FFC26E59FFFE9075FFFE9075FFFE90 + 75FFFE9075FF915243FF000000BD000000360000000500000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000006F543027FFFE9075FFFE9075FFFE9075FFFE9075FFFE90 + 75FFFC8F74FF251511FF00000067000000230000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000D040202F0DE7E66FFFE9075FFFE9075FFFE9075FFFE90 + 75FFB36552FF000000D7000000380000000B0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000008C724034FFFE9075FFFE9075FFFE9075FFFE90 + 75FF452720FF000000820000002B000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000001F0F0907FBF0886FFFFE9075FFFE9075FFD478 + 62FF010101ED0000003E00000013000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000AA8F5142FFFE9075FFFE9075FF673A + 2FFF0000009C0000003200000001000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000039221310FFFB8E74FFED866DFF0B06 + 05FA0000004B0000001A00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000C7AD624FFF894E3FFF0000 + 00B7000000360000000400000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000056251511FF180E0BFF0000 + 0045000000120000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000004000000660000005D0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000000FFFF + FFFFFFFF00008000FFF800000000800047F800000000000000F0000000000000 + 0070000000000001C03000030000C00FE01E001F0000F00FE01F001F0000F00F + F00F003F0000F807F803003F0000FC07FE00007F0000FC03FF00007F0000FE03 + FF8000FF0000FE01FF8000FF0000FE01FFC001FF0000FF00000001FF0000FF00 + 000003FF0000FF80000003FF0000FF80000003FF0000FFC0000001FF0000FFC0 + 000000FF0000FFE03FE0007F0000FFE01FC0003F0000FFE01FC0001F0000FFF0 + 1F80000F0000FFF00F8010070000FFF80F0030030000FFF8070038010000FFFC + 07007C000000FFFC02007E000000FFFC0200FF030000FFFE0000FF830000FFFE + 0000FF810000FFFF0001FFC10000FFFF0001FFE30000FFFF8003FFFF0000FFFF + 8003FFFF0000FFFFC007FFFF0000FFFFC007FFFF0000FFFFC007FFFF0000FFFF + E00FFFFF0000FFFFE00FFFFF0000FFFFF01FFFFF0000FFFFF01FFFFF0000FFFF + F83FFFFF0000FFFFF83FFFFF0000FFFFFCFFFFFF0000FFFFFFFFFFFF00002800 + 0000200000004000000001002000000000008010000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000F00000034000000340000003400000034000000340000 + 00340000003400000034000000340000002F00000000D3D3D30CC6C6C6180000 + 0003000000000000000000000000000000000000001700000034000000340000 + 0034000000340000003400000034000000340000003400000034000000340000 + 003400000034000002B4000006C0000006C0000006C0000006C0000006C00000 + 06C0000006C0000005C00000008649495C4B9191E6907D7DDFD97D7DCFE99494 + ADC17979794C000000070000000000000018020101B6050102C0050202C00502 + 02C0050202C0050202C0050202C0050302C0050302C0050303C0050303C00000 + 009500000038000010C5000052F70000B5FF0000FEFF0000FEFF0000FEFF0000 + ADFF00004EF6000026CF0000006EB2B2C715DDDDE1219E9EDB9B7B7BE5EF8C8C + D5EE9D9DAEEA6767676B00000009000000190E0305C2340F15E7842B35FFE353 + 5EFFE75D62FFEC6766FFF0726AFFF57C6DFFE27967FF6F3F33FE301B16D90100 + 008300000005000000000000000C000002900000A3FF0000FFFF0000C9FF0000 + 02B00000002C00000000000000000000000000000000CBCBCB0DACACD4C5B7B7 + E8E4CCCCD5E5999999E53F3F3F3C00000000000000000000000100000086A63F + 45FFE95F63FFED6967FFF2736AFFDD7063FF1F110EDE00000041000000000000 + 000000000000000000000000000000000001000013BE0000E6FF0000ADFF0000 + 0080000000340000000200000000000000000000000000000000B8B8BC37C8C8 + CFDAE8E8E8DDC6C6C6E86868689D3C3C3C190000000000000000000000539439 + 3EFFEA6164FFEE6B67FFF3756BFF4E2723F70000004D00000002000000000000 + 0000000000000000000000000000000000000000002C000069FC0000E8FF0000 + 05B700000038000000150000000000000000000000000000000000000000A8A8 + A831ADADADC6DCDCDCDF8C8C8CEA0505055A000000230000000002010196CB50 + 55FFEB6465FFEF6E68FFBA5B52FF000000A00000001700000000000000000000 + 0000000000000000000000000000000000000000000000000BAB0000E6FF0000 + 53F8000000480000002D00000000000000000000000000000000000000000000 + 00009393930D6F6F6FC46C6C77FB37374FE30000004B000000293C1719EEE85E + 62FFEC6866FFF1716AFF4A2421F7000000430000000200000000000000000000 + 0000000000000000000000000000000000000000000000000036000079FF0100 + BFFF0000009A000000380000000E000000000000000000000000000000000000 + 0000000000000707071A67676CE1BABADBFF252537CE0000008F9A3C41FFEA62 + 64FFEE6C67FFCD635BFF020101AD0000001D0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000040014C46300 + 90FF200016EC0000003E00000027000000000000000000000000000000000000 + 000000000000000000000000002F85858CF3A4A4C9FF1B151DFCD4565AFFEC67 + 66FFF07069FF67322EFE00000056000000060000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000547203 + 26FF7D052AFF00000083000000380000002C0000002C0000002C0000002C0000 + 002C0000002C0000002C0000002C05050570A1A1AAFD8A8AB2FF642E32FFE467 + 63FFE46E65FF0F0807C700000025000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000032303 + 0CDEC11144FF180309E4000000A3000000A3000000A3000000A3000000A30000 + 00A3000000A3000000A3000000A3000000A30F0D0EE4B7B7C4FF717095FF7F3D + 39FF82403AFF0000007B0000000C000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0071901434FFB81C43FFA91C3EFFAA1F3FFFAC2341FFAD2742FFAF2B44FFB230 + 46FFB43648FFB63C4AFFB9414CFFBC484EFFCB5356FF774244FFC5C5D7FF5B57 + 77FF130A08E80000005F00000013000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000E3A0B16F1C12748FF090203F3000000B5000000AD000000A0000000A00000 + 00A0000000A0000000A0000000A0000000DDB8504FFFEA6C66FF6F4F4FFFC8C8 + E1FF3D3D58EE0000005C0000003B000000100000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000100008FB02B44FF581722FD000000560000003200000001000000000000 + 0000000000000000000000000008371918E9EF6E68FFF3756BFFE47466FF5F58 + 5AFFC0C0DFFF2B2B3FD6000000440000003A0000000E00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000021541821FCBA384AFF020101AD0000003800000014000000000000 + 00000000000000000000000000609B4944FFF3766BFFF67D6EFFCD6C5DFF0100 + 00BF79797FF1ACACD0FF1B1B29BD0000003E000000390000000C000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000A0304ACCC4553FF45181DF7000000470000002D000000000000 + 000000000000000000001E0F0DCEEE756AFFF67E6FFFF98571FF63362DFD0000 + 0051020203479898A0FA9393BAFF0F0F17A00000003D000000380000000B0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000003C722B30FFAB4348FF00000097000000380000000E0000 + 0000000000000000003E7E4038FFF7806FFFFA8772FFE9826BFF0C0706C20000 + 00230000000012121365B0B0BCFF7979A0FE050508810000003D000000370000 + 0009000000000000000000000000000000000000000000000000000000000000 + 000000000000000000001A0B0BCAE36162FF311615EB0000003D000000270000 + 0000000000000C0605ADE47967FFFB8973FFFD8E75FF864C3EFF0000006B0000 + 000B00000000000000002424278DC1C1D1FF606083F8000000640000003D0000 + 0036000000070000000000000000000000000000000000000000000000000000 + 0000000000000000000000000059934440FF994843FF00000081000000370000 + 00080000002061352CFCFD8C74FFFE9075FFF98D73FF21130FDC0000002B0000 + 00000000000000000000000000033A3A3DB3C8C8DFFF484865EB0000004D0000 + 003D000000210000000000000000000000000000000000000000000000000000 + 0000000000000000000000000005301815E2EF7A6BFF1E100DDA000000380000 + 00200100008CCF755FFFFE9075FFFE9075FFA85F4DFF00000086000000120000 + 00000000000000000000000000000000000D535357D1C4C4E1FF33334AD50000 + 0024000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000076B76353FF84493CFF0000006C0000 + 003F44261FEFFE9075FFFE9075FFFE9075FF3E231CF000000038000000010000 + 0000000000000000000000000000000000000000001F707075E7B4B4D6FF2323 + 34B5000000030000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000114C2B23F4EC866DFF0E0806C40000 + 008BAE6250FFFE9075FFFE9075FFCA725DFF000000A10000001A000000000000 + 000000000000000000000000000000000000000000000000013867676CF51B1B + 238D000000050000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000003010194D57962FF6A3C31FE2414 + 11EAFB8E74FFFE9075FFFE9075FF5D352BFC0000004C00000004000000000000 + 00000000000000000000000000000000000000000000000000000000001A0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000025673B30FDD87B64FF8E51 + 42FFFE9075FFFE9075FFE6826AFF090504BC0000002100000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000E0806B2EB856CFFFB8E + 74FFFE9075FFFE9075FF7E483AFF000000650000000900000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000041844B3DFFFE90 + 75FFFE9075FFF78C72FF1C100DD6000000290000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000020120FCFF88D + 72FFFE9075FFA05B4AFF00000080000000110000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000005EA15B + 4AFFFE9075FF371F19EC00000035000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000000000007371F + 19E6C26E59FF0000009B00000018000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00771E110EEA0000002400000002000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000FFFFFFFF0013E0000000C0000000400180F03807E0F8180FE07C + 080FF07E001FF03F001FF83F803FF800003FFC00003FFC00003FFC00001FFE0F + C00FFE078007FF078003FF030103FF830181FF8203C0FFC003C1FFC007E1FFC0 + 07F1FFE00FFBFFE00FFFFFF01FFFFFF01FFFFFF81FFFFFF83FFFFFFC3FFFFFFC + 7FFFFFFFFFFF2800000010000000200000000100200000000000400400000000 + 0000000000000000000000000000000000110000001A0000001A0000001A0000 + 001A0000000C000000090000000100000000000000060000001A0000001A0000 + 001A0000001A0000001A0000001A00001ECC00007EE0000093E000004ADD0000 + 0EA18989BD448383DBD39191B5B96666671F0702036A361116DA853338E08A3F + 3CE088473DE0301B16D6000000550000000300004D940000D7FF000001640000 + 000000000000B0B0CF42CCCCDDE0959595AA0000000600000036C34E52FFF06F + 69FF67342EC80000001100000000000000000000000B00009DE90000268C0000 + 00100000000000000000ABABAB41909093E21E1E2B6B220D0E6BE35E61FFBA58 + 52FD0000003F000000000000000000000000000000000200457E250065E10000 + 002B0000000000000000000000004E4E524A87879FF06F2F34E2ED6967FF6732 + 2DC0000000090000000000000000000000000000000000000016780729F70A01 + 0390000000670000006700000067000000673B3A3EBD86788FFFB2544FFF0804 + 045D000000000000000000000000000000000000000000000000510C1E9C8C18 + 34FC651326D86B1929CF6E1F2BCF71262ECF953D3FF7A57174FF5F5C71F50000 + 00420000000400000000000000000000000000000000000000000100002C8624 + 34FE0100005B00000005000000000000001AB0534DF9E67567FF6D6B75EB5050 + 66B6000000300000000300000000000000000000000000000000000000007028 + 2EB9542023B50000001D0000000049252183F67F6EFF9D5648EF0101012F8E8E + 9FD738384B970000002E00000002000000000000000000000000000000001207 + 084992423FFA000000470000000A9F5749EAFC8D74FF42251E9C000000032424 + 26248F8FA4EA2424327600000027000000000000000000000000000000000000 + 00018B483ED63F221D9F22131076F28970FFBA6A56FB00000034000000000000 + 00004545483F8B8BA2EF1D1D2B37000000000000000000000000000000000000 + 00002E1A1566965545F0844B3DDDFE9075FF65392EBA00000007000000000000 + 0000000000004D4D52521A1A2224000000000000000000000000000000000000 + 000000000009995746EBE18068FFD87A63FF0503025300000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000004C2B2384FC8F74FF81493BD50000000E00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000019A9604EF91C100D750000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000140B09580000000A0000000000000000000000000000 + 000000000000000000000000000003C00000000000008C41000086030000C707 + 0000C0070000E0070000E3030000F1010000F0100000F8180000F83C0000FC3F + 0000FC3F0000FC7F0000FE7F0000280000002000000040000000010008000000 + 0000800400000000000000000000000000000000000000000000000080000080 + 000000808000800000008000800080800000C0C0C000C0DCC000F0CAA6000000 + 0A0000000B0000000C0000000D0000000E0000000F0000002000000040000000 + 600000007F000000A0000000C0000000E0000000FE001C1CFF003838FF005454 + FF007070FF008C8CFF00A8A8FF00C4C4FF00E0E0FF0000200000004000000060 + 0000007F000000A0000000C0000000E0000000FE00001CFF1C0038FF380054FF + 540070FF70008CFF8C00A8FFA800C4FFC400E0FFE00020000000400000006000 + 00007F000000A0000000C0000000E0000000FE000000FF1C1C00FF383800FF54 + 5400FF707000FF8C8C00FFA8A800FFC4C400FFE0E00000202000004040000060 + 6000007F7F0000A0A00000C0C00000E0E00000FEFE001CFFFF0038FFFF0054FF + FF0070FFFF008CFFFF00A8FFFF00C4FFFF00E0FFFF0020200000404000006060 + 00007F7F0000A0A00000C0C00000E0E00000FEFE0000FFFF1C00FFFF3800FFFF + 5400FFFF7000FFFF8C00FFFFA800FFFFC400FFFFE00020002000400040006000 + 60007F007F00A000A000C000C000E000E000FE00FE00FF1CFF00FF38FF00FF54 + FF00FF70FF00FF8CFF00FFA8FF00FFC4FF00FFE0FF004F8FCF005F9FDF006FAF + EF007FBFFF008FC9FF009FD3FF00AFDDFF00BFE7FF00004080001F578F003F6F + 9F005F87AF007F9FBF009FB7CF00BFCFDF00DFE7EF00FF800000FF8F1F00FF9F + 3F00FFAF5F00FFBF7F00FFCF9F00FFDFBF00FFEFDF00804000008F571F009F6F + 3F00AF875F00BF9F7F00CFB79F00DFCFBF00EFE7DF00FF008000FF1F8F00FF3F + 9F00FF5FAF00FF7FBF00FF9FCF00FFBFDF00FFDFEF00800040008F1F57009F3F + 6F00AF5F8700BF7F9F00CF9FB700DFBFCF00EFDFE70000FF80001FFF8F003FFF + 9F005FFFAF007FFFBF009FFFCF00BFFFDF00DFFFEF00008040001F8F57003F9F + 6F005FAF87007FBF9F009FCFB700BFDFCF00DFEFE7002B66FF003C76FF004D86 + FF005F96FF0070A7FF0082B7FF0093C7FF00A5D8FF00804080008F578F009F6F + 9F00AF87AF00BF9FBF00CFB7CF00DFCFDF00EFE7EF0080FF00008FFF1F009FFF + 3F00AFFF5F00BFFF7F00CFFF9F00DFFFBF00EFFFDF0040800000578F1F006F9F + 3F0087AF5F009FBF7F00B7CF9F00CFDFBF00E7EFDF0000520000004B24000045 + 4800003F6D00003891000032B600002CDA000026FF000050FF00007AFF0000A4 + FF0010CEFF0040F8FF006FFFFF00A0FFFF00D0FFFF0010101000202020003030 + 3000404040005050500060606000707070007F7F7F0090909000A0A0A000B0B0 + B000C0C0C000D0D0D000E0E0E000F0F0F000FEFEFE000000F8000000FD000000 + FC000000FB000000FA000000F900F0FBFF00A4A0A000808080000000FF0000FF + 000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00181818181B000000000000000000000000000000000000161A1A1A1A1A1600 + 00001818191B1CEA000000353D3D3D3D3D3D35000000000000161A1A1A160000 + 000000191B1DECECEA0000003C3D3D3D3D350000000000000000161A16000000 + 000000001DEDEDEBEA000000003D3D3D3A00000000000000000000161A000000 + 0000000000ECEDEDE3000000003D3D3C3500000000000000000000181A000000 + 000000000000ECE3E3E20000353D3D3A0000000000000000000000141A140000 + 0000000000000000E3EBE2003A3D3D3500000000000000000000000018170000 + 000000000000000000E7EBE23A3A3C00000000000000000000000000141A0000 + 00000000000000000000E7EBE23A3A00000000000000000000000000001A1400 + 0000000000000000000000E7EBE2350000000000000000000000000000171700 + 00000000000000000000353DE7EBE20000000000000000000000000000143D3D + 3D3D3D3D3D3D3D3D3D3D3D3D3DE7EBE200000000000000000000000000003D3B + 000000000000000000003D3D3D35E7EBE2000000000000000000000000003B3D + 000000000000000000353D3D3D0000E7EBE2000000000000000000000000003D + 3B00000000000000003A3D3D35000000E7EBE20000000000000000000000003C + 3C00000000000000003C3D3C0000000000E7EBE200000000000000000000003B + 3D3B000000000000353D3D3A000000000000E7EBE20000000000000000000000 + 3C3C0000000000003A3D3D3500000000000000E7000000000000000000000000 + 3B3D0000000000353D3D3C000000000000000000000000000000000000000000 + 003C3B000000003A3D3D3A000000000000000000000000000000000000000000 + 003C3C000000003C3D3C35000000000000000000000000000000000000000000 + 003B3D000000353D3D3A00000000000000000000000000000000000000000000 + 00003C3B00003A3D3D3500000000000000000000000000000000000000000000 + 00003B3D00003D3D3C0000000000000000000000000000000000000000000000 + 0000003C3D353D3D3A0000000000000000000000000000000000000000000000 + 0000003A3D3D3D3D350000000000000000000000000000000000000000000000 + 000000393D3D3D3A000000000000000000000000000000000000000000000000 + 00000000383D3D35000000000000000000000000000000000000000000000000 + 0000000000383D00000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000FFFFFFFF8020F0038030 + 300380381003C07C1807E0FE180FF07F080FF07FC01FF07FE01FF83FF03FF83F + E03FFC00003FFC00003FFC00001FFE0FC00FFE0FC0C7FF0780E3FF0781F1FF07 + 01FBFF8301FFFF8303FFFFC203FFFFC003FFFFC007FFFFE007FFFFE00FFFFFF0 + 0FFFFFF00FFFFFF01FFFFFF81FFFFFFC3FFFFFFFFFFF28000000100000002000 + 0000010008000000000040010000000000000000000000000000000000000000 + 009F000080FF008000EF0080801F8000009F800080878080009FC0C0C0DFC0DC + C0E7F0CAA62400000A4500000B0000000CB600000D2C00000E0000000FFF0000 + 20A400004010000060FF00007FFF0000A0D00000C0200000E0300000FE401C1C + FF603838FF705454FF7F7070FFA08C8CFFB0A8A8FFC0C4C4FFE0E0E0FFF00020 + 00FE004000FD00600000007F000000A000F900C000FB00E000A400FE00FF1CFF + 1CFF38FF380054FF54FF70FF70FF8CFF8CFFA8FFA861C4FFC430E0FFE0002000 + 000040000000600000007F000000A0000000C0000000E0000000FE000000FF1C + 1C00FF383800FF545400FF7070FFFF8C8CFFFFA8A8FFFFC4C4FFFFE0E0FF0020 + 20FF0040400000606000007F7F0000A0A00000C0C00000E0E00A00FEFE191CFF + FF0238FFFF0054FFFF0070FFFF008CFFFF00A8FFFF00C4FFFF00E0FFFF2A2020 + 001740400002606000007F7F0000A0A00000C0C00000E0E00000FEFE0000FFFF + 1C57FFFF3813FFFF5402FFFF7000FFFF8C00FFFFA800FFFFC400FFFFE0012000 + 2000400040276000600C7F007F39A000A000C000C000E000E000FE00FE00FF1C + FF01FF38FF00FF54FF4BFF70FF0BFF8CFF02FFA8FF00FFC4FF00FFE0FF004F8F + CFFF5F9FDF396FAFEFFF7FBFFF398FC9FF3D9FD3FF3AAFDDFF3ABFE7FF390040 + 80FF1F578F393F6F9FFF5F87AFFF7F9FBFFF9FB7CF3ABFCFDF3ADFE7EFFFFF80 + 00FFFF8F1F39FF9F3FFFFFAF5FFFFFBF7F39FFCF9FFFFFDFBF3DFFEFDFFF8040 + 003A8F571F399F6F3F02AF875F39BF9F7FFFCFB79FFFDFCFBFFFEFE7DF39FF00 + 8002FF1F8F02FF3F9F02FF5FAF02FF7FBFFFFF9FCFFFFFBFDF02FFDFEF398000 + 40028F1F57E79F3F6F02AF5F8702BF7F9FFFCF9FB7FFDFBFCF02EFDFE73900FF + 80021FFF8FEB3FFF9F025FFFAF027FFFBFFF9FFFCF02BFFFDF02DFFFEF390080 + 40021F8F57E23F9F6F025FAF87027FBF9F3D9FCFB702BFDFCF02DFEFE7392B66 + FFFF3C76FF024D86FF025F96FF0270A7FF3982B7FFFF93C7FFFFA5D8FF398040 + 80E78F578F1D9F6F9FE7AF87AF1CBF9FBFE7CFB7CFFFDFCFDFFFEFE7EF0280FF + 00028FFF1FE79FFF3FEBAFFF5FFFBFFF7F02CFFF9F02DFFFBFE7EFFFDF364080 + 0002578F1F026F9F3FFF87AF5FFF9FBF7F02B7CF9F02CFDFBFEBE7EFDF390052 + 0002004B2402004548FF003F6DFF003891020032B602002CDAE20026FF390050 + FF02007AFF0200A4FFFF10CEFFFF40F8FF026FFFFFECA0FFFF02D0FFFF391010 + 100220202002303030FF4040400250505002606060FF707070027F7F7F399090 + 9002A0A0A002B0B0B01DC0C0C0FFD0D0D002E0E0E0FFF0F0F002FEFEFE390000 + F8FF0000FD020000FC1A0000FBFF0000FA020000F9FFF0FBFFFFA4A0A0398080 + 80FF0000FF0200FF001A00FFFF1DFF000018FF00FF1CFFFF00FFFFFFFF390000 + 00000018171B1D1F000000000000E2E2E2E2E2E21B1D1FEAE2E2E2E2E200E21A + 1A1A1AE2001FEAEBE43B3D3DE200E2E21A1AE2E2000000E7EBE43BE2E20000E2 + 1A1AE2E2000000E2E7EBE4E2000000E2E21A1AE2E2E2E2E23DE7EBE400000000 + E21A3D3D3D3D3D3D3D3DE7EBE4000000E2E23D3BE2E2E23B3DE2E2E7EBE40000 + 00E23B3DE200E23D3BE20000E700000000E23A3DE2E2E23D3AE2000000000000 + 00E2E23B3BE23B3DE2E20000000000000000E23A3DE23D3BE200000000000000 + 0000E2E23D3D3D3AE200000000000000000000E23B3D3BE2E200000000000000 + 000000E23A3D3AE20000000000000000000000E2E2E2E2E2000000000000F83F + 00000001000002010000038100008383000080030000C0010000C0000000E10D + 0000E00F0000E00F0000F01F0000F01F0000F81F0000F83F0000F83F0000} + OldCreateOrder = False + Position = poDefaultPosOnly + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 12 + object FontGroupBox: TGroupBox + Left = 8 + Top = 8 + Width = 377 + Height = 137 + Caption = 'フォント(&F)' + TabOrder = 0 + object Label1: TLabel + Left = 8 + Top = 20 + Width = 76 + Height = 12 + Caption = 'フォント名(&N) : ' + FocusControl = FontSelectComboBox + end + object Label2: TLabel + Left = 8 + Top = 68 + Width = 108 + Height = 12 + Caption = 'サイズ(文字高さ)(&S) :' + end + object Label3: TLabel + Left = 200 + Top = 68 + Width = 43 + Height = 12 + Caption = 'ピクセル' + end + object FontSelectComboBox: TComboBox + Left = 88 + Top = 16 + Width = 273 + Height = 20 + Style = csDropDownList + DropDownCount = 20 + ItemHeight = 12 + TabOrder = 0 + OnChange = FontSelectComboBoxChange + end + object SizeEdit: TEdit + Left = 128 + Top = 64 + Width = 49 + Height = 20 + TabOrder = 2 + Text = '24' + OnChange = SizeEditChange + end + object SizeUpDown: TUpDown + Left = 177 + Top = 64 + Width = 15 + Height = 20 + Associate = SizeEdit + Min = 1 + Max = 300 + Position = 24 + TabOrder = 3 + Wrap = False + end + object BoldCheckBox: TCheckBox + Left = 160 + Top = 88 + Width = 81 + Height = 17 + Caption = '太字(&B)' + TabOrder = 5 + OnClick = BoldCheckBoxClick + end + object ShowSampleButton: TButton + Left = 256 + Top = 64 + Width = 105 + Height = 20 + Caption = 'サンプルを表示(&V)' + TabOrder = 7 + OnClick = ShowSampleButtonClick + end + object IncludeAllFontCharsCheckBox: TCheckBox + Left = 8 + Top = 104 + Width = 233 + Height = 17 + Caption = 'フォント内のすべての文字を含める(&U)' + Enabled = False + TabOrder = 6 + OnClick = IncludeAllFontCharsCheckBoxClick + end + object AntialiasedCheckBox: TCheckBox + Left = 8 + Top = 88 + Width = 145 + Height = 17 + Caption = 'アンチエイリアス(&A)' + Checked = True + State = cbChecked + TabOrder = 4 + OnClick = AntialiasedCheckBoxClick + end + object ShowAllFontsCheckBox: TCheckBox + Left = 88 + Top = 40 + Width = 265 + Height = 17 + Caption = 'すべての TrueType フォントを表示(&T)' + TabOrder = 1 + OnClick = ShowAllFontsCheckBoxClick + end + object IncludePrivateCharsCheckBox: TCheckBox + Left = 248 + Top = 104 + Width = 121 + Height = 17 + Caption = '外字を含める(&P)' + Checked = True + State = cbChecked + TabOrder = 8 + OnClick = IncludePrivateCharsCheckBoxClick + end + end + object OutputGroupBox: TGroupBox + Left = 8 + Top = 152 + Width = 377 + Height = 65 + Caption = '出力ファイル(&O)' + TabOrder = 1 + object OutputEdit: TEdit + Left = 8 + Top = 26 + Width = 273 + Height = 20 + TabOrder = 0 + end + object OutputRefButton: TButton + Left = 288 + Top = 26 + Width = 75 + Height = 20 + Caption = '参照(&R) ...' + TabOrder = 1 + OnClick = OutputRefButtonClick + end + end + object CreateButton: TButton + Left = 216 + Top = 224 + Width = 75 + Height = 25 + Caption = '作成(&G) ...' + Default = True + TabOrder = 2 + OnClick = CreateButtonClick + end + object CancelButton: TButton + Left = 304 + Top = 224 + Width = 75 + Height = 25 + Caption = '閉じる(&C)' + TabOrder = 3 + OnClick = CancelButtonClick + end + object SaveDialog: TSaveDialog + DefaultExt = 'tft' + Filter = '吉里吉里 pre-rendered font (*.tft)|*.tft' + Options = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofEnableSizing] + Title = '出力ファイル ...' + Left = 320 + Top = 144 + end +end diff --git a/tools/win32/krdevui/FontMakerUnit.h b/tools/win32/krdevui/FontMakerUnit.h new file mode 100644 index 0000000..e448c24 --- /dev/null +++ b/tools/win32/krdevui/FontMakerUnit.h @@ -0,0 +1,98 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef FontMakerUnitH +#define FontMakerUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include "FontPreviewUnit.h" +//--------------------------------------------------------------------------- +extern DWORD WINAPI (*procGetFontUnicodeRanges)(HDC, LPGLYPHSET); +extern DWORD WINAPI (*procGetGlyphOutlineW)(HDC, UINT, UINT, LPGLYPHMETRICS, DWORD, LPVOID, CONST MAT2 *); +extern BOOL WINAPI (*procTextOutW)(HDC, int, int, LPCWSTR, int); +extern BOOL APIENTRY (*procGetTextExtentPoint32W)(HDC, LPCWSTR, int, LPSIZE); +//--------------------------------------------------------------------------- +class TPrivRefControl : public TCustomControl +{ + // a class to provide Canvas and window handle +public: + __fastcall TPrivRefControl(TComponent *AOwner) : TCustomControl(AOwner) {;} + __fastcall ~TPrivRefControl() {;} + +public: + __property Canvas; +}; +//--------------------------------------------------------------------------- +class TFontMakerForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TGroupBox *FontGroupBox; + TLabel *Label1; + TComboBox *FontSelectComboBox; + TLabel *Label2; + TEdit *SizeEdit; + TUpDown *SizeUpDown; + TCheckBox *BoldCheckBox; + TButton *ShowSampleButton; + TGroupBox *OutputGroupBox; + TEdit *OutputEdit; + TButton *OutputRefButton; + TLabel *Label3; + TButton *CreateButton; + TButton *CancelButton; + TCheckBox *IncludeAllFontCharsCheckBox; + TCheckBox *AntialiasedCheckBox; + TSaveDialog *SaveDialog; + TCheckBox *ShowAllFontsCheckBox; + TCheckBox *IncludePrivateCharsCheckBox; + void __fastcall OutputRefButtonClick(TObject *Sender); + void __fastcall CreateButtonClick(TObject *Sender); + void __fastcall CancelButtonClick(TObject *Sender); + void __fastcall ShowAllFontsCheckBoxClick(TObject *Sender); + void __fastcall ShowSampleButtonClick(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall FontSelectComboBoxChange(TObject *Sender); + void __fastcall SizeEditChange(TObject *Sender); + void __fastcall BoldCheckBoxClick(TObject *Sender); + void __fastcall AntialiasedCheckBoxClick(TObject *Sender); + void __fastcall IncludeAllFontCharsCheckBoxClick(TObject *Sender); + void __fastcall IncludePrivateCharsCheckBoxClick(TObject *Sender); +private: // ユーザー宣言 + TFontPreviewForm *FontPreviewForm; + void __fastcall EnumFonts(); + bool CharacterListInvalidated; + wchar_t * CharacterList; + int CharacterListCount; + TPrivRefControl * PrivRefControl; + + +public: // ユーザー宣言 + __fastcall TFontMakerForm(TComponent* Owner); +private: + void __fastcall SetFontToCanvas(LOGFONT & font); + void __fastcall SetPrivFontToPrivCanvas(); + void __fastcall NotifyFontChanged(); + + static int __cdecl CodeComparison(const void *s1, const void *s2); + void __fastcall PushDBCSCharacter(int code); + void __fastcall PushCharacterRange(int base, int count); + void __fastcall CreateCharacterList(); +public: + int __fastcall GetCharacterListCount(); + const wchar_t * __fastcall GetCharacterList(); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFontMakerForm *FontMakerForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/FontMakerWriteUnit.cpp b/tools/win32/krdevui/FontMakerWriteUnit.cpp new file mode 100644 index 0000000..1111b3d --- /dev/null +++ b/tools/win32/krdevui/FontMakerWriteUnit.cpp @@ -0,0 +1,333 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "FontMakerWriteUnit.h" +#include "FontMakerUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TFontMakerWriteForm *FontMakerWriteForm; + +//--------------------------------------------------------------------------- +static void ExpandLine + (unsigned char *dest, const unsigned char *buf, int len) +{ + unsigned char *d=dest, *dlim; + unsigned char b; + + dlim = dest + len-7; + while(d < dlim) + { + b = *(buf++); + d[0] = (b&0x80) ? 64 : 0; + d[1] = (b&0x40) ? 64 : 0; + d[2] = (b&0x20) ? 64 : 0; + d[3] = (b&0x10) ? 64 : 0; + d[4] = (b&0x08) ? 64 : 0; + d[5] = (b&0x04) ? 64 : 0; + d[6] = (b&0x02) ? 64 : 0; + d[7] = (b&0x01) ? 64 : 0; + d += 8; + } + dlim = dest + len; + b = *buf; + while(d= 2) + { + while(count) + { + int len = count > 190 ? 190 : count; + newbuf[newsize++] = 0x40 + len; // running + count -= len; + } + } + else + { + while(count--) + newbuf[newsize++] = last; + } + count = 0; + newbuf[newsize++] = buf[i]; + } + last = buf[i]; + } + + if(count >= 2) + { + while(count) + { + int len = count > 190 ? 190 : count; + newbuf[newsize++] = 0x40 + len; // running + count -= len; + } + } + else + { + while(count--) + newbuf[newsize++] = last; + } + + try + { + out->WriteBuffer(newbuf, newsize); + } + catch(...) + { + delete [] newbuf; + throw; + } + delete [] newbuf; +} +//--------------------------------------------------------------------------- +__fastcall TFontMakerWriteForm::TFontMakerWriteForm(TComponent* Owner, + AnsiString filename, + TCanvas * targetcanvas, TCanvas * privtargetcanvas, + bool antialiased, bool vertical, const wchar_t *list, + int listcount) : TForm(Owner) +{ + Canceled = false; + TargetCanvas = targetcanvas; + PrivTargetCanvas = privtargetcanvas; + Antialiased = antialiased; + Vertical = vertical; + CharacterList = list; + CharacterListCount = listcount; + + FileName = filename; + OutStream = new TFileStream(filename, fmCreate|fmShareDenyWrite); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerWriteForm::FormDestroy(TObject *Sender) +{ + delete OutStream; + if(Canceled) DeleteFile(FileName); +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerWriteForm::CancelButtonClick(TObject *Sender) +{ + Canceled = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerWriteForm::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + Canceled = true; + CanClose = false; +} +//--------------------------------------------------------------------------- +void __fastcall TFontMakerWriteForm::TimerTimer(TObject *Sender) +{ + Timer->Enabled = false; + CancelButton->Enabled = true; + + // write header + OutStream->WriteBuffer("TVP pre-rendered font\x1a\x01\x02", 24); + // header + version + sizeof(wchar_t) + OutStream->WriteBuffer(" ", 12); + // count/offset to chindex/offset to index + + // make table + // make SJIS table + + // ASCII and kana + for(int i = 0; i < CharacterListCount; i++) + { + TCharacterItem item; + item.Code = CharacterList[i]; + Items.push_back(item); + } + + // sort table + std::sort(Items.begin(), Items.end()); + + // create each font + std::vector::iterator i; + int count = 0; + for(i = Items.begin(); i != Items.end(); i++, count++) + { + // process messages + ProgressBar->Position = count * 100 / Items.size(); + + Application->ProcessMessages(); + if(Canceled) + { + OnCloseQuery = NULL; + ModalResult = mrCancel; + return; + } + + // retrieve character metrics + GLYPHMETRICS gm; + ZeroMemory(&gm, sizeof(gm)); + static MAT2 no_transform_affin_matrix = { {0,1}, {0,0}, {0,0}, {0,1} }; + + UINT format = Antialiased ? GGO_GRAY8_BITMAP : GGO_BITMAP; + int size; + wchar_t code = i->Code; + int pitch; + int ncode = code; + + if(!procGetGlyphOutlineW) + { + unsigned char temp[4]; + int nch = WideCharToMultiByte(CP_ACP, 0, &code, 1, (char*)temp, 4, 0, NULL); + if(nch == 2) ncode = temp[1] + (temp[0] << 8); else ncode = temp[0]; + } + + HDC dc = (code >= 0xe000 && code <= 0xf8ff) ? + PrivTargetCanvas->Handle : TargetCanvas->Handle; + + if(procGetGlyphOutlineW) + size = procGetGlyphOutlineW(dc, ncode, format, + &gm, 0, NULL, &no_transform_affin_matrix); + else + size = GetGlyphOutline(dc, ncode, format, + &gm, 0, NULL, &no_transform_affin_matrix); + + + SIZE incsz; + procGetTextExtentPoint32W(dc, &code, 1, &incsz); + int inc = incsz.cx; + + // setup structure members + i->Offset = OutStream->Position; + i->Width = size?gm.gmBlackBoxX:0; + i->Height = size?gm.gmBlackBoxY:0; + i->IncX = gm.gmCellIncX; + i->IncY = gm.gmCellIncY; + i->OriginX = gm.gmptGlyphOrigin.x; + i->OriginY = gm.gmptGlyphOrigin.y; + i->Inc = inc; + + if(size && gm.gmBlackBoxX && gm.gmBlackBoxY) + { + if(Antialiased) + pitch = (size / gm.gmBlackBoxY) & ~0x03; // data is aligned to DWORD + else + pitch = (((gm.gmBlackBoxX -1)>>5)+1)<<2; // data is aligned to DWORD + + // retrieve font data + unsigned char *buf = new unsigned char[size]; + + if(procGetGlyphOutlineW) + procGetGlyphOutlineW(dc, ncode, format, + &gm, size, buf, &no_transform_affin_matrix); + else + GetGlyphOutline(dc, ncode, format, + &gm, size, buf, &no_transform_affin_matrix); + + + // expand if not antialiased + if(!Antialiased) + { + int newsize = gm.gmBlackBoxX * gm.gmBlackBoxY; + + unsigned char *newbuf = new unsigned char[newsize]; + unsigned char *np = newbuf; + unsigned char *p = buf; + int h = gm.gmBlackBoxY; + while(h--) + { + ExpandLine(np, p, gm.gmBlackBoxX); + np += gm.gmBlackBoxX, p += pitch; + } + pitch = gm.gmBlackBoxX; + delete [] buf; + buf = newbuf; + size = newsize; + } + else + { + // or stuff data + int h = i->Height; + unsigned char *np; + unsigned char *p; + np = p = buf; + while(h--) + { + if(np != p) memmove(np, p, i->Width); + np += i->Width; + p += pitch; + } + pitch = i->Width; + size = gm.gmBlackBoxX * gm.gmBlackBoxY; + } + + // write data + try + { + if(size) WriteDataCompress(OutStream, buf, size); + } + catch(...) + { + delete [] buf; + throw; + } + delete [] buf; + } + } + + // write character index/ index data + + int chindexpos = OutStream->Position; + OutStream->WriteBuffer("\0\0\0\0", 4 - (chindexpos % 4)); // align + chindexpos = OutStream->Position; + for(i = Items.begin(); i != Items.end(); i++) + { + OutStream->WriteBuffer(&(i->Code), sizeof(wchar_t)); + } + + int indexpos = OutStream->Position; + OutStream->WriteBuffer("\0\0\0\0", 4 - (indexpos % 4)); // align + indexpos = OutStream->Position; + for(i = Items.begin(); i != Items.end(); i++) + { + OutStream->WriteBuffer( + (unsigned char *)&(*i) + sizeof(wchar_t), + sizeof(TCharacterItem) - sizeof(wchar_t)); + } + + OutStream->Position = 24; + OutStream->WriteBuffer(&count, 4); + OutStream->WriteBuffer(&chindexpos, 4); + OutStream->WriteBuffer(&indexpos, 4); + + OnCloseQuery = NULL; + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/FontMakerWriteUnit.dfm b/tools/win32/krdevui/FontMakerWriteUnit.dfm new file mode 100644 index 0000000..1776995 --- /dev/null +++ b/tools/win32/krdevui/FontMakerWriteUnit.dfm @@ -0,0 +1,46 @@ +object FontMakerWriteForm: TFontMakerWriteForm + Left = 104 + Top = 188 + BorderStyle = bsDialog + Caption = '作成中 ...' + ClientHeight = 64 + ClientWidth = 227 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poMainFormCenter + OnCloseQuery = FormCloseQuery + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 12 + object ProgressBar: TProgressBar + Left = 9 + Top = 8 + Width = 209 + Height = 16 + Min = 0 + Max = 100 + TabOrder = 0 + end + object CancelButton: TButton + Left = 76 + Top = 32 + Width = 75 + Height = 25 + Cancel = True + Caption = 'キャンセル' + Enabled = False + TabOrder = 1 + OnClick = CancelButtonClick + end + object Timer: TTimer + Interval = 100 + OnTimer = TimerTimer + Left = 16 + Top = 40 + end +end diff --git a/tools/win32/krdevui/FontMakerWriteUnit.h b/tools/win32/krdevui/FontMakerWriteUnit.h new file mode 100644 index 0000000..3529c04 --- /dev/null +++ b/tools/win32/krdevui/FontMakerWriteUnit.h @@ -0,0 +1,69 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef FontMakerWriteUnitH +#define FontMakerWriteUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#include +//--------------------------------------------------------------------------- +#pragma pack(push, 1) +struct TCharacterItem +{ + wchar_t Code; + unsigned __int32 Offset; + unsigned __int16 Width; + unsigned __int16 Height; + __int16 OriginX; + __int16 OriginY; + __int16 IncX; + __int16 IncY; + __int16 Inc; + __int16 Reserved; +}; +#pragma pack(pop) +inline bool operator <(const TCharacterItem &x, const TCharacterItem &y) +{ return x.Code< y.Code; } +//--------------------------------------------------------------------------- +class TFontMakerWriteForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TProgressBar *ProgressBar; + TButton *CancelButton; + TTimer *Timer; + void __fastcall CancelButtonClick(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall TimerTimer(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); +private: // ユーザー宣言 + AnsiString FileName; + bool Canceled; + TCanvas *TargetCanvas; + TCanvas *PrivTargetCanvas; + const wchar_t *CharacterList; + int CharacterListCount; + bool Antialiased; + bool Vertical; + TStream * OutStream; + std::vector Items; +public: // ユーザー宣言 + __fastcall TFontMakerWriteForm(TComponent* Owner, + AnsiString outfile, TCanvas * font, TCanvas * privfont, + bool antialiased, bool vertical, const wchar_t *list, int listcount); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFontMakerWriteForm *FontMakerWriteForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/FontPreviewUnit.cpp b/tools/win32/krdevui/FontPreviewUnit.cpp new file mode 100644 index 0000000..a16f32d --- /dev/null +++ b/tools/win32/krdevui/FontPreviewUnit.cpp @@ -0,0 +1,515 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "FontPreviewUnit.h" +#include "FontMakerUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TFontPreviewForm *FontPreviewForm; +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +static void __fastcall SetGrayscalePalette(Graphics::TBitmap *dib) +{ + int psize; + int icol; + + psize = 256; + + icol = 255/(psize-1); + + int i; + int c = 0; + +#pragma pack(push, 1) + + struct + { + WORD v; + WORD n; + PALETTEENTRY entry[256]; + } paldata; + +#pragma pack(pop) + + paldata.v = 0x300; + paldata.n = 256; + + for(i = 0; i < psize; i++) + { + if(c >= 256) c = 255; + paldata.entry[i].peRed = paldata.entry[i].peGreen = paldata.entry[i].peBlue = (BYTE)c; + paldata.entry[i].peFlags = 0; + c += icol; + } + dib->Palette = CreatePalette((const LOGPALETTE*)&paldata); +} +//--------------------------------------------------------------------------- +static Graphics::TBitmap * GetGlyphBitmap(wchar_t code, TCanvas *refcanvas, + bool antialiased) +{ + // retrieve character metrics + GLYPHMETRICS gm; + ZeroMemory(&gm, sizeof(gm)); + static MAT2 no_transform_affin_matrix = { {0,1}, {0,0}, {0,0}, {0,1} }; + + UINT format = antialiased ? GGO_GRAY8_BITMAP : GGO_BITMAP; + int size; + int pitch; + + int ncode = code; + + if(!procGetGlyphOutlineW) + { + unsigned char temp[4]; + int nch = WideCharToMultiByte(CP_ACP, 0, &code, 1, (char*)temp, 4, 0, NULL); + if(nch == 2) ncode = temp[1] + (temp[0] << 8); else ncode = temp[0]; + } + + if(procGetGlyphOutlineW) + size = procGetGlyphOutlineW(refcanvas->Handle, ncode, format, + &gm, 0, NULL, &no_transform_affin_matrix); + else + size = GetGlyphOutline(refcanvas->Handle, ncode, format, + &gm, 0, NULL, &no_transform_affin_matrix); + + if(!size || !gm.gmBlackBoxX || !gm.gmBlackBoxY) return NULL; + + // create bitmap + Graphics::TBitmap *bmp = new Graphics::TBitmap(); + bmp->PixelFormat = pf8bit; + bmp->Width = gm.gmBlackBoxX; + bmp->Height = gm.gmBlackBoxY; + SetGrayscalePalette(bmp); + + if(antialiased) + pitch = (size / gm.gmBlackBoxY) & ~0x03; // data is aligned to DWORD + else + pitch = (((gm.gmBlackBoxX -1)>>5)+1)<<2; // data is aligned to DWORD + + // retrieve font data + unsigned char *buf = new unsigned char[size]; + + if(procGetGlyphOutlineW) + procGetGlyphOutlineW(refcanvas->Handle, ncode, format, + &gm, size, buf, &no_transform_affin_matrix); + else + GetGlyphOutline(refcanvas->Handle, ncode, format, + &gm, size, buf, &no_transform_affin_matrix); + + + // expand + if(!antialiased) + { + unsigned char *p = buf; + for(unsigned int y = 0; y < gm.gmBlackBoxY; y++) + { + unsigned char *d = (unsigned char *)bmp->ScanLine[y]; + for(unsigned int x = 0; x < gm.gmBlackBoxX; x++) + { + d[x] = (p[x >> 3]& (0x80 >> (x & 0x07))) ? 0 : 255; + } + p += pitch; + } + } + else + { + unsigned char *p = buf; + for(unsigned int y = 0; y < gm.gmBlackBoxY; y++) + { + unsigned char *d = (unsigned char *)bmp->ScanLine[y]; + for(unsigned int x = 0; x < gm.gmBlackBoxX; x++) + { + d[x] = 255 - (p[x] == 64 ? 255 : p[x] * 4); + } + p += pitch; + } + } + + delete [] buf; + + return bmp; +} + +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +struct TRedrawData +{ + int Index; +}; +//--------------------------------------------------------------------------- +__fastcall TFontPreviewBox::TFontPreviewBox(TWinControl *Owner) + : TCustomControl(Owner) +{ + Form = (TFontPreviewForm*)Owner; + Cols = 0; + Brush->Style = bsClear; +// Brush->Color = clWindow; + + RedrawList = new TList(); + Application->OnIdle = ApplicationIdle; +} +//--------------------------------------------------------------------------- +__fastcall TFontPreviewBox::~TFontPreviewBox() +{ + for(int i = 0; i < RedrawList->Count; i++) + delete (TRedrawData*)(RedrawList->Items[i]); + delete RedrawList; + Application->OnIdle = NULL; +} +//--------------------------------------------------------------------------- +int __fastcall TFontPreviewBox::GetOneSize() +{ + int onesize = Form->GetRefCanvas()->Font->Height; + if(onesize < 0) onesize = -onesize; + onesize *= Form->GetZoom(); + onesize += 4; + return onesize; +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewBox::CreateParams(TCreateParams ¶ms) +{ + inherited::CreateParams(params); + + params.Style |= WS_VSCROLL; +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewBox::Paint(void) +{ + // paint the surface + if(!Cols) return; + + int onesize = GetOneSize(); + const wchar_t * charlist = Form->GetCharacterList(); + int charlistcount = Form->GetCharacterListCount(); + + TRect r; + r = Canvas->ClipRect; + + Canvas->Brush->Color = clWindow; + Canvas->FillRect(r); + Canvas->Font->Color = clGrayText; + + int topindex = GetTopIndex(); + + int xstart = r.left / onesize; + int ystart = r.top / onesize; + int xlim = r.right / onesize; + int ylim = r.bottom / onesize; + + for(int y = ylim; y >= ystart; y--) + { + for(int x = xlim; x >= xstart; x--) + { + int index = topindex + x + y*Cols; + + if(index >= charlistcount) continue; + + int i; + int listcount = RedrawList->Count; + for(i = 0; i < listcount; i++) + { + if(((TRedrawData*)(RedrawList->Items[i]))->Index == index) break; + } + + if(i == listcount) + { + TRedrawData *redraw = new TRedrawData; + redraw->Index = index; + RedrawList->Add(redraw); + } + + TRect r; + r.left = ((index - topindex) % Cols) * onesize; + r.right = r.left + onesize; + r.top = ((index - topindex) / Cols) * onesize; + r.bottom = r.top + onesize; + + SIZE sz; + procGetTextExtentPoint32W(Canvas->Handle, charlist + index, 1, &sz); + procTextOutW(Canvas->Handle, ((r.right - r.left - sz.cx) >>1) + r.left, + ((r.bottom - r.top - sz.cy) >> 1) + r.top, charlist + index, 1); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewBox::RedrawGlyphs() +{ + int onesize = GetOneSize(); + int topindex = GetTopIndex(); + int charlistcount = Form->GetCharacterListCount(); + const wchar_t * charlist = Form->GetCharacterList(); + + for(int i = RedrawList->Count - 1; i >= 0 ; i--) + { + TRedrawData *red = (TRedrawData*)(RedrawList->Items[i]); + if(!red) continue; + + int index = red->Index; + + TRect r; + r.left = ((index - topindex) % Cols) * onesize; + r.right = r.left + onesize; + r.top = ((index - topindex) / Cols) * onesize; + r.bottom = r.top + onesize; + + if(index >= charlistcount || + r.Right < 0 || r.Top < 0 || r.Left > ClientWidth || r.Top > ClientHeight) + { + delete red; + RedrawList->Items[i] = NULL; + continue; + } + + Canvas->Brush->Color = clWindow; + Canvas->FillRect(r); + + Graphics::TBitmap *bmp; + wchar_t ch = charlist[index]; + + bmp = GetGlyphBitmap(ch, + (ch >= 0xe000 && ch <= 0xf8ff) ? Form->GetPrivRefCanvas() : Form->GetRefCanvas(), + Form->GetAntialiased()); + + if(bmp) + { + int w = bmp->Width; + int h = bmp->Height; + int zoom = Form->GetZoom(); + w *= zoom; + h *= zoom; + TRect dr; + dr.left = (r.right - r.left - w)/2 + r.left; + dr.right = dr.left + w; + dr.top = (r.bottom - r.top - h)/2 + r.top; + dr.bottom = dr.top + h; + Canvas->StretchDraw(dr, bmp); + delete bmp; + } + + RedrawList->Items[i] = NULL; + + break; + } + RedrawList->Pack(); +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewBox::ApplicationIdle(System::TObject* Sender, bool &Done) +{ + RedrawGlyphs(); + if(RedrawList->Count) Done = false; else Done = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewBox::SetScrollRange(void) +{ + int charlistcount = Form->GetCharacterListCount(); + + int onesize = GetOneSize(); + int cols = ClientWidth / onesize; + if(cols <= 0) cols = 1; + Cols = cols; + int max = ((charlistcount - 1) / cols) + 1 ; + int page = ClientHeight / onesize; + if(page <= 0) page = 1; + + SCROLLINFO si; + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE/* | SIF_DISABLENOSCROLL*/; + si.nMin = 0; + si.nMax = max; + si.nPage = page; + si.nPos = 0; + + SetScrollInfo(Handle, SB_VERT, &si, true); + EnableScrollBar(Handle, SB_VERT, ESB_ENABLE_BOTH); +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewBox::WMVScroll(TWMHScroll &msg) +{ + // window is to be scrolled + + SCROLLINFO si; + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(Handle, SB_VERT, &si); + + int org = si.nPos; + + if(msg.ScrollCode == SB_THUMBTRACK) + { + si.nPos = si.nTrackPos; + } + else if(msg.ScrollCode == SB_LINEUP) + { + si.nPos--; + if(si.nPos<0) si.nPos=0; + } + else if(msg.ScrollCode == SB_LINEDOWN) + { + si.nPos++; + if((int)(si.nPos) >= (int)(si.nMax - si.nPage)) si.nPos=si.nMax- si.nPage + 1; + } + else if(msg.ScrollCode == SB_PAGEUP) + { + si.nPos = si.nPos - si.nPage; + if(si.nPos<0) si.nPos=0; + } + else if(msg.ScrollCode == SB_PAGEDOWN) + { + si.nPos = si.nPos + si.nPage; + if(si.nPos >=si.nMax) si.nPos=si.nMax-1; + } + + si.fMask = SIF_POS; + + SetScrollInfo(Handle, SB_VERT, &si, true); + RECT r; + r.left = 0; + r.top = 0; + r.right = ClientWidth; + r.bottom = ClientHeight; + + int onesize = GetOneSize(); + + ScrollWindowEx(Handle, 0, (int)(org - si.nPos) * onesize, + &r, NULL, NULL, NULL, SW_INVALIDATE); + +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewBox::WMMouseMove(TWMMouseMove &msg) +{ + int topindex = GetTopIndex(); + int onesize = GetOneSize(); + int x = msg.XPos / onesize; + int y = msg.YPos / onesize; + int index = topindex + x + y * Cols; + if(index < Form->GetCharacterListCount()) + { + wchar_t ch = Form->GetCharacterList()[index]; + Form->StatusBar->Panels->Items[0]->Text = "UNICODE " + IntToHex((int)ch, 4); + } +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewBox::Resize(void) +{ + SetScrollRange(); + + inherited::Resize(); +} +//--------------------------------------------------------------------------- +int __fastcall TFontPreviewBox::GetTopIndex() +{ + SCROLLINFO si; + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_POS; + GetScrollInfo(Handle, SB_VERT, &si); + + return (int)(si.nPos*Cols); +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewBox::NotifyFontChanged() +{ + SetScrollRange(); + Invalidate(); +} +//--------------------------------------------------------------------------- + + + + + + +//--------------------------------------------------------------------------- +__fastcall TFontPreviewForm::TFontPreviewForm(TComponent* Owner, + TCanvas *refcanvas, TCanvas *privrefcanvas) + : TForm(Owner) +{ + RefCanvas = refcanvas; + PrivRefCanvas = privrefcanvas; + PreviewBox = NULL; + + Icon->Assign(((TFontMakerForm*)Owner)->Icon); + ZoomComboBox->ItemIndex = 0; + + PreviewBox = new TFontPreviewBox(this); + PreviewBox->Parent = PreviewPanel; + PreviewBox->Align = alClient; + PreviewBox->Visible = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewForm::FormDestroy(TObject *Sender) +{ + delete PreviewBox; +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewForm::FormClose(TObject *Sender, TCloseAction &Action) +{ + Action = caHide; +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewForm::ZoomComboBoxChange(TObject *Sender) +{ + if(PreviewBox) PreviewBox->NotifyFontChanged(); +} +//--------------------------------------------------------------------------- + +void __fastcall TFontPreviewForm::CloseButtonClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewForm::FormMouseWheelDown(TObject *Sender, + TShiftState Shift, TPoint &MousePos, bool &Handled) +{ + ::PostMessage(PreviewBox->Handle, WM_VSCROLL, SB_PAGEDOWN, 0); + Handled = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewForm::FormMouseWheelUp(TObject *Sender, + TShiftState Shift, TPoint &MousePos, bool &Handled) +{ + ::PostMessage(PreviewBox->Handle, WM_VSCROLL, SB_PAGEUP, 0); + Handled = true; +} +//--------------------------------------------------------------------------- +void __fastcall TFontPreviewForm::NotifyFontChanged(bool antialiased) +{ + Antialiased = antialiased; + PreviewBox->NotifyFontChanged(); + StatusBar->Panels->Items[1]->Text = "Total " + AnsiString(GetCharacterListCount()) + " glyphs"; +} +//--------------------------------------------------------------------------- +int __fastcall TFontPreviewForm::GetZoom() const +{ + return ZoomComboBox->ItemIndex + 1; +} +//--------------------------------------------------------------------------- +const wchar_t * TFontPreviewForm::GetCharacterList() const +{ + return ((TFontMakerForm*)Owner)->GetCharacterList(); +} +//--------------------------------------------------------------------------- +int TFontPreviewForm::GetCharacterListCount() const +{ + return ((TFontMakerForm*)Owner)->GetCharacterListCount(); +} +//--------------------------------------------------------------------------- + + diff --git a/tools/win32/krdevui/FontPreviewUnit.dfm b/tools/win32/krdevui/FontPreviewUnit.dfm new file mode 100644 index 0000000..d4c291c --- /dev/null +++ b/tools/win32/krdevui/FontPreviewUnit.dfm @@ -0,0 +1,92 @@ +object FontPreviewForm: TFontPreviewForm + Left = 105 + Top = 114 + Width = 599 + Height = 390 + Caption = 'フォントサンプル' + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poDefaultPosOnly + OnClose = FormClose + OnDestroy = FormDestroy + OnMouseWheelDown = FormMouseWheelDown + OnMouseWheelUp = FormMouseWheelUp + PixelsPerInch = 96 + TextHeight = 12 + object UpperPanel: TPanel + Left = 0 + Top = 0 + Width = 591 + Height = 20 + Align = alTop + BevelOuter = bvNone + TabOrder = 0 + object ZoomComboBox: TComboBox + Left = 0 + Top = 0 + Width = 145 + Height = 20 + Style = csDropDownList + DropDownCount = 16 + ItemHeight = 12 + TabOrder = 0 + OnChange = ZoomComboBoxChange + Items.Strings = ( + '拡大率 等倍' + '拡大率 2倍' + '拡大率 3倍' + '拡大率 4倍' + '拡大率 5倍' + '拡大率 6倍' + '拡大率 7倍' + '拡大率 8倍' + '拡大率 9倍' + '拡大率 10倍' + '拡大率 11倍' + '拡大率 12倍' + '拡大率 13倍' + '拡大率 14倍' + '拡大率 15倍' + '拡大率 16倍') + end + object CloseButton: TButton + Left = 176 + Top = 0 + Width = 75 + Height = 20 + Cancel = True + Caption = '閉じる(&C)' + TabOrder = 1 + OnClick = CloseButtonClick + end + end + object StatusBar: TStatusBar + Left = 0 + Top = 337 + Width = 591 + Height = 19 + Panels = < + item + Width = 120 + end + item + Width = 50 + end> + SimplePanel = False + end + object PreviewPanel: TPanel + Left = 0 + Top = 20 + Width = 591 + Height = 317 + Align = alClient + BevelInner = bvLowered + BevelOuter = bvNone + TabOrder = 2 + end +end diff --git a/tools/win32/krdevui/FontPreviewUnit.h b/tools/win32/krdevui/FontPreviewUnit.h new file mode 100644 index 0000000..dc92efa --- /dev/null +++ b/tools/win32/krdevui/FontPreviewUnit.h @@ -0,0 +1,99 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef FontPreviewUnitH +#define FontPreviewUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TFontPreviewForm; +class TFontPreviewBox : public TCustomControl +{ + typedef TCustomControl inherited; + + TFontPreviewForm *Form; + TList *RedrawList; + + int Cols; + +public: + __fastcall TFontPreviewBox(TWinControl *Owner); + __fastcall ~TFontPreviewBox(); + + +protected: + int __fastcall GetOneSize(); + void __fastcall CreateParams(TCreateParams ¶ms); + void __fastcall Paint(void); + void __fastcall RedrawGlyphs(); + void __fastcall ApplicationIdle(System::TObject* Sender, bool &Done); + void __fastcall SetScrollRange(void); + void __fastcall WMVScroll(TWMVScroll &msg); + void __fastcall WMMouseMove(TWMMouseMove &msg); + DYNAMIC void __fastcall Resize(void); + int __fastcall GetTopIndex(); + +BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER(WM_VSCROLL, TWMVScroll, WMVScroll) + VCL_MESSAGE_HANDLER(WM_MOUSEMOVE, TWMMouseMove, WMMouseMove) +END_MESSAGE_MAP(TCustomControl) + + bool CanResizeUpdate; + +public: + void __fastcall NotifyFontChanged(); +}; +//--------------------------------------------------------------------------- +class TFontPreviewForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TPanel *UpperPanel; + TComboBox *ZoomComboBox; + TButton *CloseButton; + TStatusBar *StatusBar; + TPanel *PreviewPanel; + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall ZoomComboBoxChange(TObject *Sender); + void __fastcall CloseButtonClick(TObject *Sender); + void __fastcall FormMouseWheelDown(TObject *Sender, TShiftState Shift, + TPoint &MousePos, bool &Handled); + void __fastcall FormMouseWheelUp(TObject *Sender, TShiftState Shift, + TPoint &MousePos, bool &Handled); +private: // ユーザー宣言 + TFontPreviewBox * PreviewBox; + TCanvas *RefCanvas; + TCanvas *PrivRefCanvas; // for private (GAIJI) area + bool Antialiased; + +public: // ユーザー宣言 + __fastcall TFontPreviewForm(TComponent* Owner, TCanvas *refcanvas, + TCanvas *privrefcanvas); + + +public: + void __fastcall NotifyFontChanged(bool antialiased); + int __fastcall GetZoom() const; + + TCanvas * GetRefCanvas() const { return RefCanvas; } + TCanvas * GetPrivRefCanvas() const { return PrivRefCanvas; } + bool GetAntialiased() const { return Antialiased; } + const wchar_t * GetCharacterList() const; + int GetCharacterListCount() const; + +private: +}; +//--------------------------------------------------------------------------- +extern PACKAGE TFontPreviewForm *FontPreviewForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/KrkrExecutableUnit.cpp b/tools/win32/krdevui/KrkrExecutableUnit.cpp new file mode 100644 index 0000000..c75b476 --- /dev/null +++ b/tools/win32/krdevui/KrkrExecutableUnit.cpp @@ -0,0 +1,74 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include + +#include "KrkrExecutableUnit.h" + +//--------------------------------------------------------------------------- +#define MIN_KRKR_MARK_SEARCH 512*1024 +#define MAX_KRKR_MARK_SEARCH 4*1024*1024 +//--------------------------------------------------------------------------- +char XOPT_EMBED_AREA_[] = " OPT_EMBED_AREA_"; +char XCORE_SIG_______[] = " CORE_SIG_______"; +char XRELEASE_SIG____[] = " RELEASE_SIG____"; +char XP3_SIG[] = " P3\x0d\x0a\x20\x0a\x1a\x8b\x67\x01"; // mark_size = 11 +//--------------------------------------------------------------------------- +int CheckKrkrExecutable(AnsiString fn, const char *mark) +{ + // Find the mark in the krkr executable. + // All krkr executable have + // "XOPT_EMBED_AREA_" mark at the end of the executable image. + // Additionally + // "XCORE_SIG_______" and "XRELEASE_SIG____" are reserved area for + // signatures. + // "XP3\x0d\x0a\x20\x0a\x1a\x8b\x67\x01" are optional XP3 archive attached + // to the executable. + + // This function returns the mark offset + // (area size bofore specified mark) + int mark_size = strlen(mark); + + TFileStream *st = new TFileStream(fn, fmOpenRead | fmShareDenyWrite); + int imagesize = 0; + try + { + int ofs = MIN_KRKR_MARK_SEARCH; + char buf[4096]; + int read; + bool found = false; + st->Position = ofs; + while( (read = st->Read(buf, sizeof(buf)) ) != 0) + { + for(int i = 0; i < read; i += 16) // the mark is aligned to paragraph (16bytes) + { + if(buf[i] == 'X') + { + if(!memcmp(buf + i + 1, mark + 1, mark_size - 1)) + { + // mark found + imagesize = i + ofs; + found = true; + break; + } + } + } + if(found) break; + ofs += read; + if(ofs >= MAX_KRKR_MARK_SEARCH) break; + } + } + catch(...) + { + delete st; + throw; + } + delete st; + + return imagesize; +} +//--------------------------------------------------------------------------- + +#pragma package(smart_init) diff --git a/tools/win32/krdevui/KrkrExecutableUnit.h b/tools/win32/krdevui/KrkrExecutableUnit.h new file mode 100644 index 0000000..03c4a2a --- /dev/null +++ b/tools/win32/krdevui/KrkrExecutableUnit.h @@ -0,0 +1,14 @@ +//--------------------------------------------------------------------------- + +#ifndef KrkrExecutableUnitH +#define KrkrExecutableUnitH +//--------------------------------------------------------------------------- +extern char XOPT_EMBED_AREA_[];// = " OPT_EMBED_AREA_"; +extern char XCORE_SIG_______[];// = " CORE_SIG_______"; +extern char XRELEASE_SIG____[];// = " RELEASE_SIG____"; +extern char XP3_SIG[]; // = " P3\x0d\x0a\x20\x0a\x1a\x8b\x67\x01"; // mark_size = 11 +//--------------------------------------------------------------------------- +extern int CheckKrkrExecutable(AnsiString fn, const char *mark); +//--------------------------------------------------------------------------- + +#endif diff --git a/tools/win32/krdevui/MainUnit.cpp b/tools/win32/krdevui/MainUnit.cpp new file mode 100644 index 0000000..49ce716 --- /dev/null +++ b/tools/win32/krdevui/MainUnit.cpp @@ -0,0 +1,65 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + + + + +#pragma argsused +//--------------------------------------------------------------------------- +int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) +{ + Application->Initialize(); + + return 1; +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +extern "C" void _export PASCAL UIGetVersion(DWORD *hi, DWORD *low) +{ + static VS_FIXEDFILEINFO *FixedFileInfo; + static BYTE VersionInfo[16384]; + + static bool DoGet=true; + if(DoGet) + { + DoGet=false; + + UINT dum; + + char path[MAX_PATH+1]; + GetModuleFileName(GetModuleHandle("krdevui.dll"), path, MAX_PATH); + + GetFileVersionInfo(path,0,16384,(void*)VersionInfo); + VerQueryValue((void*)VersionInfo,"\\",(void**)(&FixedFileInfo), + &dum); + + } + + if(FixedFileInfo) + { + if(hi) *hi = FixedFileInfo->dwFileVersionMS; + if(low) *low = FixedFileInfo->dwFileVersionLS; + } + else + { + if(hi) *hi = 0; + if(low) *low = 0; + } +} +//--------------------------------------------------------------------------- + + + + diff --git a/tools/win32/krdevui/RandomizeFormUnit.cpp b/tools/win32/krdevui/RandomizeFormUnit.cpp new file mode 100644 index 0000000..9eb12c5 --- /dev/null +++ b/tools/win32/krdevui/RandomizeFormUnit.cpp @@ -0,0 +1,131 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop +#include + +#define DISTANCE 1000i64 +#define MIN_TIME 3000 + +#include "RandomizeFormUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TRandomizeForm *RandomizeForm; +//--------------------------------------------------------------------------- +__fastcall TRandomizeForm::TRandomizeForm(TComponent* Owner, prng_state *state) + : TForm(Owner) +{ + State = state; + GetCursorPos(&PrevMousePos); + Distance = 0; + StartTick = GetTickCount(); +} +//--------------------------------------------------------------------------- +void __fastcall TRandomizeForm::TimerTimer(TObject *Sender) +{ + // Add entropy noise + + DWORD tick = GetTickCount(); + + fortuna_add_entropy( (const unsigned char*)&tick, sizeof(tick), State); + + POINT pos; + GetCursorPos(&pos); + + MEMORYSTATUS status; + GlobalMemoryStatus(&status); + + time_t current; + time(¤t); + + fortuna_add_entropy( (const unsigned char*)¤t, sizeof(current), State); + fortuna_add_entropy( (const unsigned char*)&pos, sizeof(pos), State); + fortuna_add_entropy( (const unsigned char*)&Distance, sizeof(Distance), State); + fortuna_add_entropy( (const unsigned char*)&status, sizeof(status), State); + + Distance += (pos.x - PrevMousePos.x)*(pos.x - PrevMousePos.x); + Distance += (pos.y - PrevMousePos.y)*(pos.y - PrevMousePos.y); + + PrevMousePos = pos; + + if(Distance > DISTANCE*DISTANCE && (tick - StartTick) > MIN_TIME) + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +bool RandomizePRNG(prng_state *state) +{ + // initialize random generator + if(find_prng("fortuna") == -1) + { + errno = register_prng(&fortuna_desc); + if(errno != CRYPT_OK) throw Exception(error_to_string(errno)); + } + + errno = fortuna_start(state); + if(errno != CRYPT_OK) throw Exception(error_to_string(errno)); + + TRandomizeForm *form = new TRandomizeForm(Application, state); + int result = form->ShowModal(); + delete form; + + if(result != mrOk) return false; + + errno = fortuna_ready(state); + if(errno != CRYPT_OK) throw Exception(error_to_string(errno)); + + return true; +} +//--------------------------------------------------------------------------- +static BOOL CALLBACK EnumWindowsProc(HWND wnd, LPARAM lp) +{ + prng_state *state = (prng_state*)lp; + RECT r; + GetWindowRect(wnd, &r); + char tmp[256]; + GetWindowText(wnd, tmp, 255); + fortuna_add_entropy( (const unsigned char*)&r, sizeof(r), state); + fortuna_add_entropy( (const unsigned char*)tmp, sizeof(tmp), state); + + return TRUE; +} +//--------------------------------------------------------------------------- +bool RandomizePRNGSimple(prng_state *state) +{ + // initialize random generator, in simple way + if(find_prng("fortuna") == -1) + { + errno = register_prng(&fortuna_desc); + if(errno != CRYPT_OK) throw Exception(error_to_string(errno)); + } + + errno = fortuna_start(state); + if(errno != CRYPT_OK) throw Exception(error_to_string(errno)); + + DWORD tick = GetTickCount(); + fortuna_add_entropy( (const unsigned char*)&tick, sizeof(tick), state); + + POINT pos; + GetCursorPos(&pos); + + MEMORYSTATUS status; + GlobalMemoryStatus(&status); + + time_t current; + time(¤t); + + fortuna_add_entropy( (const unsigned char*)¤t, sizeof(current), state); + fortuna_add_entropy( (const unsigned char*)&pos, sizeof(pos), state); + fortuna_add_entropy( (const unsigned char*)&status, sizeof(status), state); + + EnumWindows((WNDENUMPROC)EnumWindowsProc, (LPARAM)state); + + tick = GetTickCount(); + fortuna_add_entropy( (const unsigned char*)&tick, sizeof(tick), state); + + errno = fortuna_ready(state); + if(errno != CRYPT_OK) throw Exception(error_to_string(errno)); + + return true; +} +//--------------------------------------------------------------------------- diff --git a/tools/win32/krdevui/RandomizeFormUnit.dfm b/tools/win32/krdevui/RandomizeFormUnit.dfm new file mode 100644 index 0000000..b7d1e4b --- /dev/null +++ b/tools/win32/krdevui/RandomizeFormUnit.dfm @@ -0,0 +1,73 @@ +object RandomizeForm: TRandomizeForm + Left = 429 + Top = 26 + BorderStyle = bsDialog + Caption = 'エントロピーを収集中' + ClientHeight = 182 + ClientWidth = 215 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poMainFormCenter + PixelsPerInch = 96 + TextHeight = 12 + object Label1: TLabel + Left = 64 + Top = 48 + Width = 87 + Height = 12 + Alignment = taCenter + Caption = 'マウスカーソルを' + end + object Label2: TLabel + Left = 44 + Top = 80 + Width = 126 + Height = 12 + Alignment = taCenter + Caption = 'しばらくマウスを動かすと' + end + object Label3: TLabel + Left = 21 + Top = 96 + Width = 173 + Height = 12 + Alignment = taCenter + Caption = 'このウィンドウは自動的に閉じます' + end + object Label5: TLabel + Left = 35 + Top = 64 + Width = 145 + Height = 12 + Alignment = taCenter + Caption = 'でたらめに動かしてください。' + end + object Label7: TLabel + Left = 27 + Top = 8 + Width = 161 + Height = 12 + Caption = '「でたらめさ」が必要となります。' + end + object CancelButton: TButton + Left = 59 + Top = 144 + Width = 97 + Height = 25 + Cancel = True + Caption = 'キャンセル(&C)' + ModalResult = 2 + TabOrder = 0 + end + object Timer: TTimer + Interval = 50 + OnTimer = TimerTimer + Left = 168 + Top = 144 + end +end diff --git a/tools/win32/krdevui/RandomizeFormUnit.h b/tools/win32/krdevui/RandomizeFormUnit.h new file mode 100644 index 0000000..7cb6cc4 --- /dev/null +++ b/tools/win32/krdevui/RandomizeFormUnit.h @@ -0,0 +1,49 @@ +//--------------------------------------------------------------------------- + +#ifndef RandomizeFormUnitH +#define RandomizeFormUnitH +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include + +//--------------------------------------------------------------------------- +#define _MSC_VER +#include +#undef _MSC_VER + +//--------------------------------------------------------------------------- +class TRandomizeForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TButton *CancelButton; + TLabel *Label1; + TLabel *Label2; + TLabel *Label3; + TLabel *Label5; + TLabel *Label7; + TTimer *Timer; + void __fastcall TimerTimer(TObject *Sender); +private: // ユーザー宣言 + prng_state *State; + POINT PrevMousePos; + __int64 Distance; + DWORD StartTick; + +public: // ユーザー宣言 + __fastcall TRandomizeForm(TComponent* Owner, prng_state *state); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TRandomizeForm *RandomizeForm; +//--------------------------------------------------------------------------- +bool RandomizePRNG(prng_state *state); +bool RandomizePRNGSimple(prng_state *state); +//--------------------------------------------------------------------------- + +#endif diff --git a/tools/win32/krdevui/RelDirSearchUnit.cpp b/tools/win32/krdevui/RelDirSearchUnit.cpp new file mode 100644 index 0000000..d1c0f77 --- /dev/null +++ b/tools/win32/krdevui/RelDirSearchUnit.cpp @@ -0,0 +1,119 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include + +#include "RelDirSearchUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TRelDirSearchForm *RelDirSearchForm; +//--------------------------------------------------------------------------- +__fastcall TRelDirSearchForm::TRelDirSearchForm(TComponent* Owner) + : TForm(Owner) +{ + Aborted = false; + FileList = new TStringList(); + ExtList = new TStringList(); + FileList->Duplicates = dupAccept; + FileList->Sorted = false; + ExtList->Duplicates = dupIgnore; + ExtList->Sorted = true; +} +//--------------------------------------------------------------------------- +void __fastcall TRelDirSearchForm::FormDestroy(TObject *Sender) +{ + delete FileList; + delete ExtList; +} +//--------------------------------------------------------------------------- +void __fastcall TRelDirSearchForm::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + Aborted = true; + CanClose = true; +} +//--------------------------------------------------------------------------- +void __fastcall TRelDirSearchForm::AbortButtonClick(TObject *Sender) +{ + Aborted = true; +} +//--------------------------------------------------------------------------- +void __fastcall TRelDirSearchForm::GetFileList(AnsiString path, int baselen) +{ + TSearchRec r; + int done; + + done=FindFirst(path + "*.*" ,faAnyFile, r); + try + { + while(!done) + { + if(r.FindData.cFileName[0]!='.') + { + if(! (r.Attr & faDirectory)) + { + // a file + AnsiString name = AnsiString(path.c_str()+ baselen) + + r.FindData.cFileName; + FileList->Add(name); + CurrentLabel->Caption = name; + AnsiString fileext = ExtractFileExt(r.FindData.cFileName); + ExtList->Add(fileext); + + // message processing + Application->ProcessMessages(); + if(Aborted) + { + throw EAbort("Aborted"); // raise an aborting exception + } + } + else + { + // a directory + if(r.Name != "." && r.Name != ".." && + !(r.Name == "CVS" && + FileExists(path + AnsiString("CVS\\Repository")))) + // ignoring CVS meta-data directory + { + GetFileList(path + r.FindData.cFileName+ + AnsiString("\\"), baselen); + } + } + } + done=FindNext(r); + } + } + catch(Exception &e) + { + FindClose(r); + throw Exception(e); + } + FindClose(r); +} +//--------------------------------------------------------------------------- +bool __fastcall TRelDirSearchForm::GetFileList(AnsiString folder) +{ + try + { + GetFileList(folder, folder.Length()); + } + catch(...) + { + return false; + } + return true; +} +//--------------------------------------------------------------------------- + + + diff --git a/tools/win32/krdevui/RelDirSearchUnit.dfm b/tools/win32/krdevui/RelDirSearchUnit.dfm new file mode 100644 index 0000000..dc5ce55 --- /dev/null +++ b/tools/win32/krdevui/RelDirSearchUnit.dfm @@ -0,0 +1,194 @@ +object RelDirSearchForm: TRelDirSearchForm + Left = 76 + Top = 459 + BorderIcons = [biSystemMenu] + BorderStyle = bsDialog + Caption = '吉里吉里 Releaser' + ClientHeight = 76 + ClientWidth = 304 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + Icon.Data = { + 0000010004002020100000000000E80200004600000010101000000000002801 + 00002E0300002020000000000000A80800005604000010100000000000006805 + 0000FE0C00002800000020000000400000000100040000000000000200000000 + 0000000000000000000000000000000000000000800000800000008080008000 + 00008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF00 + 0000FF00FF00FFFF0000FFFFFF00000000000000000000000000000000000000 + 0088888888888888888888880000000000000000000000000000000800000000 + 8FFFFFF77777777777777708000000008FFFFFFFF77777777777770800000000 + 8FFFFFFFFFF777777777770800000000877FFFFFFFFF77777777770800000000 + 87887FFFFFFFF77777177708000000000887FFFFFFFFFF777117770800000000 + 877FFFFFFFFFFFF7191777080000000087887FFFFFFFFFF19911111111100000 + 0887FFFFFFFFFF199999999999100000877FFFFFFFFFF9999999999999100000 + 87887FFFFFFFFF9999999999991000000887FFFFFFFFFFF99999999999100000 + 877FFFFFFFFFFFFF999FFF080000000087887FFFFFFFFFFFF99FF70800000000 + 0887FFFFFFFFFFFFFF9FFF0800000000877FFFFFFFFFFFFFFFFFFF0800000000 + 87887FFFFFFFFFFFFFFFFF08000000000887FFFFFFFFFFFFFFFFFF0800000000 + 877FFFFFFFFFFFFFFFFFFF080000000087887FFFFFFFFFFFFFFFFF0800000000 + 0887FFFFFFFFFFFFFFF7770000000000877FFFFFFFFFFFFFF777770000000000 + 87887FFFFFFFFFFF80000000000000000887FFFFFFFFFFFF8FF7800000000000 + 877FFFFFFFFFFFFF8F7800000000000087887FFFFFFFFFFF8780000000000000 + 0887FFFFFFFFFFFF8800000000000000877FFFFFFFFFFFFF8000000000000000 + 8888888888888888800000000000F8000007F8000007F0000007F0000007F000 + 0007F0000007E0000007D0000007E0000007E0000007D0000001E0000001E000 + 0001D0000001E0000001E0000007D0000007E0000007E0000007D0000007E000 + 0007E0000007D0000007E0000007E000000FD000001FE000003FE000007FD000 + 00FFE00001FFF00003FFF00007FF280000001000000020000000010004000000 + 0000800000000000000000000000000000000000000000000000000080000080 + 000000808000800000008000800080800000C0C0C000808080000000FF0000FF + 000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0000080000000000000088 + 8888888888000087777777777800008808FFFFF17800000077FFFF1178000088 + 08FFF1911111000077FF19999991008808FFF9999991000077FFFF9978000088 + 08FFFFF97800000077FFFFFF7800008808FFFFFF7880000077FFFF8000000088 + 08FFFF8F800000007FFFFF8800000088888888800000E0014000C0014000C001 + 400080014000C001400080004000C000400080004000C001400080014000C001 + 400080014000C003400080074000C00F4000C01F400028000000200000004000 + 0000010008000000000000040000000000000000000000000000000000000000 + 0000000080000080000000808000800000008000800080800000C0C0C000C0DC + C000F0CAA60004040400080808000C0C0C0011111100161616001C1C1C002222 + 220029292900555555004D4D4D004242420039393900807CFF005050FF009300 + D600FFECCC00C6D6EF00D6E7E70090A9AD000000330000006600000099000000 + CC00003300000033330000336600003399000033CC000033FF00006600000066 + 330000666600006699000066CC000066FF000099000000993300009966000099 + 99000099CC000099FF0000CC000000CC330000CC660000CC990000CCCC0000CC + FF0000FF660000FF990000FFCC00330000003300330033006600330099003300 + CC003300FF00333300003333330033336600333399003333CC003333FF003366 + 00003366330033666600336699003366CC003366FF0033990000339933003399 + 6600339999003399CC003399FF0033CC000033CC330033CC660033CC990033CC + CC0033CCFF0033FF330033FF660033FF990033FFCC0033FFFF00660000006600 + 330066006600660099006600CC006600FF006633000066333300663366006633 + 99006633CC006633FF00666600006666330066666600666699006666CC006699 + 00006699330066996600669999006699CC006699FF0066CC000066CC330066CC + 990066CCCC0066CCFF0066FF000066FF330066FF990066FFCC00CC00FF00FF00 + CC009999000099339900990099009900CC009900000099333300990066009933 + CC009900FF00996600009966330099336600996699009966CC009933FF009999 + 330099996600999999009999CC009999FF0099CC000099CC330066CC660099CC + 990099CCCC0099CCFF0099FF000099FF330099CC660099FF990099FFCC0099FF + FF00CC00000099003300CC006600CC009900CC00CC0099330000CC333300CC33 + 6600CC339900CC33CC00CC33FF00CC660000CC66330099666600CC669900CC66 + CC009966FF00CC990000CC993300CC996600CC999900CC99CC00CC99FF00CCCC + 0000CCCC3300CCCC6600CCCC9900CCCCCC00CCCCFF00CCFF0000CCFF330099FF + 6600CCFF9900CCFFCC00CCFFFF00CC003300FF006600FF009900CC330000FF33 + 3300FF336600FF339900FF33CC00FF33FF00FF660000FF663300CC666600FF66 + 9900FF66CC00CC66FF00FF990000FF993300FF996600FF999900FF99CC00FF99 + FF00FFCC0000FFCC3300FFCC6600FFCC9900FFCCCC00FFCCFF00FFFF3300CCFF + 6600FFFF9900FFFFCC006666FF0066FF660066FFFF00FF666600FF66FF00FFFF + 66002100A5005F5F5F00777777008686860096969600CBCBCB00B2B2B200D7D7 + D700DDDDDD00E3E3E300EAEAEA00F1F1F100F8F8F800F0FBFF00A4A0A0008080 + 80000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF000A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0A0A0AEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA0A0A0A0A0A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0AEA0A0A0A0A0A0A + 0A0AECF1F1F1F1F1F1BCBCBCBC07070707070707EFEFEFEF0AEA0A0A0A0A0A0A + 0A0AEC191919F1F1F1F1F1BCBCBCBC070707070707EFEFEF0AEA0A0A0A0A0A0A + 0A0AEC191919191919F1F1F1F1BCBCBC070707070707EFEF0AEA0A0A0A0A0A0A + 0A0AECBCBC191919191919F1F1F1BCBCBC070707070707EF0AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919F1F1F1BCBCBC0707010707070AEA0A0A0A0A0A0A + 0A0A0A14EAEF19191919191919F1F1F1BCBCBC01010707070AEA0A0A0A0A0A0A + 0A0AECEFEF191919191919191919F1F1F1BC01F9010707070AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919191919F1F101F9F90101010101010101010A0A0A + 0A0A0A14EAEF1919191919191919191901F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0AECBCBC19191919191919191919F9F9F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0AEAF7EC14BC191919191919191919F9F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0A0A14EAEF1919191919191919191919F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0AECBCBC19191919191919191919191919F9F9F9F1F1F10AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC191919191919191919191919F9F9F1F1BC0AEA0A0A0A0A0A0A + 0A0A0A14EAEF1919191919191919191919191919F919F1F10AEA0A0A0A0A0A0A + 0A0AECBCBC1919191919191919191919191919191919F1F10AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC19191919191919191919191919191919F10AEA0A0A0A0A0A0A + 0A0A0A14EAEF1919191919191919191919191919191919F10AEA0A0A0A0A0A0A + 0A0AECBCBC191919191919191919191919191919191919190AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC19191919191919191919191919191919190AEA0A0A0A0A0A0A + 0A0A0A14EAEF191919191919191919191919191919BCBCBC0AEA0A0A0A0A0A0A + 0A0AECBCBC1919191919191919191919191919BCBCEFEFEF0AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919191919191919EC0A0A0A0A0AEFEA0A0A0A0A0A0A + 0A0A0A14EAEF191919191919191919191919EC1919EFEC0AEFEA0A0A0A0A0A0A + 0A0AECBCBC19191919191919191919191919EC19EFEC0AEFEFEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919191919191919ECEFEC0AEAEAEAEA0A0A0A0A0A0A + 0A0A0A14EAEF191919191919191919191919ECEC0A0A0A0A0A0A0A0A0A0A0A0A + 0A0AECEFEF19191919191919191919191919EC0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0AECECECECECECECECECECECECECECECECEC0A0A0A0A0A0A0A0A0A0A0AF800 + 0007F8000007F0000007F0000007F0000007F0000007E0000007D0000007E000 + 0007E0000007D0000001E0000001E0000001D0000001E0000001E0000007D000 + 0007E0000007E0000007D0000007E0000007E0000007D0000007E0000007E000 + 0007D0000007E0000007E0000007D0000007E0000007F00003FFF00007FF2800 + 0000100000002000000001000800000000000001000000000000000000000000 + 0000000000000000000000008000008000000080800080000000800080008080 + 0000C0C0C000C0DCC000F0CAA60004040400080808000C0C0C00111111001616 + 16001C1C1C002222220029292900555555004D4D4D004242420039393900807C + FF005050FF009300D600FFECCC00C6D6EF00D6E7E70090A9AD00000033000000 + 6600000099000000CC00003300000033330000336600003399000033CC000033 + FF00006600000066330000666600006699000066CC000066FF00009900000099 + 330000996600009999000099CC000099FF0000CC000000CC330000CC660000CC + 990000CCCC0000CCFF0000FF660000FF990000FFCC0033000000330033003300 + 6600330099003300CC003300FF00333300003333330033336600333399003333 + CC003333FF00336600003366330033666600336699003366CC003366FF003399 + 00003399330033996600339999003399CC003399FF0033CC000033CC330033CC + 660033CC990033CCCC0033CCFF0033FF330033FF660033FF990033FFCC0033FF + FF00660000006600330066006600660099006600CC006600FF00663300006633 + 330066336600663399006633CC006633FF006666000066663300666666006666 + 99006666CC00669900006699330066996600669999006699CC006699FF0066CC + 000066CC330066CC990066CCCC0066CCFF0066FF000066FF330066FF990066FF + CC00CC00FF00FF00CC009999000099339900990099009900CC00990000009933 + 3300990066009933CC009900FF00996600009966330099336600996699009966 + CC009933FF009999330099996600999999009999CC009999FF0099CC000099CC + 330066CC660099CC990099CCCC0099CCFF0099FF000099FF330099CC660099FF + 990099FFCC0099FFFF00CC00000099003300CC006600CC009900CC00CC009933 + 0000CC333300CC336600CC339900CC33CC00CC33FF00CC660000CC6633009966 + 6600CC669900CC66CC009966FF00CC990000CC993300CC996600CC999900CC99 + CC00CC99FF00CCCC0000CCCC3300CCCC6600CCCC9900CCCCCC00CCCCFF00CCFF + 0000CCFF330099FF6600CCFF9900CCFFCC00CCFFFF00CC003300FF006600FF00 + 9900CC330000FF333300FF336600FF339900FF33CC00FF33FF00FF660000FF66 + 3300CC666600FF669900FF66CC00CC66FF00FF990000FF993300FF996600FF99 + 9900FF99CC00FF99FF00FFCC0000FFCC3300FFCC6600FFCC9900FFCCCC00FFCC + FF00FFFF3300CCFF6600FFFF9900FFFFCC006666FF0066FF660066FFFF00FF66 + 6600FF66FF00FFFF66002100A5005F5F5F00777777008686860096969600CBCB + CB00B2B2B200D7D7D700DDDDDD00E3E3E300EAEAEA00F1F1F100F8F8F800F0FB + FF00A4A0A000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF + 0000FFFFFF000A0A0AEC0A0C0A0C0A0C0A0C0A0C0A0A0A0AEC12121212121212 + 121212120C0A0A0AEB09070909090909090909120A0A0A43EC920C9219090909 + 090109120C0A0A0A4343070919190909010109120A0A0A43EC920C9219191901 + F901010101010A0A43430709191901F9F9F9F9F9F9010A43EC920C92191919F9 + F9F9F9F9F9010A0A4343070919191919F9F909120C0A0A43EC920C9219191919 + 19F909120C0A0A0A4343070919191919191909120A0A0A43EC920C9219191919 + 19191912120A0A0A434307091919191912434343EC0A0A43EC920C9219191919 + 921912EC0A0A0A0A43430719191919199212EC0A0A0A0A0AECECECECECECECEC + EC0A0A0A0A0AE0010000C0010000C001000080010000C001000080000000C000 + 000080000000C001000080010000C001000080010000C001000080030000C007 + 0000C01F0000} + OldCreateOrder = False + Position = poScreenCenter + OnCloseQuery = FormCloseQuery + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 12 + object Label1: TLabel + Left = 8 + Top = 8 + Width = 239 + Height = 12 + Caption = 'ファイル/フォルダの情報を読み込んでいます ...' + end + object CurrentLabel: TLabel + Left = 8 + Top = 24 + Width = 80 + Height = 12 + Caption = ' ' + end + object AbortButton: TButton + Left = 115 + Top = 48 + Width = 75 + Height = 25 + Cancel = True + Caption = '中断(&A)' + TabOrder = 0 + OnClick = AbortButtonClick + end +end diff --git a/tools/win32/krdevui/RelDirSearchUnit.h b/tools/win32/krdevui/RelDirSearchUnit.h new file mode 100644 index 0000000..2fd47b5 --- /dev/null +++ b/tools/win32/krdevui/RelDirSearchUnit.h @@ -0,0 +1,39 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef RelDirSearchUnitH +#define RelDirSearchUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TRelDirSearchForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TButton *AbortButton; + TLabel *Label1; + TLabel *CurrentLabel; + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall AbortButtonClick(TObject *Sender); +private: // ユーザー宣言 + bool Aborted; + void __fastcall GetFileList(AnsiString path, int baselen); +public: // ユーザー宣言 + __fastcall TRelDirSearchForm(TComponent* Owner); + TStringList *FileList; + TStringList *ExtList; + bool __fastcall GetFileList(AnsiString folder); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TRelDirSearchForm *RelDirSearchForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/RelFolderSelectorUnit.cpp b/tools/win32/krdevui/RelFolderSelectorUnit.cpp new file mode 100644 index 0000000..0c1bd60 --- /dev/null +++ b/tools/win32/krdevui/RelFolderSelectorUnit.cpp @@ -0,0 +1,94 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include + +#include "RelFolderSelectorUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "ShellCtrls" +#pragma resource "*.dfm" +TRelFolderSelectorForm *RelFolderSelectorForm; +//--------------------------------------------------------------------------- +#define SPACER 6 +__fastcall TRelFolderSelectorForm::TRelFolderSelectorForm(TComponent* Owner) + : TForm(Owner) +{ + ShellTreeView->Path = ExtractFileDir(ParamStr(0)); + + // adjust components + Label1->Left = SPACER; + Label1->Top = SPACER; + ShellComboBox->Left = SPACER; + ShellComboBox->Top = SPACER + Label1->Height + 2; + ShellComboBox->Width = ClientWidth - SPACER * 2; + ShellTreeView->Left = SPACER; + ShellTreeView->Top = ShellComboBox->Height + ShellComboBox->Top; + ShellTreeView->Width = ClientWidth - SPACER * 2; + OKButton->Top = ClientHeight - OKButton->Height - SPACER; + CancelButton->Top = ClientHeight - CancelButton->Height - SPACER; + OKButton->Left = ClientWidth - (StatusBar->Width + SPACER + CancelButton->Width + + SPACER + OKButton->Width); + CancelButton->Left = ClientWidth - ( StatusBar->Width + SPACER + CancelButton->Width); + ShellTreeView->Height = CancelButton->Top - SPACER - ShellTreeView->Top; + + if(ShellTreeView->Selected) + { + ShellTreeView->Selected->Expanded = true; + TTreeNode * topnode = ShellTreeView->Selected; + if(topnode->Count >= 1) + { + TTreeNode * longestitem = NULL; + int longesttextsize = -1; + for(int i = 0; i < topnode->Count; i++) + { + TTreeNode *subnode = topnode->Item[i]; + TRect rect = subnode->DisplayRect(true); + if(rect.right > longesttextsize) + { + longesttextsize = rect.right; + longestitem = topnode->Item[i]; + } + } + if(longestitem) + longestitem->MakeVisible(); + } + ShellTreeView->TopItem = topnode; + topnode->MakeVisible(); + } + +} +//--------------------------------------------------------------------------- +void __fastcall TRelFolderSelectorForm::ShellTreeViewChange( + TObject *Sender, TTreeNode *Node) +{ + if(ShellTreeView->Path != "" && DirectoryExists(ShellTreeView->Path)) + OKButton->Enabled = true; + else + OKButton->Enabled = false; +} +//--------------------------------------------------------------------------- +void __fastcall TRelFolderSelectorForm::SelectMenuItemClick( + TObject *Sender) +{ + if(OKButton->Enabled) OKButton->Click(); +} +//--------------------------------------------------------------------------- +void __fastcall TRelFolderSelectorForm::FormDestroy(TObject *Sender) +{ + delete ShellTreeView; + delete ShellComboBox; +} +//--------------------------------------------------------------------------- + + + diff --git a/tools/win32/krdevui/RelFolderSelectorUnit.dfm b/tools/win32/krdevui/RelFolderSelectorUnit.dfm new file mode 100644 index 0000000..e5f9111 --- /dev/null +++ b/tools/win32/krdevui/RelFolderSelectorUnit.dfm @@ -0,0 +1,252 @@ +object RelFolderSelectorForm: TRelFolderSelectorForm + Left = 141 + Top = 261 + Width = 416 + Height = 383 + HorzScrollBar.Tracking = True + HorzScrollBar.Visible = False + VertScrollBar.Tracking = True + VertScrollBar.Visible = False + Caption = '吉里吉里 Releaser - フォルダ選択' + Color = clBtnFace + Constraints.MinHeight = 209 + Constraints.MinWidth = 307 + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + Icon.Data = { + 0000010004002020100000000000E80200004600000010101000000000002801 + 00002E0300002020000000000000A80800005604000010100000000000006805 + 0000FE0C00002800000020000000400000000100040000000000000200000000 + 0000000000000000000000000000000000000000800000800000008080008000 + 00008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF00 + 0000FF00FF00FFFF0000FFFFFF00000000000000000000000000000000000000 + 0088888888888888888888880000000000000000000000000000000800000000 + 8FFFFFF77777777777777708000000008FFFFFFFF77777777777770800000000 + 8FFFFFFFFFF777777777770800000000877FFFFFFFFF77777777770800000000 + 87887FFFFFFFF77777177708000000000887FFFFFFFFFF777117770800000000 + 877FFFFFFFFFFFF7191777080000000087887FFFFFFFFFF19911111111100000 + 0887FFFFFFFFFF199999999999100000877FFFFFFFFFF9999999999999100000 + 87887FFFFFFFFF9999999999991000000887FFFFFFFFFFF99999999999100000 + 877FFFFFFFFFFFFF999FFF080000000087887FFFFFFFFFFFF99FF70800000000 + 0887FFFFFFFFFFFFFF9FFF0800000000877FFFFFFFFFFFFFFFFFFF0800000000 + 87887FFFFFFFFFFFFFFFFF08000000000887FFFFFFFFFFFFFFFFFF0800000000 + 877FFFFFFFFFFFFFFFFFFF080000000087887FFFFFFFFFFFFFFFFF0800000000 + 0887FFFFFFFFFFFFFFF7770000000000877FFFFFFFFFFFFFF777770000000000 + 87887FFFFFFFFFFF80000000000000000887FFFFFFFFFFFF8FF7800000000000 + 877FFFFFFFFFFFFF8F7800000000000087887FFFFFFFFFFF8780000000000000 + 0887FFFFFFFFFFFF8800000000000000877FFFFFFFFFFFFF8000000000000000 + 8888888888888888800000000000F8000007F8000007F0000007F0000007F000 + 0007F0000007E0000007D0000007E0000007E0000007D0000001E0000001E000 + 0001D0000001E0000001E0000007D0000007E0000007E0000007D0000007E000 + 0007E0000007D0000007E0000007E000000FD000001FE000003FE000007FD000 + 00FFE00001FFF00003FFF00007FF280000001000000020000000010004000000 + 0000800000000000000000000000000000000000000000000000000080000080 + 000000808000800000008000800080800000C0C0C000808080000000FF0000FF + 000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0000080000000000000088 + 8888888888000087777777777800008808FFFFF17800000077FFFF1178000088 + 08FFF1911111000077FF19999991008808FFF9999991000077FFFF9978000088 + 08FFFFF97800000077FFFFFF7800008808FFFFFF7880000077FFFF8000000088 + 08FFFF8F800000007FFFFF8800000088888888800000E0014000C0014000C001 + 400080014000C001400080004000C000400080004000C001400080014000C001 + 400080014000C003400080074000C00F4000C01F400028000000200000004000 + 0000010008000000000000040000000000000000000000000000000000000000 + 0000000080000080000000808000800000008000800080800000C0C0C000C0DC + C000F0CAA60004040400080808000C0C0C0011111100161616001C1C1C002222 + 220029292900555555004D4D4D004242420039393900807CFF005050FF009300 + D600FFECCC00C6D6EF00D6E7E70090A9AD000000330000006600000099000000 + CC00003300000033330000336600003399000033CC000033FF00006600000066 + 330000666600006699000066CC000066FF000099000000993300009966000099 + 99000099CC000099FF0000CC000000CC330000CC660000CC990000CCCC0000CC + FF0000FF660000FF990000FFCC00330000003300330033006600330099003300 + CC003300FF00333300003333330033336600333399003333CC003333FF003366 + 00003366330033666600336699003366CC003366FF0033990000339933003399 + 6600339999003399CC003399FF0033CC000033CC330033CC660033CC990033CC + CC0033CCFF0033FF330033FF660033FF990033FFCC0033FFFF00660000006600 + 330066006600660099006600CC006600FF006633000066333300663366006633 + 99006633CC006633FF00666600006666330066666600666699006666CC006699 + 00006699330066996600669999006699CC006699FF0066CC000066CC330066CC + 990066CCCC0066CCFF0066FF000066FF330066FF990066FFCC00CC00FF00FF00 + CC009999000099339900990099009900CC009900000099333300990066009933 + CC009900FF00996600009966330099336600996699009966CC009933FF009999 + 330099996600999999009999CC009999FF0099CC000099CC330066CC660099CC + 990099CCCC0099CCFF0099FF000099FF330099CC660099FF990099FFCC0099FF + FF00CC00000099003300CC006600CC009900CC00CC0099330000CC333300CC33 + 6600CC339900CC33CC00CC33FF00CC660000CC66330099666600CC669900CC66 + CC009966FF00CC990000CC993300CC996600CC999900CC99CC00CC99FF00CCCC + 0000CCCC3300CCCC6600CCCC9900CCCCCC00CCCCFF00CCFF0000CCFF330099FF + 6600CCFF9900CCFFCC00CCFFFF00CC003300FF006600FF009900CC330000FF33 + 3300FF336600FF339900FF33CC00FF33FF00FF660000FF663300CC666600FF66 + 9900FF66CC00CC66FF00FF990000FF993300FF996600FF999900FF99CC00FF99 + FF00FFCC0000FFCC3300FFCC6600FFCC9900FFCCCC00FFCCFF00FFFF3300CCFF + 6600FFFF9900FFFFCC006666FF0066FF660066FFFF00FF666600FF66FF00FFFF + 66002100A5005F5F5F00777777008686860096969600CBCBCB00B2B2B200D7D7 + D700DDDDDD00E3E3E300EAEAEA00F1F1F100F8F8F800F0FBFF00A4A0A0008080 + 80000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF000A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0A0A0AEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA0A0A0A0A0A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0AEA0A0A0A0A0A0A + 0A0AECF1F1F1F1F1F1BCBCBCBC07070707070707EFEFEFEF0AEA0A0A0A0A0A0A + 0A0AEC191919F1F1F1F1F1BCBCBCBC070707070707EFEFEF0AEA0A0A0A0A0A0A + 0A0AEC191919191919F1F1F1F1BCBCBC070707070707EFEF0AEA0A0A0A0A0A0A + 0A0AECBCBC191919191919F1F1F1BCBCBC070707070707EF0AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919F1F1F1BCBCBC0707010707070AEA0A0A0A0A0A0A + 0A0A0A14EAEF19191919191919F1F1F1BCBCBC01010707070AEA0A0A0A0A0A0A + 0A0AECEFEF191919191919191919F1F1F1BC01F9010707070AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919191919F1F101F9F90101010101010101010A0A0A + 0A0A0A14EAEF1919191919191919191901F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0AECBCBC19191919191919191919F9F9F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0AEAF7EC14BC191919191919191919F9F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0A0A14EAEF1919191919191919191919F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0AECBCBC19191919191919191919191919F9F9F9F1F1F10AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC191919191919191919191919F9F9F1F1BC0AEA0A0A0A0A0A0A + 0A0A0A14EAEF1919191919191919191919191919F919F1F10AEA0A0A0A0A0A0A + 0A0AECBCBC1919191919191919191919191919191919F1F10AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC19191919191919191919191919191919F10AEA0A0A0A0A0A0A + 0A0A0A14EAEF1919191919191919191919191919191919F10AEA0A0A0A0A0A0A + 0A0AECBCBC191919191919191919191919191919191919190AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC19191919191919191919191919191919190AEA0A0A0A0A0A0A + 0A0A0A14EAEF191919191919191919191919191919BCBCBC0AEA0A0A0A0A0A0A + 0A0AECBCBC1919191919191919191919191919BCBCEFEFEF0AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919191919191919EC0A0A0A0A0AEFEA0A0A0A0A0A0A + 0A0A0A14EAEF191919191919191919191919EC1919EFEC0AEFEA0A0A0A0A0A0A + 0A0AECBCBC19191919191919191919191919EC19EFEC0AEFEFEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919191919191919ECEFEC0AEAEAEAEA0A0A0A0A0A0A + 0A0A0A14EAEF191919191919191919191919ECEC0A0A0A0A0A0A0A0A0A0A0A0A + 0A0AECEFEF19191919191919191919191919EC0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0AECECECECECECECECECECECECECECECECEC0A0A0A0A0A0A0A0A0A0A0AF800 + 0007F8000007F0000007F0000007F0000007F0000007E0000007D0000007E000 + 0007E0000007D0000001E0000001E0000001D0000001E0000001E0000007D000 + 0007E0000007E0000007D0000007E0000007E0000007D0000007E0000007E000 + 0007D0000007E0000007E0000007D0000007E0000007F00003FFF00007FF2800 + 0000100000002000000001000800000000000001000000000000000000000000 + 0000000000000000000000008000008000000080800080000000800080008080 + 0000C0C0C000C0DCC000F0CAA60004040400080808000C0C0C00111111001616 + 16001C1C1C002222220029292900555555004D4D4D004242420039393900807C + FF005050FF009300D600FFECCC00C6D6EF00D6E7E70090A9AD00000033000000 + 6600000099000000CC00003300000033330000336600003399000033CC000033 + FF00006600000066330000666600006699000066CC000066FF00009900000099 + 330000996600009999000099CC000099FF0000CC000000CC330000CC660000CC + 990000CCCC0000CCFF0000FF660000FF990000FFCC0033000000330033003300 + 6600330099003300CC003300FF00333300003333330033336600333399003333 + CC003333FF00336600003366330033666600336699003366CC003366FF003399 + 00003399330033996600339999003399CC003399FF0033CC000033CC330033CC + 660033CC990033CCCC0033CCFF0033FF330033FF660033FF990033FFCC0033FF + FF00660000006600330066006600660099006600CC006600FF00663300006633 + 330066336600663399006633CC006633FF006666000066663300666666006666 + 99006666CC00669900006699330066996600669999006699CC006699FF0066CC + 000066CC330066CC990066CCCC0066CCFF0066FF000066FF330066FF990066FF + CC00CC00FF00FF00CC009999000099339900990099009900CC00990000009933 + 3300990066009933CC009900FF00996600009966330099336600996699009966 + CC009933FF009999330099996600999999009999CC009999FF0099CC000099CC + 330066CC660099CC990099CCCC0099CCFF0099FF000099FF330099CC660099FF + 990099FFCC0099FFFF00CC00000099003300CC006600CC009900CC00CC009933 + 0000CC333300CC336600CC339900CC33CC00CC33FF00CC660000CC6633009966 + 6600CC669900CC66CC009966FF00CC990000CC993300CC996600CC999900CC99 + CC00CC99FF00CCCC0000CCCC3300CCCC6600CCCC9900CCCCCC00CCCCFF00CCFF + 0000CCFF330099FF6600CCFF9900CCFFCC00CCFFFF00CC003300FF006600FF00 + 9900CC330000FF333300FF336600FF339900FF33CC00FF33FF00FF660000FF66 + 3300CC666600FF669900FF66CC00CC66FF00FF990000FF993300FF996600FF99 + 9900FF99CC00FF99FF00FFCC0000FFCC3300FFCC6600FFCC9900FFCCCC00FFCC + FF00FFFF3300CCFF6600FFFF9900FFFFCC006666FF0066FF660066FFFF00FF66 + 6600FF66FF00FFFF66002100A5005F5F5F00777777008686860096969600CBCB + CB00B2B2B200D7D7D700DDDDDD00E3E3E300EAEAEA00F1F1F100F8F8F800F0FB + FF00A4A0A000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF + 0000FFFFFF000A0A0AEC0A0C0A0C0A0C0A0C0A0C0A0A0A0AEC12121212121212 + 121212120C0A0A0AEB09070909090909090909120A0A0A43EC920C9219090909 + 090109120C0A0A0A4343070919190909010109120A0A0A43EC920C9219191901 + F901010101010A0A43430709191901F9F9F9F9F9F9010A43EC920C92191919F9 + F9F9F9F9F9010A0A4343070919191919F9F909120C0A0A43EC920C9219191919 + 19F909120C0A0A0A4343070919191919191909120A0A0A43EC920C9219191919 + 19191912120A0A0A434307091919191912434343EC0A0A43EC920C9219191919 + 921912EC0A0A0A0A43430719191919199212EC0A0A0A0A0AECECECECECECECEC + EC0A0A0A0A0AE0010000C0010000C001000080010000C001000080000000C000 + 000080000000C001000080010000C001000080010000C001000080030000C007 + 0000C01F0000} + OldCreateOrder = False + Position = poDefaultPosOnly + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 12 + object Label1: TLabel + Left = 8 + Top = 8 + Width = 279 + Height = 12 + Caption = 'アーカイブ化するプロジェクトフォルダを選んでください :' + end + object ShellTreeView: TShellTreeView + Left = 8 + Top = 48 + Width = 390 + Height = 271 + Anchors = [akLeft, akTop, akRight, akBottom] + Checkboxes = False + Indent = 19 + TabOrder = 0 + OnChange = ShellTreeViewChange + ShellComboBox = ShellComboBox + ShellPopupMenu = ShellPopupMenu + ShVirtuaItems = [itNetWork] + end + object OKButton: TButton + Left = 221 + Top = 326 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = 'OK' + Default = True + ModalResult = 1 + TabOrder = 2 + end + object CancelButton: TButton + Left = 309 + Top = 326 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Cancel = True + Caption = 'キャンセル' + ModalResult = 2 + TabOrder = 4 + end + object ShellComboBox: TShellComboBox + Left = 8 + Top = 24 + Width = 390 + Height = 24 + Anchors = [akLeft, akTop, akRight] + TabOrder = 1 + end + object StatusBar: TStatusBar + Left = 389 + Top = 337 + Width = 19 + Height = 19 + Align = alNone + Anchors = [akRight, akBottom] + Panels = < + item + Bevel = pbNone + Width = 50 + end> + SimplePanel = False + end + object ShellPopupMenu: TShellPopupMenu + AutoPopup = False + InsertPos = 2 + Left = 192 + Top = 96 + object SelectMenuItem: TMenuItem + Caption = '選択' + Default = True + OnClick = SelectMenuItemClick + end + object N2: TMenuItem + Caption = '-' + end + end +end diff --git a/tools/win32/krdevui/RelFolderSelectorUnit.h b/tools/win32/krdevui/RelFolderSelectorUnit.h new file mode 100644 index 0000000..5887a6e --- /dev/null +++ b/tools/win32/krdevui/RelFolderSelectorUnit.h @@ -0,0 +1,43 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef RelFolderSelectorUnitH +#define RelFolderSelectorUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include "ShellCtrls.hpp" +#include +#include +//--------------------------------------------------------------------------- +class TRelFolderSelectorForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TShellTreeView *ShellTreeView; + TButton *OKButton; + TButton *CancelButton; + TShellComboBox *ShellComboBox; + TLabel *Label1; + TStatusBar *StatusBar; + TShellPopupMenu *ShellPopupMenu; + TMenuItem *SelectMenuItem; + TMenuItem *N2; + void __fastcall ShellTreeViewChange(TObject *Sender, TTreeNode *Node); + void __fastcall SelectMenuItemClick(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); +private: // ユーザー宣言 +public: // ユーザー宣言 + __fastcall TRelFolderSelectorForm(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TRelFolderSelectorForm *RelFolderSelectorForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/RelMain.cpp b/tools/win32/krdevui/RelMain.cpp new file mode 100644 index 0000000..c271abe --- /dev/null +++ b/tools/win32/krdevui/RelMain.cpp @@ -0,0 +1,369 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include + +#include "RelMain.h" +#include "RelDirSearchUnit.h" +#include "RelFolderSelectorUnit.h" +#include "RelSettingsUnit.h" + +//--------------------------------------------------------------------------- +static void _UIExecReleaser() +{ + // load xp3enc.dll + HMODULE xp3enc = LoadLibrary("xp3enc.dll"); + if(xp3enc) + { + void * funcptr; + funcptr = GetProcAddress(xp3enc, "XP3ArchiveAttractFilter_v2"); + if(funcptr) + { + *(void**)&XP3ArchiveAttractFilter_v2_org = funcptr; + XP3EncDLLAvailable = true; + } + } + + // start releaser + AnsiString projfolder; + AnsiString outputfile; + AnsiString rpffile; + TStringList *filelist; + TStringList *extlist; + + bool go_immediate = false; + bool write_rpf = true; + + int paramcount = ParamCount(); + for(int i = 1; i <= paramcount; i++) + { + AnsiString param = ParamStr(i); + if(param.c_str()[0] != '-') + projfolder = param; + else if(param == "-go") + go_immediate = true; + else if(param == "-nowriterpf") + write_rpf = false; + else if(param == "-out") + { + i++; + outputfile = ParamStr(i); + } + else if(param == "-rpf") + { + i++; + rpffile = ParamStr(i); + } + } + + if(projfolder != "") + { + if(projfolder.c_str()[0] == '\\' && + projfolder.c_str()[1] == '\\') + { + projfolder = ExpandUNCFileName(projfolder); + } + else + { + projfolder = ExpandFileName(projfolder); + } + projfolder = ExcludeTrailingBackslash(projfolder); + + if(!DirectoryExists(projfolder)) + { + MessageBox(NULL, ("Folder \"" + projfolder + "\" does not exist").c_str(), + "Error", MB_OK); + ExitProcess(0); + } + + projfolder = IncludeTrailingBackslash(projfolder); + + filelist = new TStringList(); + extlist = new TStringList(); + goto search; + } + +start: + + filelist = new TStringList(); + extlist = new TStringList(); + { + int res; + TRelFolderSelectorForm *form = new TRelFolderSelectorForm(Application); + res = form->ShowModal(); + projfolder = IncludeTrailingBackslash(form->ShellTreeView->Path); + delete form; + + if(res == mrCancel) + { + delete filelist; + delete extlist; + return; + } + + } + +search: + { + bool state; + TRelDirSearchForm * form = new TRelDirSearchForm(Application); + form->Visible = true; + state = form->GetFileList(projfolder); + if(state == false) + { + delete form; + delete filelist; + delete extlist; + return; + } + filelist->Assign(form->FileList); + extlist->Assign(form->ExtList); + delete form; + } + + + { + int res; + TRelSettingsForm * form = new TRelSettingsForm(Application); + form->SetGoImmediate(go_immediate); + form->SetWriteDefaultRPF(write_rpf); + form->SetProjFolder(projfolder); + form->SetFileList(filelist); + delete filelist; + form->SetExtList(extlist); + delete extlist; + if(rpffile == "") + form->LoadDefaultProfile(); + else + form->LoadProfile(rpffile); + if(outputfile != "") form->SetOutputFilename(outputfile); + res = form->ShowModal(); + delete form; + if(res == mrRetry) goto start; + } +} +//--------------------------------------------------------------------------- +extern "C" void _export PASCAL UIExecReleaser() +{ + _UIExecReleaser(); + ExitProcess(0); +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// tTVPStream base stream class +//--------------------------------------------------------------------------- +void tTVPStream::SetEndOfStorage() +{ + throw Exception("cannot write"); +} +//--------------------------------------------------------------------------- +void tTVPStream::ReadBuffer(void *buffer, unsigned int read_size) +{ + if(Read(buffer, read_size)!=read_size) + throw Exception("cannot read"); +} +//--------------------------------------------------------------------------- +void tTVPStream::WriteBuffer(const void *buffer, unsigned int write_size) +{ + if(Write(buffer, write_size)!=write_size) + throw Exception("cannot write"); +} +//--------------------------------------------------------------------------- +void tTVPStream::WriteInt64C(__int64 n) +{ + // compressed int64 + int bytes = 0; + __int64 mask = (__int64)-1; + + while(bytes < 8) + { + if((n & mask) == 0) break; + mask <<= 8; + bytes++; + } + + WriteBuffer(&bytes, 1); + if(bytes) WriteBuffer(&n, bytes); +} +//--------------------------------------------------------------------------- +void tTVPStream::WriteInt64(__int64 n) +{ + // this function is for intel byte order systems + WriteBuffer(&n, 8); +} +//--------------------------------------------------------------------------- +void tTVPStream::WriteInt32(__int32 n) +{ + WriteBuffer(&n, 4); +} +//--------------------------------------------------------------------------- +void tTVPStream::WriteInt16(__int16 n) +{ + WriteBuffer(&n, 2); +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// XP3 filter related +//--------------------------------------------------------------------------- +bool XP3EncDLLAvailable = false; +void (__stdcall * XP3ArchiveAttractFilter_v2_org)( + unsigned __int32 hash, + unsigned __int64 offset, void * buffer, long bufferlen) = NULL; +void (__stdcall * XP3ArchiveAttractFilter_v2)( + unsigned __int32 hash, + unsigned __int64 offset, void * buffer, long bufferlen) = NULL; +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// tTVPLocalFileStream +//--------------------------------------------------------------------------- +tTVPLocalFileStream::tTVPLocalFileStream(const char *name, + unsigned int flag, bool useencryption, unsigned __int32 salt) +{ + FileName = NULL; + Handle = INVALID_HANDLE_VALUE; + UseEncryption = useencryption; + Salt = salt; + + FileName = new char[strlen(name) + 1]; + try + { + strcpy(FileName, name); + + unsigned int access = flag & TVP_ST_ACCESS_MASK; + + DWORD dwcd; + DWORD rw; + switch(access) + { + case TVP_ST_READ: + rw = GENERIC_READ; dwcd = OPEN_EXISTING; break; + case TVP_ST_WRITE: + rw = GENERIC_WRITE; dwcd = CREATE_ALWAYS; break; + case TVP_ST_APPEND: + rw = GENERIC_WRITE; dwcd = OPEN_ALWAYS; break; + case TVP_ST_UPDATE: + rw = GENERIC_WRITE|GENERIC_READ; dwcd = OPEN_EXISTING; break; + } + + Handle = CreateFile( + name, + rw, + FILE_SHARE_READ, // read shared accesss is strongly needed + NULL, + dwcd, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if(Handle == INVALID_HANDLE_VALUE) + { + throw Exception(AnsiString("Cannot open ")+ name); + } + + if(access == TVP_ST_APPEND) + { + // move the file pointer to last + SetFilePointer(Handle, 0, NULL, FILE_END); + } + } + catch(...) + { + delete [] FileName; + throw; + } + +} +//--------------------------------------------------------------------------- +tTVPLocalFileStream::~tTVPLocalFileStream() +{ + if(Handle!=INVALID_HANDLE_VALUE) CloseHandle(Handle); + if(FileName) delete [] FileName; +} +//--------------------------------------------------------------------------- +unsigned __int64 tTVPLocalFileStream::Seek(__int64 offset, int whence) +{ + DWORD dwmm; + switch(whence) + { + case TVP_ST_SEEK_SET: dwmm = FILE_BEGIN; break; + case TVP_ST_SEEK_CUR: dwmm = FILE_CURRENT; break; + case TVP_ST_SEEK_END: dwmm = FILE_END; break; + default: dwmm = FILE_BEGIN; break; // may be enough + } + + DWORD low; + + low = SetFilePointer(Handle, (LONG)offset, ((LONG*)&offset)+1, dwmm); + + if(low == 0xffffffff && GetLastError() != NO_ERROR) + { + return 0xffffffffffffffff; + } + unsigned __int64 ret; + *(DWORD*)&ret = low; + *((DWORD*)&ret+1) = *((DWORD*)&offset+1); + + return ret; +} +//--------------------------------------------------------------------------- +unsigned int tTVPLocalFileStream::Read(void *buffer, unsigned int read_size) +{ + DWORD ret = 0; + + unsigned __int64 current; + + if(XP3ArchiveAttractFilter_v2) + current = Seek(0, TVP_ST_SEEK_CUR); + + ReadFile(Handle, buffer, read_size, &ret, NULL); + + if(ret && XP3ArchiveAttractFilter_v2 && UseEncryption) + { + // v2 read filter + XP3ArchiveAttractFilter_v2(Salt, current, buffer, ret); + } + + return ret; +} +//--------------------------------------------------------------------------- +unsigned int tTVPLocalFileStream::Write(const void *buffer, unsigned int write_size) +{ + DWORD ret = 0; + WriteFile(Handle, buffer, write_size, &ret, NULL); + return ret; +} +//--------------------------------------------------------------------------- +void tTVPLocalFileStream::SetEndOfStorage() +{ + if(!SetEndOfFile(Handle)) throw Exception("cannot write"); +} +//--------------------------------------------------------------------------- +unsigned __int64 tTVPLocalFileStream::GetSize() +{ + unsigned __int64 ret; + *(DWORD*)&ret = GetFileSize(Handle, ((DWORD*)&ret+1)); + return ret; +} +//--------------------------------------------------------------------------- + + + +#pragma package(smart_init) diff --git a/tools/win32/krdevui/RelMain.h b/tools/win32/krdevui/RelMain.h new file mode 100644 index 0000000..57ad500 --- /dev/null +++ b/tools/win32/krdevui/RelMain.h @@ -0,0 +1,130 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef RelMainH +#define RelMainH +//--------------------------------------------------------------------------- +#define TVP_ST_UNKNOWN_SIZE ((tvp_uint64)(tvp_int64)-1) +#define TVP_ST_READ 0 +#define TVP_ST_WRITE 1 +#define TVP_ST_APPEND 2 +#define TVP_ST_UPDATE 3 +#define TVP_ST_ACCESS_MASK 0x0f + +#define TVP_ST_SEEK_SET 0 +#define TVP_ST_SEEK_CUR 1 +#define TVP_ST_SEEK_END 2 + + +//--------------------------------------------------------------------------- +// tTVPStream base stream class +//--------------------------------------------------------------------------- +class tTVPStream +{ +private: +public: + //-- constructor/destructor + tTVPStream() {;} + virtual ~tTVPStream() {;} + + //-- must implement + virtual unsigned __int64 Seek(__int64 offset, int whence) = 0; + /* if error, position is not changed */ + + //-- optionally to implement + virtual unsigned int Read(void *buffer, unsigned int read_size) { return 0; } + /* returns actually read size */ + + virtual unsigned int Write(const void *buffer, unsigned int write_size) { return 0; } + /* returns actually written size */ + + virtual void SetEndOfStorage(); // the default behavior is raising a exception + /* if error, raises exception */ + + //-- should implement for higher performance + virtual unsigned __int64 GetSize() + { + unsigned __int64 orgpos = GetPosition(); + unsigned __int64 size = Seek(0, SEEK_END); + Seek(orgpos, SEEK_SET); + return size; + } + + //-- below functions are utitlity functions. child classes should not + //-- override these. + unsigned __int64 GetPosition() + { + return Seek(0, SEEK_CUR); + } + + unsigned __int64 SetPosition(unsigned __int64 pos) + { + return Seek(pos, SEEK_SET); + } + + void ReadBuffer(void *buffer, unsigned int read_size); + void WriteBuffer(const void *buffer, unsigned int write_size); + /* ReadBuffer and WriteBuffer raise exception when specified size was not + read/witten. */ + + void WriteInt64C(__int64 n); + void WriteInt64(__int64 n); + void WriteInt32(__int32 n); + void WriteInt16(__int16 n); +}; +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// XP3 filter related +//--------------------------------------------------------------------------- +extern bool XP3EncDLLAvailable; +extern void (__stdcall * XP3ArchiveAttractFilter_v2_org)( + unsigned __int32 hash, + unsigned __int64 offset, void * buffer, long bufferlen); +extern void (__stdcall * XP3ArchiveAttractFilter_v2)( + unsigned __int32 hash, + unsigned __int64 offset, void * buffer, long bufferlen); +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// tTVPLocalFileStream +//--------------------------------------------------------------------------- +class tTVPLocalFileStream : public tTVPStream +{ +private: + HANDLE Handle; + char *FileName; + bool UseEncryption; + unsigned __int32 Salt; + +public: + tTVPLocalFileStream(const char *name, unsigned int flag, bool useencryption = false, + unsigned __int32 salt = 0); + ~tTVPLocalFileStream(); + + unsigned __int64 Seek(__int64 offset, int whence); + + unsigned int Read(void *buffer, unsigned int read_size); + unsigned int Write(const void *buffer, unsigned int write_size); + + void SetEndOfStorage(); + + unsigned __int64 GetSize(); + + HANDLE GetHandle() { return Handle; } +}; +//--------------------------------------------------------------------------- + +#endif diff --git a/tools/win32/krdevui/RelSettingsUnit.cpp b/tools/win32/krdevui/RelSettingsUnit.cpp new file mode 100644 index 0000000..f678ab4 --- /dev/null +++ b/tools/win32/krdevui/RelSettingsUnit.cpp @@ -0,0 +1,1366 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop +#include +#include + +#include + +#include "RelSettingsUnit.h" +#include "RelMain.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "ConfMainFrameUnit" +#pragma resource "*.dfm" +TRelSettingsForm *RelSettingsForm; +//--------------------------------------------------------------------------- +#define SPACER 6 +__fastcall TRelSettingsForm::TRelSettingsForm(TComponent* Owner) + : TForm(Owner) +{ + GoImmediate = false; + WriteDefaultRPF = true; + + FileList = new TStringList(); + ExeOptionsSheet->TabVisible = 0; + + // adjust components + SelectFolderButton->Left = SPACER; + SelectFolderButton->Top = ClientHeight - SPACER - SelectFolderButton->Height; + OKButton->Top = ClientHeight - SPACER - OKButton->Height; + OKButton->Left = ClientWidth - SPACER - CancelButton->Width - SPACER - + OKButton->Width; + CancelButton->Top = ClientHeight - SPACER - CancelButton->Height; + CancelButton->Left = ClientWidth - SPACER - CancelButton->Width; + ProgressLabel->Top = CancelButton->Top; + ProgressLabel->Left = SPACER; + ProgressLabel->Width = OKButton->Left - SPACER - ProgressLabel->Left; + + PageControl->Left = SPACER; + PageControl->Top = SPACER; + PageControl->Width = ClientWidth - SPACER*2; + PageControl->Height = OKButton->Top - PageControl->Top- SPACER; + LoadProfileButton->Top = PageControl->Top - 2; + LoadProfileButton->Left = ClientWidth - LoadProfileButton->Width - SPACER; + SaveProfileButton->Top = PageControl->Top - 2; + SaveProfileButton->Left = LoadProfileButton->Left - SaveProfileButton->Width + - SPACER; + StaticText1->Top = PageControl->Top; + StaticText1->Left = SaveProfileButton->Left - StaticText1->Width - SPACER; + + ConfMainFrame->ReadOptions(GetKrKrFileName()); + + if(!XP3EncDLLAvailable) UseXP3EncDLLCheck->Visible = false; +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::FormDestroy(TObject *Sender) +{ + if(FileList) delete FileList; +} +//--------------------------------------------------------------------------- +AnsiString __fastcall TRelSettingsForm::GetKrKrFileName() +{ + AnsiString fn = ExtractFileDir(ParamStr(0)) + "\\krkr.eXe"; + if(!FileExists(fn)) + { + fn = ExtractFileDir(ParamStr(0)) + "\\..\\krkr.eXe"; + if(!FileExists(fn)) return ""; + } + return fn; +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::SetProjFolder(AnsiString folder) +{ + ProjFolder = folder; + InputDirectoryMemo->Text = ProjFolder; +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::SetFileList(TStringList *list) +{ + FileList->Assign(list); +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::SetExtList(TStringList *list) +{ + // distributes the list among three default lists; + // compress, just store, discard. + + CompressExtList->Items->BeginUpdate(); + StoreExtList->Items->BeginUpdate(); + DiscardExtList->Items->BeginUpdate(); + + int i; + for(i=0; iCount; i++) + { + AnsiString ext = list->Strings[i]; + if( + !ext.AnsiCompareIC(".xpk") || + !ext.AnsiCompareIC(".xp3") || + !ext.AnsiCompareIC(".exe") || + !ext.AnsiCompareIC(".bat") || + !ext.AnsiCompareIC(".tmp") || + !ext.AnsiCompareIC(".db") || + !ext.AnsiCompareIC(".sue") || + !ext.AnsiCompareIC(".vix") || + !ext.AnsiCompareIC(".ico") || + !ext.AnsiCompareIC(".aul") || + !ext.AnsiCompareIC(".aue") || + !ext.AnsiCompareIC(".rpf") || + !ext.AnsiCompareIC(".bak") || + !ext.AnsiCompareIC(".log") || + !ext.AnsiCompareIC(".kep") || + !ext.AnsiCompareIC(".cf") || + !ext.AnsiCompareIC(".cfu") || + ext == "" || !strncmp(ext.c_str(), ".~", 2)) + { + if(ext == "") ext = NoExtNameLabel->Caption; + DiscardExtList->Items->Add(ext); + } + else if( + !ext.AnsiCompareIC(".wav") || + !ext.AnsiCompareIC(".dll") || + !ext.AnsiCompareIC(".tpi") || + !ext.AnsiCompareIC(".spi") || + !ext.AnsiCompareIC(".txt") || + !ext.AnsiCompareIC(".mid") || + !ext.AnsiCompareIC(".smf") || + !ext.AnsiCompareIC(".swf") || + !ext.AnsiCompareIC(".ks") || + !ext.AnsiCompareIC(".tjs") || + !ext.AnsiCompareIC(".ma") || + !ext.AnsiCompareIC(".asq") || + !ext.AnsiCompareIC(".asd") || + !ext.AnsiCompareIC(".ttf") || + !ext.AnsiCompareIC(".ttc") || + !ext.AnsiCompareIC(".bmp") || + !ext.AnsiCompareIC(".tft") || + !ext.AnsiCompareIC(".cks") ) + { + CompressExtList->Items->Add(ext); + } + else + { + StoreExtList->Items->Add(ext); + } + + } + + CompressExtList->Items->EndUpdate(); + StoreExtList->Items->EndUpdate(); + DiscardExtList->Items->EndUpdate(); + +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::LoadDefaultProfile() +{ + AnsiString n = ProjFolder + "default.rpf"; + if(FileExists(n)) + { + LoadProfile(n); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::MoveSelected(TListBox *dest, TListBox *src) +{ + // move selected items from src to dest + int i; + for(i=0; iItems->Count; i++) + { + if(src->Selected[i]) + { + dest->Items->Add(src->Items->Strings[i]); + } + } + + for(i=src->Items->Count-1; i>=0; i--) + { + if(src->Selected[i]) + { + src->Items->Delete(i); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::CompressExtListStartDrag(TObject *Sender, + TDragObject *&DragObject) +{ + if(((TListBox*)Sender)->SelCount ==0 ) CancelDrag(); +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::CompressExtListDragOver(TObject *Sender, + TObject *Source, int X, int Y, TDragState State, bool &Accept) +{ + Accept = false; + if(Source!=Sender && AnsiString(Source->ClassName()) == "TListBox") Accept=true; +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::CompressExtListDragDrop(TObject *Sender, + TObject *Source, int X, int Y) +{ + MoveSelected((TListBox*)Sender, (TListBox*)Source); +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::Button1Click(TObject *Sender) +{ + MoveSelected(CompressExtList, StoreExtList); +} +//--------------------------------------------------------------------------- + +void __fastcall TRelSettingsForm::Button2Click(TObject *Sender) +{ + MoveSelected(StoreExtList, CompressExtList); +} +//--------------------------------------------------------------------------- + +void __fastcall TRelSettingsForm::Button3Click(TObject *Sender) +{ + MoveSelected(StoreExtList, DiscardExtList); +} +//--------------------------------------------------------------------------- + +void __fastcall TRelSettingsForm::Button4Click(TObject *Sender) +{ + MoveSelected(DiscardExtList, StoreExtList); +} +//--------------------------------------------------------------------------- + +void __fastcall TRelSettingsForm::SetFileNameButtonClick(TObject *Sender) +{ + SaveDialog->FileName = OutputFileNameEdit->Text; + if(SaveDialog->Execute()) + { + OutputFileNameEdit->Text = SaveDialog->FileName; + if(SaveDialog->FilterIndex == 1) + { + XP3ArchiveRadio->Checked = true; + XP3ArchiveRadioClick(this); + } + else if(SaveDialog->FilterIndex == 2) + { + ExecutableRadio->Checked = true; + ExecutableRadioClick(this); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::XP3ArchiveRadioClick(TObject *Sender) +{ + if(OutputFileNameEdit->Text != "") + { + OutputFileNameEdit->Text = + ChangeFileExt(OutputFileNameEdit->Text, ".xp3"); + } + SaveDialog->FilterIndex = 1; + ExeOptionsSheet->TabVisible = false; +} +//--------------------------------------------------------------------------- + +void __fastcall TRelSettingsForm::ExecutableRadioClick(TObject *Sender) +{ + if(GetKrKrFileName() == "") + { + MessageDlg( + MissingKrKrEXELabel->Caption, + mtError, TMsgDlgButtons() << mbOK, 0); + XP3ArchiveRadio->Checked = true; + return; + } + if(OutputFileNameEdit->Text != "") + { + OutputFileNameEdit->Text = + ChangeFileExt(OutputFileNameEdit->Text, ".exe"); + } + SaveDialog->FilterIndex =2; + ExeOptionsSheet->TabVisible = true; +} +//--------------------------------------------------------------------------- + +void __fastcall TRelSettingsForm::CompressLimitCheckClick(TObject *Sender) +{ + bool b = CompressLimitCheck->Checked; + CompressLimitSizeEdit->Enabled = b; + CompressLimitSizeLabel->Font->Color = b?clWindowText:clGrayText; +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::CompressLimitSizeEditKeyPress( + TObject *Sender, char &Key) +{ + if(isprint(Key) && ( Key < '0' || Key > '9')) Key = 0; +} +//--------------------------------------------------------------------------- + +void __fastcall TRelSettingsForm::CompressLimitSizeEditExit( + TObject *Sender) +{ + CompressLimitSizeEdit->Text = atoi(CompressLimitSizeEdit->Text.c_str()); +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::SaveProfile(AnsiString name) +{ + TMemIniFile *ini = new TMemIniFile(name); + try + { + SaveProfileToIni(ini); + ini->UpdateFile(); + } + catch(...) + { + delete ini; + throw; + } + delete ini; +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::LoadProfile(AnsiString name) +{ + TMemIniFile *ini = new TMemIniFile(name); + try + { + LoadProfileFromIni(ini); + } + catch(...) + { + delete ini; + throw; + } + delete ini; +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::SaveProfileToIni(TMemIniFile *ini) +{ + ini->WriteBool("Output", "Executable", ExecutableRadio->Checked); + ini->WriteString("Output", "OutputFileName", OutputFileNameEdit->Text); + + ini->WriteString("Extensions", "Compress", CompressExtList->Items->CommaText); + ini->WriteString("Extensions", "Store", StoreExtList->Items->CommaText); + ini->WriteString("Extensions", "Discard", DiscardExtList->Items->CommaText); + + ini->WriteBool("Options", "DoCompressSizeLimit", CompressLimitCheck->Checked); + ini->WriteInteger("Options", "CompressSizeLimit", + CompressLimitSizeEdit->Text.ToInt()); + ini->WriteBool("Options", "Protect", ProtectCheck->Checked); + ini->WriteBool("Options", "OVBookShare", OVBookShareCheck->Checked); + ini->WriteBool("Options", "CompressIndex", CompressIndexCheck->Checked); + ini->WriteBool("Options", "UseXP3EncDLL", UseXP3EncDLLCheck->Checked); + + ConfMainFrame->WriteToIni(ini); +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::LoadProfileFromIni(TMemIniFile *ini) +{ + ConfMainFrame->ReadFromIni(ini); + ConfMainFrame->ApplyReadDataToUI(); + + ExecutableRadio->Checked = ini->ReadBool("Output", "Executable", + false); + if(ExecutableRadio->Checked) + { + ExecutableRadioClick(this); + } + else + { + XP3ArchiveRadio->Checked = true; + XP3ArchiveRadioClick(this); + } + + OutputFileNameEdit->Text = ini->ReadString("Output", "OutputFileName", ""); + + LoadExtList(ini->ReadString("Extensions", "Compress", ""), + CompressExtList->Items, StoreExtList->Items, DiscardExtList->Items); + LoadExtList(ini->ReadString("Extensions", "Store", ""), + StoreExtList->Items, DiscardExtList->Items, CompressExtList->Items); + LoadExtList(ini->ReadString("Extensions", "Discard", ""), + DiscardExtList->Items, StoreExtList->Items, CompressExtList->Items); + + CompressLimitCheck->Checked = ini->ReadBool("Options", "DoCompressSizeLimit", + true); + CompressLimitSizeEdit->Text = AnsiString(ini->ReadInteger("Options", + "CompressSizeLimit", 1024)); + CompressLimitCheckClick(this); + ProtectCheck->Checked = ini->ReadBool("Options", "Protect", false); + OVBookShareCheck->Checked = ini->ReadBool("Options", "OVBookShare", true); + CompressIndexCheck->Checked = ini->ReadBool("Options", "CompressIndex", true); + UseXP3EncDLLCheck->Checked = ini->ReadBool("Options", "UseXP3EncDLL", false); + + // adjust + if(!XP3EncDLLAvailable) + UseXP3EncDLLCheck->Checked = false; // xp3encdll not found +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::LoadExtList(AnsiString ext, TStrings *to, + TStrings *f1, TStrings *f2) +{ + // split the ext into ext list + TStringList *list = new TStringList(); + list->CommaText = ext; + for(int i= 0; i< list->Count; i++) + { + AnsiString e =list->Strings[i]; + if(-1 == to->IndexOf(e)) + { + int n; + if(-1 != (n = f1->IndexOf(e))) + { + f1->Delete(n); + to->Add(e); + } + else if(-1 != (n = f2->IndexOf(e))) + { + f2->Delete(n); + to->Add(e); + } + } + } + delete list; +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::SaveProfileButtonClick(TObject *Sender) +{ + if(SaveProfileDialog->Execute()) + { + SaveProfile(SaveProfileDialog->FileName); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TRelSettingsForm::LoadProfileButtonClick(TObject *Sender) +{ + if(OpenProfileDialog->Execute()) + { + LoadProfile(OpenProfileDialog->FileName); + } +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::OKButtonClick(TObject *Sender) +{ + if(ExecutableRadio->Checked && GetKrKrFileName() == "") + { + MessageDlg( + MissingKrKrEXELabel->Caption, + mtError, TMsgDlgButtons() << mbOK, 0); + return; + } + + if(OutputFileNameEdit->Text == "") + { + SetFileNameButton->Click(); + if(OutputFileNameEdit->Text == "") return; + } + + if(ExecutableRadio->Checked) + { + if(!ConfMainFrame->CheckOK()) return; + } + + if(!GoImmediate) + { + if(FileExists(OutputFileNameEdit->Text)) + { + int mr = + MessageDlg(OutputFileNameEdit->Text + ConfirmOverwriteLabel->Caption, + mtWarning, TMsgDlgButtons() << mbYes << mbNo, 0); + if(mr != mrYes) return; + } + } + + PageControl->Enabled = false; + SaveProfileButton->Enabled = false; + LoadProfileButton->Enabled = false; + SelectFolderButton->Visible = false; + OKButton->Enabled = false; + + try + { + _CreateArchive(); + } + __finally + { + PageControl->Enabled = true; + SaveProfileButton->Enabled = true; + LoadProfileButton->Enabled = true; + SelectFolderButton->Visible = true; + OKButton->Enabled = true; + ProgressLabel->Caption = ""; + } + + + if(GoImmediate) ::PostMessage(Handle, WM_USER + 0x11, 0, 0); + +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + if(CancelButton->Caption == InterruptNameLabel->Caption) + { + CanClose = false; + Aborted = true; + } +} +//--------------------------------------------------------------------------- + +void __fastcall TRelSettingsForm::CancelButtonClick(TObject *Sender) +{ + if(CancelButton->Caption == InterruptNameLabel->Caption) + { + Aborted = true; + } + else + { + ModalResult = mrCancel; + } +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::_CreateArchive(void) +{ + Aborted = false; + AnsiString orgcancelcap = CancelButton->Caption; + CancelButton->Caption = InterruptNameLabel->Caption; + try + { + CreateArchive(); + } + catch(...) + { + CancelButton->Caption = orgcancelcap; + throw; + } + if(!GoImmediate) + { + MessageDlg(ExecutableRadio->Checked? + ExecutableCreatedNameLabel->Caption:ArchiveCreatedNameLabel->Caption, + mtInformation, TMsgDlgButtons() << mbOK, 0); + } + CancelButton->Caption = ExitNameLabel->Caption; +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::FormShow(TObject *Sender) +{ + if(GoImmediate) ::PostMessage(Handle, WM_USER + 0x10, 0, 0); +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::WMStart(TMessage &msg) +{ + OKButton->Click(); +} +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::WMClose(TMessage &msg) +{ + CancelButton->Click(); +} +//--------------------------------------------------------------------------- +struct TFileSegment +{ + unsigned __int32 Flags; + unsigned __int64 Offset; + unsigned __int64 StoreSize; + unsigned __int64 OrgSize; +}; + +struct TFileInfo +{ + unsigned __int32 Flags; + unsigned __int64 FileSize; + unsigned __int64 StoreSize; + unsigned __int32 Adler32; // adler32 running checksum + std::vector Segments; + AnsiString LocalFileName; + AnsiString FileName; +}; + +#define OV_MATCH_BUF_LEN 32768 +#define OV_MATCH_MIN 128 +#define OV_MATCH_DIF_MAX 256 +#define OV_MATCH_HOLD 16 + +static bool DetectMatch(unsigned char *ref, int reflen, unsigned char *buf, int buflen, + std::vector &refstart, std::vector &bufstart, std::vector &len) +{ + if(reflen <= OV_MATCH_MIN) return false; + if(buflen <= OV_MATCH_MIN) return false; + + bool anymatched = false; + int bufpos; + int refpos; + for(bufpos = 0; bufpos= reflen - OV_MATCH_MIN) refmax = reflen - OV_MATCH_MIN; + for(refpos = (bufpos reflen-refpos ? reflen-refpos : buflen-bufpos; + unsigned char *rp = ref + refpos; + unsigned char *bp = buf + bufpos; + while(*rp == *bp && remain) rp++, bp++, remain--; + matchlen = rp - (ref + refpos); + + if(matchlen >= OV_MATCH_MIN) + { + // matched + refstart.push_back(refpos); + bufstart.push_back(bufpos); + len.push_back(matchlen); + matched = true; + break; + } + } + } + + if(matched) + bufpos += matchlen, anymatched = true; + else + bufpos++; + } + + return anymatched; +} + +struct TOVCodeBookInfo +{ + unsigned __int64 Offset[OV_MATCH_HOLD]; // offset in archive file + int HeadersLen[OV_MATCH_HOLD]; // byte length in Headers + unsigned char Headers[OV_MATCH_HOLD][OV_MATCH_BUF_LEN]; + // first OV_MATCH_BUF_LEN of the ogg vorbis flie +}; +//--------------------------------------------------------------------------- +static void Copy(tTVPLocalFileStream &dest, tTVPLocalFileStream &src, + unsigned __int64 length) +{ + // copy stream + + if(length == 0) return; + + unsigned __int64 remain = length; + BYTE *buf = new BYTE[1024*1024]; + try + { + while(remain) + { + int onesize = + remain > 1*1024*1024 ? 1*1024*1024 : (int)remain; + src.ReadBuffer(buf, onesize); + dest.WriteBuffer(buf, onesize); + remain -= onesize; + } + } + catch(...) + { + delete [] buf; + throw; + } + delete [] buf; +} +//--------------------------------------------------------------------------- +static unsigned __int32 GetFileCheckSum(tTVPLocalFileStream &src) +{ + // compute file checksum via adler32. + // src's file pointer is to be reset to zero. + unsigned __int32 adler32sum = adler32(0L, Z_NULL, 0); + + BYTE *buf = new BYTE[1024*1024]; + try + { + while(true) + { + int onesize = src.Read(buf, 1024*1024); + if(onesize == 0) break; + adler32sum = adler32(adler32sum, buf, onesize); + } + } + catch(...) + { + delete [] buf; + throw; + } + delete [] buf; + + src.SetPosition(0); + + return adler32sum; +} +//--------------------------------------------------------------------------- +static bool CompareFile(AnsiString file1, AnsiString file2) +{ + // compare two files; + // returns true if all matched. + tTVPLocalFileStream f1(file1.c_str(), TVP_ST_READ); + tTVPLocalFileStream f2(file2.c_str(), TVP_ST_READ); + + BYTE *buf1 = NULL; + BYTE *buf2 = NULL; + bool matched = true; + try + { + buf1 = new BYTE[1024*1024]; + buf2 = new BYTE[1024*1024]; + while(true) + { + int onesize1 = f1.Read(buf1, 1024*1024); + int onesize2 = f2.Read(buf2, 1024*1024); + if(onesize1 != onesize2) + { + matched = false; + break; + } + if(onesize1 == 0) break; + if(memcmp(buf1, buf2, onesize1)) + { + matched = false; + break; + } + } + } + catch(...) + { + if(buf1) delete [] buf1; + if(buf2) delete [] buf2; + throw; + } + if(buf1) delete [] buf1; + if(buf2) delete [] buf2; + + return matched; +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +void __fastcall TRelSettingsForm::CreateArchive(void) +{ + // setup input filter + if(XP3EncDLLAvailable && UseXP3EncDLLCheck->Checked) + XP3ArchiveAttractFilter_v2 = XP3ArchiveAttractFilter_v2_org; + else + XP3ArchiveAttractFilter_v2 = NULL; + + // information vector + std::vector fileinfo; + + // ogg vorbis code books + int ovcb_index = 0; + std::auto_ptr ovcb(new TOVCodeBookInfo); + for(int i = 0; i< OV_MATCH_HOLD; i++) + { + ovcb->HeadersLen[i] = 0; + } + + // copy executable file or write a stub + if(ExecutableRadio->Checked) + { + ConfMainFrame->SetSourceAndTargetFileName(GetKrKrFileName(), OutputFileNameEdit->Text); + ConfMainFrame->CopyExe(); + } + else + { + // just touch + TFileStream * stream = new TFileStream(OutputFileNameEdit->Text, fmCreate); + delete stream; + } + + // open target file + tTVPLocalFileStream stream(OutputFileNameEdit->Text.c_str(), TVP_ST_APPEND); + + + unsigned __int64 offset = stream.GetPosition(); // real xp3 header start + + unsigned __int64 compsizelimit = (!CompressLimitCheck->Checked) ? + (__int64)-1 : CompressLimitSizeEdit->Text.ToInt() * (unsigned __int64 )1024; + + // count total files + int totalcount = 0; + for(int i=0; iCount; i++) + { + + AnsiString ext = ExtractFileExt(FileList->Strings[i]).LowerCase(); + if(ext == "") ext = NoExtNameLabel->Caption; + if(DiscardExtList->Items->IndexOf(ext) != -1) + continue; + totalcount ++; + } + + // write a header + stream.WriteBuffer("XP3\r\n \n\x1a ", 8); + stream.WriteBuffer("\x8b\x67\x01", 3); + stream.WriteInt64(11+4+8); // to cushion header + stream.WriteBuffer("\x01\x00\x00\x00", 4); // header minor version + + // cushion header + stream.WriteBuffer("\x80", 1); // continue + stream.WriteBuffer("\0\0\0\0\0\0\0\0", 8); // index size = 0 + unsigned __int64 index_pointer_pos = stream.GetPosition(); + stream.WriteBuffer(" ", 8); // to real header + + // write protection warning + if(ProtectCheck->Checked) + { + static char dummy_png [] = + "\x89\x50\x4e\x47\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00" + "\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90\x77\x53\xde" + "\x00\x00\x00\xa5\x74\x45\x58\x74\x57\x61\x72\x6e\x69\x6e\x67\x00" + "\x57\x61\x72\x6e\x69\x6e\x67\x3a\x20\x45\x78\x74\x72\x61\x63\x74" + "\x69\x6e\x67\x20\x74\x68\x69\x73\x20\x61\x72\x63\x68\x69\x76\x65" + "\x20\x6d\x61\x79\x20\x69\x6e\x66\x72\x69\x6e\x67\x65\x20\x6f\x6e" + "\x20\x61\x75\x74\x68\x6f\x72\x27\x73\x20\x72\x69\x67\x68\x74\x73" + "\x2e\x20\x8c\x78\x8d\x90\x20\x3a\x20\x82\xb1\x82\xcc\x83\x41\x81" + "\x5b\x83\x4a\x83\x43\x83\x75\x82\xf0\x93\x57\x8a\x4a\x82\xb7\x82" + "\xe9\x82\xb1\x82\xc6\x82\xc9\x82\xe6\x82\xe8\x81\x41\x82\xa0\x82" + "\xc8\x82\xbd\x82\xcd\x92\x98\x8d\xec\x8e\xd2\x82\xcc\x8c\xa0\x97" + "\x98\x82\xf0\x90\x4e\x8a\x51\x82\xb7\x82\xe9\x82\xa8\x82\xbb\x82" + "\xea\x82\xaa\x82\xa0\x82\xe8\x82\xdc\x82\xb7\x81\x42\x4b\x49\x44" + "\x27\x00\x00\x00\x0c\x49\x44\x41\x54\x78\x9c\x63\xf8\xff\xff\x3f" + "\x00\x05\xfe\x02\xfe\x0d\xef\x46\xb8\x00\x00\x00\x00\x49\x45\x4e" + "\x44\xae\x42\x60\x82\x89\x50\x4e\x47\x0a\x1a\x0a\x00\x00\x00\x0d" + "\x49\x48\x44\x52\x00\x00\x01\xef\x00\x00\x00\x13\x01\x03\x00\x00" + "\x00\x83\x60\x17\x58\x00\x00\x00\x06\x50\x4c\x54\x45\x00\x00\x00" + "\xff\xff\xff\xa5\xd9\x9f\xdd\x00\x00\x02\x4f\x49\x44\x41\x54\x78" + "\xda\xd5\xd3\x31\x6b\xdb\x40\x14\x07\x70\x1d\x0a\x55\xb3\x44\x6d" + "\xb2\xc4\x20\xac\x14\x9b\x78\x15\xf1\x12\x83\xf1\x0d\x1d\x4a\x21" + "\x44\x1f\xa2\xa1\x5a\xd3\x78\x49\xc0\x44\x86\x14\xb2\x04\xec\xc4" + "\x53\x40\xf8\xbe\x8a\x4c\x42\x6a\x83\xf0\x7d\x05\xb9\x15\xba\x55" + "\xe8\x2d\x3e\x10\x7a\x3d\x25\xf9\x06\x19\x4a\x6f\x38\x74\x9c\x7e" + "\xf7\x7f\x8f\xe3\x34\xc4\x37\x8c\x52\x7b\x8b\xfe\xe7\x3c\xe3\x8b" + "\xd7\xef\x02\x45\x06\x99\xae\x99\x02\x11\x10\x39\xa2\x2c\x7d\x2e" + "\x68\x3b\xf7\x53\x1f\x27\x65\x17\xd6\xba\x44\x51\xed\x31\x79\xcd" + "\xd4\xff\xbc\xd4\x62\xa2\x78\x3c\xb0\x48\xb5\xcc\x00\xc0\xe1\x82" + "\xc4\x7d\x89\xbc\xf1\xc2\x0f\xb5\x33\x3f\xbd\x34\xc7\x4e\x02\x12" + "\xd4\xd9\x04\x0a\xe3\x56\xf1\xdb\x67\x9e\x6d\x0e\x6d\xc4\xb5\x2b" + "\x15\x5f\x92\xe1\xa9\xae\xbd\x27\x80\x00\x06\xdf\xc4\x70\xd7\x20" + "\x73\xb3\x9d\xea\x5a\xb1\xbf\x51\x24\xc3\x33\xbd\x33\x27\x10\xd2" + "\xe5\xc6\xfa\x88\xfc\x0c\x1d\x5d\xf1\x46\x47\x15\x9e\x7b\xf7\x18" + "\x9b\x4c\x8a\xdc\x55\xe9\xaa\xc0\x1d\x9c\xd5\x54\x7a\x9f\x73\x1a" + "\x25\x2c\x91\xed\xe1\x87\xa6\x00\x45\x85\x00\xc6\x6e\x56\x26\xbb" + "\x79\x4e\x2f\xbf\xaa\x3a\x15\x9f\xb0\x82\xdb\x72\x55\xf5\x6e\xcc" + "\x70\xdd\x47\xde\xc1\xac\x77\x11\xba\x5d\x32\x9b\x6a\xb5\xf6\x66" + "\x37\x59\xc5\x44\xa2\x31\x03\x4e\x03\xd9\xd2\x83\xb0\x6e\x56\xbd" + "\x6b\x26\x62\xea\x4d\xc2\x6e\x64\xcb\xc7\x03\x97\x2e\xbd\x00\x25" + "\x54\x3c\xb6\x04\xe3\xf4\x41\x5c\x09\x68\x6f\x9f\x9f\x3c\x3a\x52" + "\xdb\xf2\x82\xec\x50\xb7\xe4\x3e\x09\x8a\x82\xbf\x5e\x9c\x48\xbd" + "\x6b\x2c\x16\x0c\xe6\x19\xd9\x3b\xf6\x7a\x1e\xbc\xf0\x23\xc5\x0f" + "\x35\x8f\x0d\xfb\x07\xda\x6e\x73\x9e\xeb\x58\x7a\xbd\x6f\x8c\x5a" + "\xb0\xbf\xf1\xc2\xd7\x46\x48\x91\xa7\x1e\x43\xc9\x19\x64\xf9\x8e" + "\xc3\x8d\x27\x57\x40\xcf\xec\xe0\x3c\xba\x9e\x44\xbd\x8e\x98\x6e" + "\xf5\x0f\xb6\x4f\x93\x0c\x5a\x21\x35\x9e\x3e\x4f\x2f\x2d\x68\xde" + "\x04\x71\x69\xd6\x55\x3a\xa7\x9c\x27\x82\x56\x5c\x24\xf9\x97\x3d" + "\x57\xdc\xb9\x22\x1f\x3c\x48\x16\x2d\x1a\xad\xc5\x2e\x11\x57\xe1" + "\x59\x7f\x6c\x15\x09\x8c\x38\x15\x77\x15\x6f\x77\xa3\x22\xa2\xcb" + "\x63\x95\xce\x55\xba\xa3\x26\xe0\x8c\xab\x2e\x1c\xce\xc7\xbc\x95" + "\x0f\x16\xc0\x17\xf7\x9f\x5a\x2b\xb3\x23\xd8\xf2\xdc\xbb\x1b\x14" + "\x02\x5a\x2a\x6a\xfc\x30\xf5\x83\x66\xf7\x5e\x46\x6c\x7a\xac\x49" + "\xa1\x8a\x8f\x2f\xea\x3e\xa6\x36\xb3\xb3\xe6\xc7\xe6\xc8\x9e\xc5" + "\xa7\xb5\x77\xf6\x2f\xf1\x9b\x8e\xb2\x13\x9f\x08\x16\x0e\x46\x63" + "\x6b\x9d\x39\x3f\x42\x6a\xcf\x12\x6a\x4c\xbf\x5f\x36\xfe\xac\x4a" + "\x5a\x57\xe9\xff\xf1\x8b\x7b\x1b\xff\x0b\x28\x8d\x8d\xf8\xb3\xe9" + "\xa1\xdf\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82"; + const int dummy_png_text_start = 0x30; + const int dummy_png_text_length = 157; + + unsigned __int64 pwarnstart = stream.GetPosition() - offset; + int size = dummy_png_text_length; + + stream.WriteBuffer( // dummy PNG header + dummy_png, sizeof(dummy_png)); + pwarnstart += dummy_png_text_start; + + TFileInfo info; + info.FileName = + ProtectWarnFileNameLabel1->Caption + + ProtectWarnFileNameLabel1->Caption + + ProtectWarnFileNameLabel1->Caption + + ProtectWarnFileNameLabel2->Caption; + info.LocalFileName = ""; + info.Flags = 0; + info.FileSize = size; + info.StoreSize = size; + + unsigned __int32 adler32sum = adler32(0L, Z_NULL, 0); + adler32sum = adler32(adler32sum, dummy_png + dummy_png_text_start, size); + + info.Adler32 = adler32sum; + + TFileSegment seg; + seg.Offset = pwarnstart; + seg.StoreSize = size; + seg.OrgSize = size; + seg.Flags = 0; + info.Segments.push_back(seg); + + fileinfo.push_back(info); + } + + // write each flie + int currentno = 0; + for(int i=0; iCount; i++) + { + + AnsiString ext = ExtractFileExt(FileList->Strings[i]).LowerCase(); + if(ext == "") ext = NoExtNameLabel->Caption; + if(DiscardExtList->Items->IndexOf(ext) != -1) continue; + + AnsiString storefilename = FileList->Strings[i]; + AnsiString filename = ProjFolder + storefilename; + + ProgressLabel->Caption = FileList->Strings[i] + " ("+ + AnsiString(currentno + 1) + "/" + AnsiString(totalcount) + ")" ; +// Sleep(500); + + Application->ProcessMessages(); + if(Aborted) throw Exception(InterruptedNameLabel->Caption); + + // open input flie + unsigned __int64 filesize; + unsigned __int32 adler32sum; + bool avoidstore = false; + + { + tTVPLocalFileStream infile(filename.c_str(), TVP_ST_READ); + + { + DWORD h; + DWORD l = GetFileSize(infile.GetHandle(), &h); + filesize = ((unsigned __int64)l) + (((unsigned __int64)h)<<32); + } + + + // check checksum + adler32sum = GetFileCheckSum(infile); + for(std::vector::iterator i = fileinfo.begin(); + i != fileinfo.end(); i++) + { + if(i->Adler32 == adler32sum && i->FileSize == filesize && + i->LocalFileName != "") + { + // two files may be identical + if(CompareFile(filename, i->LocalFileName)) + { + // files are identical + avoidstore = true; + TFileInfo info; + info = *i; // copy from reference file info + info.LocalFileName = filename; + info.FileName = storefilename; + fileinfo.push_back(info); + break; + } + } + } + } + + // reopen input file + tTVPLocalFileStream infile(filename.c_str(), TVP_ST_READ, true, adler32sum); + + if(!avoidstore) + { + // compress + BYTE *outbuf; + unsigned __int64 storesize; + + bool isov = OVBookShareCheck->Checked && ext == ".ogg"; // ogg vorbis + + if(CompressExtList->Items->IndexOf(ext) == -1 || + (compsizelimit != (__int64)-1 && filesize >= compsizelimit) || + filesize >= ((unsigned __int64)2*1024*1024*1024-1) || isov) + { + // avoid compress + outbuf = NULL; + storesize = filesize; + } + else + { + BYTE *src = new BYTE[(size_t)filesize]; + try + { + unsigned long compsize = 0; + outbuf = new BYTE[compsize = + (unsigned long)(filesize + filesize /100 + 1024)]; + infile.Read(src, (unsigned int )filesize); + infile.Seek(0, TVP_ST_SEEK_SET); + + int res; + unsigned long srclen = (unsigned long) filesize; + try + { + // compress with zlib deflate + res = compress2(outbuf, &compsize, src, srclen, + Z_BEST_COMPRESSION); + if(res != Z_OK) compsize = -1; + } + catch(...) + { + compsize = -1; + } + + if(compsize == (unsigned long)-1) + { + delete [] outbuf; + outbuf = NULL; + storesize = filesize; + } + else + { + storesize = compsize; + } + } + catch(...) + { + delete [] src; + throw; + } + delete [] src; + } + + + + // write + try + { + TFileInfo info; + info.FileSize = filesize; + info.StoreSize = storesize; + unsigned __int32 flags = ProtectCheck->Checked ? (1<<31)/*protected*/:0; + info.Flags = flags; + info.Adler32 = adler32sum; + info.LocalFileName = filename; + + // align to 8bytes +/* + int padding = 8 - ((int)stream.GetPosition() & 0x07); + if(padding != 8) + { + stream.WriteBuffer("padding-", padding); + } +*/ + + // write + if(outbuf) + { + // write the compressed image + TFileSegment seg; + seg.Offset = stream.GetPosition() - offset; + seg.StoreSize = storesize; + seg.OrgSize = filesize; + seg.Flags = 1; // compressed segment + info.Segments.push_back(seg); + stream.WriteBuffer(outbuf, storesize); + delete [] outbuf; + outbuf = NULL; + } + else + { + // copy whole file + + // share ogg vorbis codebooks + bool segment_detected = false; + std::vector seg_refstart; + std::vector seg_bufstart; + std::vector seg_length; + unsigned __int64 ref_offset; + if(isov) + { + // is ogg vorbis + ovcb->HeadersLen[ovcb_index] = + infile.Read(ovcb->Headers[ovcb_index], + OV_MATCH_BUF_LEN); + ovcb->Offset[ovcb_index] = stream.GetPosition(); + infile.SetPosition(0); + + // detect match + for(int i = 0; iHeadersLen[i]) != 0) + { + unsigned char *ref = ovcb->Headers[i]; + int buflen = ovcb->HeadersLen[ovcb_index]; + unsigned char *buf = ovcb->Headers[ovcb_index]; + + seg_refstart.clear(); + seg_bufstart.clear(); + seg_length.clear(); + + bool b = DetectMatch(ref, reflen, buf, buflen, + seg_refstart, seg_bufstart, seg_length); + if(b) + { + segment_detected = true; + ref_offset = ovcb->Offset[i]; + break; + } + } + } + + if(segment_detected) + { + ovcb->HeadersLen[ovcb_index] = 0; + } + else + { + // to next ... + ovcb_index ++; + if(ovcb_index == OV_MATCH_HOLD) ovcb_index = 0; + } + } + + if(segment_detected) + { + std::vector::iterator rs, bs, l; + TFileSegment seg; + int pos = 0; + rs = seg_refstart.begin(); + bs = seg_bufstart.begin(); + l = seg_length.begin(); + while(rs != seg_refstart.end()) + { + int blen = *bs - pos; + if(blen != 0) + { + seg.Flags = 0; + seg.Offset = stream.GetPosition() - offset; + Copy(stream, infile, blen); + seg.OrgSize = seg.StoreSize = blen; + info.Segments.push_back(seg); + } + + seg.Flags = 0; + seg.Offset = *rs + ref_offset - offset; + seg.OrgSize = seg.StoreSize = *l; + info.Segments.push_back(seg); + infile.SetPosition(infile.GetPosition() + *l); + + pos = *bs + *l; + + rs++; + bs++; + l++; + } + + seg.Offset = stream.GetPosition() - offset; + unsigned __int64 in_pos = infile.GetPosition(); + seg.OrgSize = seg.StoreSize = storesize - in_pos; + if(seg.OrgSize) + { + info.Segments.push_back(seg); + Copy(stream, infile, seg.OrgSize); + } + } + else + { + TFileSegment seg; + seg.Flags = 0; + seg.Offset = stream.GetPosition() - offset; + seg.OrgSize = seg.StoreSize = storesize; + + info.Segments.push_back(seg); + Copy(stream, infile, storesize); + } + } + info.FileName = storefilename; + fileinfo.push_back(info); + } + catch(...) + { + if(outbuf) delete [] outbuf; + throw; + } + } + + currentno ++; + } + + + // compute index size + int index_size = 0; + + std::vector::iterator it; + for(it = fileinfo.begin(); it != fileinfo.end(); it++) + { + WideString str = (it->FileName); + + // for each file + index_size += 4 + 8 + 4 + 8 + 4 + 8 + 8 + 2 + str.Length()*2 + 4 + 8 + + 4 + 8 + 4 + + it->Segments.size()*28; + } + + // write index pos + { + unsigned __int64 pos_save = stream.GetPosition(); + stream.SetPosition(index_pointer_pos); + stream.WriteInt64(pos_save - offset); + stream.SetPosition(pos_save); + } + + // write index + ProgressLabel->Caption = "Writing index ..."; + Application->ProcessMessages(); + if(Aborted) throw Exception(InterruptedNameLabel->Caption); + + unsigned char *index_buf_alloc_p = new unsigned char [index_size]; + unsigned char *index_buf = index_buf_alloc_p; + unsigned char *index_compressed = NULL; + + try + { + + it = fileinfo.begin(); + for(it = fileinfo.begin(); it != fileinfo.end(); it++) + { + WideString str = (it->FileName); + + // for each file + memcpy(index_buf, "File", 4); + index_buf += 4; + *(__int64*)(index_buf) = 4 + 8 + 4 + 8 + 8 + 2 + str.Length()*2 + 4 + 8 + + 4 + 8 + 4 + it->Segments.size()*28; + index_buf += 8; + + // write "info" + memcpy(index_buf, "info", 4); + index_buf += 4; + *(__int64*)(index_buf) = 4 + 8 + 8 + 2 + str.Length()*2; + index_buf += 8; + *(__int32*)(index_buf) = it->Flags; + index_buf += 4; + *(__int64*)(index_buf) = it->FileSize; + index_buf += 8; + *(__int64*)(index_buf) = it->StoreSize; + index_buf += 8; + *(__int16*)(index_buf) = str.Length(); + index_buf += 2; + + wchar_t *tstr = new wchar_t[str.Length() +1]; + try + { + // change path delimiter to '/' + wcscpy(tstr, str.c_bstr()); + wchar_t *p = tstr; + while(*p) + { + if(*p == '\\') *p = '/'; + p++; + } + memcpy(index_buf, tstr, str.Length() * 2); + index_buf += str.Length() * 2; + } + catch(...) + { + delete [] tstr; + throw; + } + delete [] tstr; + + // write "segm" + memcpy(index_buf, "segm", 4); + index_buf += 4; + *(__int64*)(index_buf) = it->Segments.size() * 28; + index_buf += 8; + std::vector::iterator sit; + for(sit = it->Segments.begin(); sit != it->Segments.end(); sit++) + { + *(__int32*)(index_buf) = sit->Flags; + index_buf += 4; + *(__int64*)(index_buf) = sit->Offset; + index_buf += 8; + *(__int64*)(index_buf) = sit->OrgSize; + index_buf += 8; + *(__int64*)(index_buf) = sit->StoreSize; + index_buf += 8; + } + + // write "adlr" (adler32 check sum) + memcpy(index_buf, "adlr", 4); + index_buf += 4; + *(__int64*)(index_buf) = 4; + index_buf += 8; + *(unsigned __int32*)(index_buf) = it->Adler32; + index_buf += 4; + + } + + unsigned long comp_size; + if(CompressIndexCheck->Checked) + { + index_compressed = new unsigned char [comp_size = + index_size + index_size/100 + 1024]; + + int res; + unsigned long srclen = (unsigned long) index_size; + try + { + // compress with zlib deflate + res = compress2(index_compressed, &comp_size, index_buf_alloc_p, srclen, + Z_BEST_COMPRESSION); + if(res != Z_OK) comp_size = -1; + } + catch(...) + { + comp_size = -1; + } + + if(comp_size == (unsigned long)-1) + { + delete [] index_compressed; + index_compressed = NULL; + } + } + + if(index_compressed) + { + int flag = 1; + stream.WriteBuffer(&flag, 1); + stream.WriteInt64(comp_size); + stream.WriteInt64(index_size); + stream.WriteBuffer(index_compressed, comp_size); + } + else + { + int flag = 0; + stream.WriteBuffer(&flag, 1); + stream.WriteInt64(index_size); + stream.WriteBuffer(index_buf_alloc_p, index_size); + } + + } + catch(...) + { + delete [] index_buf_alloc_p; + if(index_compressed) delete [] index_compressed; + throw; + } + + delete [] index_buf_alloc_p; + if(index_compressed) delete [] index_compressed; + + // save current profile to the project folder + if(WriteDefaultRPF) + { + try + { + SaveProfile(ProjFolder + "default.rpf"); + } + catch(...) + { + // ignode errors + } + } +} +//--------------------------------------------------------------------------- + + + diff --git a/tools/win32/krdevui/RelSettingsUnit.dfm b/tools/win32/krdevui/RelSettingsUnit.dfm new file mode 100644 index 0000000..cd641a2 --- /dev/null +++ b/tools/win32/krdevui/RelSettingsUnit.dfm @@ -0,0 +1,740 @@ +object RelSettingsForm: TRelSettingsForm + Left = 76 + Top = 368 + Width = 630 + Height = 440 + HorzScrollBar.Tracking = True + HorzScrollBar.Visible = False + VertScrollBar.Tracking = True + VertScrollBar.Visible = False + Caption = '吉里吉里 Releaser - 設定' + Color = clBtnFace + Constraints.MinHeight = 440 + Constraints.MinWidth = 630 + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + Icon.Data = { + 0000010004002020100000000000E80200004600000010101000000000002801 + 00002E0300002020000000000000A80800005604000010100000000000006805 + 0000FE0C00002800000020000000400000000100040000000000000200000000 + 0000000000000000000000000000000000000000800000800000008080008000 + 00008000800080800000C0C0C000808080000000FF0000FF000000FFFF00FF00 + 0000FF00FF00FFFF0000FFFFFF00000000000000000000000000000000000000 + 0088888888888888888888880000000000000000000000000000000800000000 + 8FFFFFF77777777777777708000000008FFFFFFFF77777777777770800000000 + 8FFFFFFFFFF777777777770800000000877FFFFFFFFF77777777770800000000 + 87887FFFFFFFF77777177708000000000887FFFFFFFFFF777117770800000000 + 877FFFFFFFFFFFF7191777080000000087887FFFFFFFFFF19911111111100000 + 0887FFFFFFFFFF199999999999100000877FFFFFFFFFF9999999999999100000 + 87887FFFFFFFFF9999999999991000000887FFFFFFFFFFF99999999999100000 + 877FFFFFFFFFFFFF999FFF080000000087887FFFFFFFFFFFF99FF70800000000 + 0887FFFFFFFFFFFFFF9FFF0800000000877FFFFFFFFFFFFFFFFFFF0800000000 + 87887FFFFFFFFFFFFFFFFF08000000000887FFFFFFFFFFFFFFFFFF0800000000 + 877FFFFFFFFFFFFFFFFFFF080000000087887FFFFFFFFFFFFFFFFF0800000000 + 0887FFFFFFFFFFFFFFF7770000000000877FFFFFFFFFFFFFF777770000000000 + 87887FFFFFFFFFFF80000000000000000887FFFFFFFFFFFF8FF7800000000000 + 877FFFFFFFFFFFFF8F7800000000000087887FFFFFFFFFFF8780000000000000 + 0887FFFFFFFFFFFF8800000000000000877FFFFFFFFFFFFF8000000000000000 + 8888888888888888800000000000F8000007F8000007F0000007F0000007F000 + 0007F0000007E0000007D0000007E0000007E0000007D0000001E0000001E000 + 0001D0000001E0000001E0000007D0000007E0000007E0000007D0000007E000 + 0007E0000007D0000007E0000007E000000FD000001FE000003FE000007FD000 + 00FFE00001FFF00003FFF00007FF280000001000000020000000010004000000 + 0000800000000000000000000000000000000000000000000000000080000080 + 000000808000800000008000800080800000C0C0C000808080000000FF0000FF + 000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0000080000000000000088 + 8888888888000087777777777800008808FFFFF17800000077FFFF1178000088 + 08FFF1911111000077FF19999991008808FFF9999991000077FFFF9978000088 + 08FFFFF97800000077FFFFFF7800008808FFFFFF7880000077FFFF8000000088 + 08FFFF8F800000007FFFFF8800000088888888800000E0014000C0014000C001 + 400080014000C001400080004000C000400080004000C001400080014000C001 + 400080014000C003400080074000C00F4000C01F400028000000200000004000 + 0000010008000000000000040000000000000000000000000000000000000000 + 0000000080000080000000808000800000008000800080800000C0C0C000C0DC + C000F0CAA60004040400080808000C0C0C0011111100161616001C1C1C002222 + 220029292900555555004D4D4D004242420039393900807CFF005050FF009300 + D600FFECCC00C6D6EF00D6E7E70090A9AD000000330000006600000099000000 + CC00003300000033330000336600003399000033CC000033FF00006600000066 + 330000666600006699000066CC000066FF000099000000993300009966000099 + 99000099CC000099FF0000CC000000CC330000CC660000CC990000CCCC0000CC + FF0000FF660000FF990000FFCC00330000003300330033006600330099003300 + CC003300FF00333300003333330033336600333399003333CC003333FF003366 + 00003366330033666600336699003366CC003366FF0033990000339933003399 + 6600339999003399CC003399FF0033CC000033CC330033CC660033CC990033CC + CC0033CCFF0033FF330033FF660033FF990033FFCC0033FFFF00660000006600 + 330066006600660099006600CC006600FF006633000066333300663366006633 + 99006633CC006633FF00666600006666330066666600666699006666CC006699 + 00006699330066996600669999006699CC006699FF0066CC000066CC330066CC + 990066CCCC0066CCFF0066FF000066FF330066FF990066FFCC00CC00FF00FF00 + CC009999000099339900990099009900CC009900000099333300990066009933 + CC009900FF00996600009966330099336600996699009966CC009933FF009999 + 330099996600999999009999CC009999FF0099CC000099CC330066CC660099CC + 990099CCCC0099CCFF0099FF000099FF330099CC660099FF990099FFCC0099FF + FF00CC00000099003300CC006600CC009900CC00CC0099330000CC333300CC33 + 6600CC339900CC33CC00CC33FF00CC660000CC66330099666600CC669900CC66 + CC009966FF00CC990000CC993300CC996600CC999900CC99CC00CC99FF00CCCC + 0000CCCC3300CCCC6600CCCC9900CCCCCC00CCCCFF00CCFF0000CCFF330099FF + 6600CCFF9900CCFFCC00CCFFFF00CC003300FF006600FF009900CC330000FF33 + 3300FF336600FF339900FF33CC00FF33FF00FF660000FF663300CC666600FF66 + 9900FF66CC00CC66FF00FF990000FF993300FF996600FF999900FF99CC00FF99 + FF00FFCC0000FFCC3300FFCC6600FFCC9900FFCCCC00FFCCFF00FFFF3300CCFF + 6600FFFF9900FFFFCC006666FF0066FF660066FFFF00FF666600FF66FF00FFFF + 66002100A5005F5F5F00777777008686860096969600CBCBCB00B2B2B200D7D7 + D700DDDDDD00E3E3E300EAEAEA00F1F1F100F8F8F800F0FBFF00A4A0A0008080 + 80000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF000A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0A0A0AEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEAEA0A0A0A0A0A0A + 0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0A0AEA0A0A0A0A0A0A + 0A0AECF1F1F1F1F1F1BCBCBCBC07070707070707EFEFEFEF0AEA0A0A0A0A0A0A + 0A0AEC191919F1F1F1F1F1BCBCBCBC070707070707EFEFEF0AEA0A0A0A0A0A0A + 0A0AEC191919191919F1F1F1F1BCBCBC070707070707EFEF0AEA0A0A0A0A0A0A + 0A0AECBCBC191919191919F1F1F1BCBCBC070707070707EF0AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919F1F1F1BCBCBC0707010707070AEA0A0A0A0A0A0A + 0A0A0A14EAEF19191919191919F1F1F1BCBCBC01010707070AEA0A0A0A0A0A0A + 0A0AECEFEF191919191919191919F1F1F1BC01F9010707070AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919191919F1F101F9F90101010101010101010A0A0A + 0A0A0A14EAEF1919191919191919191901F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0AECBCBC19191919191919191919F9F9F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0AEAF7EC14BC191919191919191919F9F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0A0A14EAEF1919191919191919191919F9F9F9F9F9F9F9F9F9F9F9010A0A0A + 0A0AECBCBC19191919191919191919191919F9F9F9F1F1F10AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC191919191919191919191919F9F9F1F1BC0AEA0A0A0A0A0A0A + 0A0A0A14EAEF1919191919191919191919191919F919F1F10AEA0A0A0A0A0A0A + 0A0AECBCBC1919191919191919191919191919191919F1F10AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC19191919191919191919191919191919F10AEA0A0A0A0A0A0A + 0A0A0A14EAEF1919191919191919191919191919191919F10AEA0A0A0A0A0A0A + 0A0AECBCBC191919191919191919191919191919191919190AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC19191919191919191919191919191919190AEA0A0A0A0A0A0A + 0A0A0A14EAEF191919191919191919191919191919BCBCBC0AEA0A0A0A0A0A0A + 0A0AECBCBC1919191919191919191919191919BCBCEFEFEF0AEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919191919191919EC0A0A0A0A0AEFEA0A0A0A0A0A0A + 0A0A0A14EAEF191919191919191919191919EC1919EFEC0AEFEA0A0A0A0A0A0A + 0A0AECBCBC19191919191919191919191919EC19EFEC0AEFEFEA0A0A0A0A0A0A + 0A0AEAF7EC14BC1919191919191919191919ECEFEC0AEAEAEAEA0A0A0A0A0A0A + 0A0A0A14EAEF191919191919191919191919ECEC0A0A0A0A0A0A0A0A0A0A0A0A + 0A0AECEFEF19191919191919191919191919EC0A0A0A0A0A0A0A0A0A0A0A0A0A + 0A0AECECECECECECECECECECECECECECECECEC0A0A0A0A0A0A0A0A0A0A0AF800 + 0007F8000007F0000007F0000007F0000007F0000007E0000007D0000007E000 + 0007E0000007D0000001E0000001E0000001D0000001E0000001E0000007D000 + 0007E0000007E0000007D0000007E0000007E0000007D0000007E0000007E000 + 0007D0000007E0000007E0000007D0000007E0000007F00003FFF00007FF2800 + 0000100000002000000001000800000000000001000000000000000000000000 + 0000000000000000000000008000008000000080800080000000800080008080 + 0000C0C0C000C0DCC000F0CAA60004040400080808000C0C0C00111111001616 + 16001C1C1C002222220029292900555555004D4D4D004242420039393900807C + FF005050FF009300D600FFECCC00C6D6EF00D6E7E70090A9AD00000033000000 + 6600000099000000CC00003300000033330000336600003399000033CC000033 + FF00006600000066330000666600006699000066CC000066FF00009900000099 + 330000996600009999000099CC000099FF0000CC000000CC330000CC660000CC + 990000CCCC0000CCFF0000FF660000FF990000FFCC0033000000330033003300 + 6600330099003300CC003300FF00333300003333330033336600333399003333 + CC003333FF00336600003366330033666600336699003366CC003366FF003399 + 00003399330033996600339999003399CC003399FF0033CC000033CC330033CC + 660033CC990033CCCC0033CCFF0033FF330033FF660033FF990033FFCC0033FF + FF00660000006600330066006600660099006600CC006600FF00663300006633 + 330066336600663399006633CC006633FF006666000066663300666666006666 + 99006666CC00669900006699330066996600669999006699CC006699FF0066CC + 000066CC330066CC990066CCCC0066CCFF0066FF000066FF330066FF990066FF + CC00CC00FF00FF00CC009999000099339900990099009900CC00990000009933 + 3300990066009933CC009900FF00996600009966330099336600996699009966 + CC009933FF009999330099996600999999009999CC009999FF0099CC000099CC + 330066CC660099CC990099CCCC0099CCFF0099FF000099FF330099CC660099FF + 990099FFCC0099FFFF00CC00000099003300CC006600CC009900CC00CC009933 + 0000CC333300CC336600CC339900CC33CC00CC33FF00CC660000CC6633009966 + 6600CC669900CC66CC009966FF00CC990000CC993300CC996600CC999900CC99 + CC00CC99FF00CCCC0000CCCC3300CCCC6600CCCC9900CCCCCC00CCCCFF00CCFF + 0000CCFF330099FF6600CCFF9900CCFFCC00CCFFFF00CC003300FF006600FF00 + 9900CC330000FF333300FF336600FF339900FF33CC00FF33FF00FF660000FF66 + 3300CC666600FF669900FF66CC00CC66FF00FF990000FF993300FF996600FF99 + 9900FF99CC00FF99FF00FFCC0000FFCC3300FFCC6600FFCC9900FFCCCC00FFCC + FF00FFFF3300CCFF6600FFFF9900FFFFCC006666FF0066FF660066FFFF00FF66 + 6600FF66FF00FFFF66002100A5005F5F5F00777777008686860096969600CBCB + CB00B2B2B200D7D7D700DDDDDD00E3E3E300EAEAEA00F1F1F100F8F8F800F0FB + FF00A4A0A000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF + 0000FFFFFF000A0A0AEC0A0C0A0C0A0C0A0C0A0C0A0A0A0AEC12121212121212 + 121212120C0A0A0AEB09070909090909090909120A0A0A43EC920C9219090909 + 090109120C0A0A0A4343070919190909010109120A0A0A43EC920C9219191901 + F901010101010A0A43430709191901F9F9F9F9F9F9010A43EC920C92191919F9 + F9F9F9F9F9010A0A4343070919191919F9F909120C0A0A43EC920C9219191919 + 19F909120C0A0A0A4343070919191919191909120A0A0A43EC920C9219191919 + 19191912120A0A0A434307091919191912434343EC0A0A43EC920C9219191919 + 921912EC0A0A0A0A43430719191919199212EC0A0A0A0A0AECECECECECECECEC + EC0A0A0A0A0AE0010000C0010000C001000080010000C001000080000000C000 + 000080000000C001000080010000C001000080010000C001000080030000C007 + 0000C01F0000} + OldCreateOrder = False + Position = poDefaultPosOnly + OnCloseQuery = FormCloseQuery + OnDestroy = FormDestroy + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 12 + object NoExtNameLabel: TLabel + Left = 206 + Top = 384 + Width = 64 + Height = 12 + Anchors = [akRight, akBottom] + Caption = '(拡張子なし)' + Visible = False + end + object InterruptNameLabel: TLabel + Left = 206 + Top = 392 + Width = 24 + Height = 12 + Anchors = [akRight, akBottom] + Caption = '中断' + Visible = False + end + object ExitNameLabel: TLabel + Left = 238 + Top = 392 + Width = 24 + Height = 12 + Anchors = [akRight, akBottom] + Caption = '終了' + Visible = False + end + object ArchiveCreatedNameLabel: TLabel + Left = 278 + Top = 384 + Width = 128 + Height = 12 + Anchors = [akRight, akBottom] + Caption = 'アーカイブを作成しました' + Visible = False + end + object InterruptedNameLabel: TLabel + Left = 270 + Top = 392 + Width = 64 + Height = 12 + Anchors = [akRight, akBottom] + Caption = '中断しました' + Visible = False + end + object ProgressLabel: TLabel + Left = 8 + Top = 392 + Width = 423 + Height = 12 + Alignment = taRightJustify + Anchors = [akLeft, akRight, akBottom] + AutoSize = False + end + object ExecutableCreatedNameLabel: TLabel + Left = 288 + Top = 304 + Width = 212 + Height = 12 + Caption = 'EXE 形式実行可能ファイルを作成しました' + Visible = False + end + object OKButton: TButton + Left = 443 + Top = 375 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Caption = '作成' + Default = True + TabOrder = 0 + OnClick = OKButtonClick + end + object CancelButton: TButton + Left = 531 + Top = 375 + Width = 75 + Height = 25 + Anchors = [akRight, akBottom] + Cancel = True + Caption = 'キャンセル' + TabOrder = 1 + OnClick = CancelButtonClick + end + object SelectFolderButton: TButton + Left = 8 + Top = 375 + Width = 137 + Height = 25 + Anchors = [akLeft, akBottom] + Caption = 'フォルダ選択に戻る(&B)' + ModalResult = 4 + TabOrder = 2 + end + object PageControl: TPageControl + Left = 8 + Top = 8 + Width = 604 + Height = 361 + ActivePage = OutputSheel + Anchors = [akLeft, akTop, akRight, akBottom] + TabOrder = 3 + object OutputSheel: TTabSheet + Caption = '出力' + object SpecifyOutputNameLabel: TLabel + Left = 8 + Top = 136 + Width = 169 + Height = 12 + Caption = '出力ファイル名を指定してください' + Visible = False + end + object ConfirmOverwriteLabel: TLabel + Left = 192 + Top = 136 + Width = 197 + Height = 12 + Caption = ' は既に存在します。 上書きしますか?' + Visible = False + end + object ProtectWarnLabel: TLabel + Left = 0 + Top = 152 + Width = 815 + Height = 12 + Caption = + 'Warning: Extracting this archive may infringe on author'#39's right.' + + ' 警告 : このアーカイブを展開することにより、あなたは著作者の権利' + + 'を侵害するおそれがあります。' + Visible = False + end + object ProtectWarnFileNameLabel1: TLabel + Left = 0 + Top = 168 + Width = 656 + Height = 12 + Caption = + '$$$ This is a protected archive. $$$ 著作者はこのアーカイブが正' + + '規の利用方法以外の方法で展開されることを望んでいません。 ' + Visible = False + end + object ProtectWarnFileNameLabel2: TLabel + Left = 0 + Top = 184 + Width = 854 + Height = 12 + Caption = + '$$$ Warning! Extracting this archive may infringe on author'#39's ri' + + 'ghts. 警告 このアーカイブを展開することにより、あなたは著作者の' + + '権利を侵害するおそれがあります。.txt' + Visible = False + end + object Label6: TLabel + Left = 8 + Top = 273 + Width = 87 + Height = 12 + Anchors = [akLeft, akBottom] + Caption = '入力ディレクトリ :' + end + object OutputFileGroup: TGroupBox + Left = 8 + Top = 72 + Width = 580 + Height = 57 + Anchors = [akLeft, akTop, akRight] + Caption = '出力ファイル(&F)' + TabOrder = 0 + object OutputFileNameEdit: TEdit + Left = 8 + Top = 24 + Width = 500 + Height = 20 + Anchors = [akLeft, akTop, akRight] + TabOrder = 0 + end + object SetFileNameButton: TButton + Left = 515 + Top = 24 + Width = 57 + Height = 20 + Anchors = [akTop, akRight] + Caption = '参照 ...' + TabOrder = 1 + OnClick = SetFileNameButtonClick + end + end + object OutputFormatGroup: TGroupBox + Left = 8 + Top = 8 + Width = 580 + Height = 57 + Anchors = [akLeft, akTop, akRight] + Caption = '出力形式(&T)' + TabOrder = 1 + object MissingKrKrEXELabel: TLabel + Left = 64 + Top = 40 + Width = 383 + Height = 12 + Caption = + 'krkr.eXe が見つからないため、EXE 形式実行可能ファイルを出力でき' + + 'ません' + Visible = False + end + object XP3ArchiveRadio: TRadioButton + Left = 8 + Top = 24 + Width = 169 + Height = 17 + Caption = '.XP3 形式 アーカイブ(&A)' + Checked = True + TabOrder = 0 + TabStop = True + OnClick = XP3ArchiveRadioClick + end + object ExecutableRadio: TRadioButton + Left = 224 + Top = 24 + Width = 193 + Height = 17 + Caption = '.EXE 形式 実行可能ファイル(&E)' + TabOrder = 1 + OnClick = ExecutableRadioClick + end + end + object InputDirectoryMemo: TMemo + Left = 8 + Top = 289 + Width = 580 + Height = 33 + Anchors = [akLeft, akRight, akBottom] + BorderStyle = bsNone + Color = clBtnFace + ReadOnly = True + TabOrder = 2 + WantReturns = False + end + end + object FileTypeSheet: TTabSheet + Caption = 'ファイル' + ImageIndex = 1 + object Label1: TLabel + Left = 8 + Top = 24 + Width = 80 + Height = 12 + Caption = '圧縮する物(&C) :' + FocusControl = CompressExtList + end + object Label2: TLabel + Left = 152 + Top = 24 + Width = 98 + Height = 12 + Caption = '圧縮をしない物(&T) :' + FocusControl = StoreExtList + end + object Label3: TLabel + Left = 152 + Top = 8 + Width = 123 + Height = 12 + Caption = 'アーカイブには含めるが' + end + object Label4: TLabel + Left = 296 + Top = 8 + Width = 77 + Height = 12 + Caption = 'アーカイブには' + end + object Label5: TLabel + Left = 296 + Top = 24 + Width = 79 + Height = 12 + Caption = '含めない物(&E) :' + FocusControl = DiscardExtList + end + object Label7: TLabel + Left = 470 + Top = 272 + Width = 111 + Height = 12 + Anchors = [akRight, akBottom] + Caption = '※ドラッグ&ドロップで' + end + object Label8: TLabel + Left = 478 + Top = 288 + Width = 104 + Height = 12 + Anchors = [akRight, akBottom] + Caption = '各項目間を移動する' + end + object Label9: TLabel + Left = 478 + Top = 304 + Width = 73 + Height = 12 + Anchors = [akRight, akBottom] + Caption = 'こともできます' + end + object CompressExtList: TListBox + Left = 8 + Top = 40 + Width = 105 + Height = 281 + Anchors = [akLeft, akTop, akBottom] + DragMode = dmAutomatic + ItemHeight = 12 + MultiSelect = True + TabOrder = 0 + OnDragDrop = CompressExtListDragDrop + OnDragOver = CompressExtListDragOver + OnStartDrag = CompressExtListStartDrag + end + object StoreExtList: TListBox + Left = 152 + Top = 40 + Width = 105 + Height = 281 + Anchors = [akLeft, akTop, akBottom] + DragMode = dmAutomatic + ItemHeight = 12 + MultiSelect = True + TabOrder = 1 + OnDragDrop = CompressExtListDragDrop + OnDragOver = CompressExtListDragOver + OnStartDrag = CompressExtListStartDrag + end + object DiscardExtList: TListBox + Left = 296 + Top = 40 + Width = 105 + Height = 281 + Anchors = [akLeft, akTop, akBottom] + DragMode = dmAutomatic + ItemHeight = 12 + MultiSelect = True + TabOrder = 2 + OnDragDrop = CompressExtListDragDrop + OnDragOver = CompressExtListDragOver + OnStartDrag = CompressExtListStartDrag + end + object Button1: TButton + Left = 120 + Top = 72 + Width = 25 + Height = 25 + Caption = '←' + TabOrder = 3 + OnClick = Button1Click + end + object Button2: TButton + Left = 120 + Top = 104 + Width = 25 + Height = 25 + Caption = '→' + TabOrder = 4 + OnClick = Button2Click + end + object Button3: TButton + Left = 264 + Top = 72 + Width = 25 + Height = 25 + Caption = '←' + TabOrder = 5 + OnClick = Button3Click + end + object Button4: TButton + Left = 264 + Top = 104 + Width = 25 + Height = 25 + Caption = '→' + TabOrder = 6 + OnClick = Button4Click + end + end + object OptionSheet: TTabSheet + Caption = 'オプション' + ImageIndex = 2 + object CompressLimitSizeLabel: TLabel + Left = 312 + Top = 18 + Width = 43 + Height = 12 + Caption = 'KB 以上' + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + ParentColor = False + ParentFont = False + end + object CompressLimitCheck: TCheckBox + Left = 8 + Top = 16 + Width = 217 + Height = 17 + Caption = '大きなファイルは圧縮を行わない(&L) :' + Checked = True + State = cbChecked + TabOrder = 0 + OnClick = CompressLimitCheckClick + end + object ProtectCheck: TCheckBox + Left = 8 + Top = 56 + Width = 121 + Height = 17 + Caption = '展開プロテクト(&P)' + TabOrder = 1 + end + object CompressLimitSizeEdit: TEdit + Left = 224 + Top = 14 + Width = 81 + Height = 20 + TabOrder = 2 + Text = '1024' + OnExit = CompressLimitSizeEditExit + OnKeyPress = CompressLimitSizeEditKeyPress + end + object OVBookShareCheck: TCheckBox + Left = 8 + Top = 96 + Width = 209 + Height = 17 + Caption = 'OggVorbis コードブック共有化(&C)' + Checked = True + State = cbChecked + TabOrder = 3 + end + object CompressIndexCheck: TCheckBox + Left = 8 + Top = 136 + Width = 169 + Height = 17 + Caption = 'インデックスを圧縮する(&I)' + Checked = True + State = cbChecked + TabOrder = 4 + end + object UseXP3EncDLLCheck: TCheckBox + Left = 8 + Top = 176 + Width = 265 + Height = 17 + Caption = 'xp3enc.dll を使う(&E)' + TabOrder = 5 + end + end + object ExeOptionsSheet: TTabSheet + Caption = '実行可能ファイル設定' + ImageIndex = 3 + inline ConfMainFrame: TConfMainFrame + Left = 8 + Top = 8 + Width = 583 + Height = 321 + Anchors = [akLeft, akTop, akRight, akBottom] + inherited IconGroupBox: TGroupBox + Top = 258 + Width = 583 + end + inherited OptionsGroupBox: TGroupBox + Width = 583 + Height = 199 + inherited OptionsTreeView: TTreeView + Height = 157 + TabOrder = 3 + end + inherited OptionValueComboBox: TComboBox + TabOrder = 0 + end + inherited OptionDescMemo: TMemo + Height = 85 + TabOrder = 4 + end + inherited RestoreDefaultButton: TButton + TabOrder = 2 + end + inherited InvisibleCheckBox: TCheckBox + TabOrder = 1 + end + end + inherited ReleaseOptionGroupBox: TGroupBox + Top = 208 + Width = 583 + end + inherited Panel1: TPanel + Top = 249 + Width = 583 + end + inherited Panel2: TPanel + Top = 199 + Width = 583 + end + end + end + end + object SaveProfileButton: TButton + Left = 454 + Top = 7 + Width = 76 + Height = 18 + Anchors = [akTop, akRight] + Caption = '保存(&S)' + TabOrder = 4 + OnClick = SaveProfileButtonClick + end + object LoadProfileButton: TButton + Left = 534 + Top = 7 + Width = 76 + Height = 18 + Anchors = [akTop, akRight] + Caption = '読み込み(&L)' + TabOrder = 5 + OnClick = LoadProfileButtonClick + end + object StaticText1: TStaticText + Left = 374 + Top = 9 + Width = 72 + Height = 16 + Alignment = taRightJustify + Anchors = [akTop, akRight] + Caption = 'プロファイル :' + TabOrder = 6 + end + object SaveDialog: TSaveDialog + Filter = + 'XP3 アーカイブ ( *.xp3 )|*.xp3|.EXE 実行可能ファイル ( *.exe )|*' + + '.exe|すべてのファイル|*.*' + Options = [ofHideReadOnly, ofPathMustExist, ofEnableSizing] + Title = '出力ファイルの指定' + Left = 492 + Top = 239 + end + object SaveProfileDialog: TSaveDialog + DefaultExt = 'rpf' + Filter = + 'Releaser プロファイル ( *.rpf )|*.rpf|すべてのファイル ( *.* )|*' + + '.*' + Options = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofEnableSizing] + Left = 440 + Top = 24 + end + object OpenProfileDialog: TOpenDialog + DefaultExt = 'rpf' + Filter = + 'Releaser プロファイル ( *.rpf )|*.rpf|すべてのファイル ( *.* )|*' + + '.*' + Options = [ofHideReadOnly, ofPathMustExist, ofFileMustExist, ofEnableSizing] + Left = 512 + Top = 24 + end +end diff --git a/tools/win32/krdevui/RelSettingsUnit.h b/tools/win32/krdevui/RelSettingsUnit.h new file mode 100644 index 0000000..8b4291e --- /dev/null +++ b/tools/win32/krdevui/RelSettingsUnit.h @@ -0,0 +1,153 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef RelSettingsUnitH +#define RelSettingsUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include "ConfMainFrameUnit.h" +//--------------------------------------------------------------------------- +class TRelSettingsForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TButton *OKButton; + TButton *CancelButton; + TButton *SelectFolderButton; + TPageControl *PageControl; + TTabSheet *OutputSheel; + TGroupBox *OutputFileGroup; + TEdit *OutputFileNameEdit; + TButton *SetFileNameButton; + TGroupBox *OutputFormatGroup; + TRadioButton *XP3ArchiveRadio; + TRadioButton *ExecutableRadio; + TTabSheet *FileTypeSheet; + TListBox *CompressExtList; + TListBox *StoreExtList; + TListBox *DiscardExtList; + TTabSheet *OptionSheet; + TLabel *Label1; + TLabel *Label2; + TLabel *Label3; + TLabel *Label4; + TLabel *Label5; + TButton *Button1; + TButton *Button2; + TButton *Button3; + TButton *Button4; + TCheckBox *CompressLimitCheck; + TLabel *CompressLimitSizeLabel; + TCheckBox *ProtectCheck; + TButton *SaveProfileButton; + TButton *LoadProfileButton; + TStaticText *StaticText1; + TLabel *Label7; + TLabel *Label8; + TLabel *Label9; + TLabel *NoExtNameLabel; + TSaveDialog *SaveDialog; + TTabSheet *ExeOptionsSheet; + TEdit *CompressLimitSizeEdit; + TSaveDialog *SaveProfileDialog; + TOpenDialog *OpenProfileDialog; + TLabel *InterruptNameLabel; + TLabel *ExitNameLabel; + TLabel *ArchiveCreatedNameLabel; + TLabel *InterruptedNameLabel; + TLabel *ProgressLabel; + TLabel *SpecifyOutputNameLabel; + TConfMainFrame *ConfMainFrame; + TLabel *ConfirmOverwriteLabel; + TCheckBox *OVBookShareCheck; + TCheckBox *CompressIndexCheck; + TLabel *MissingKrKrEXELabel; + TLabel *ExecutableCreatedNameLabel; + TLabel *ProtectWarnLabel; + TLabel *ProtectWarnFileNameLabel1; + TLabel *ProtectWarnFileNameLabel2; + TCheckBox *UseXP3EncDLLCheck; + TMemo *InputDirectoryMemo; + TLabel *Label6; + void __fastcall FormDestroy(TObject *Sender); + void __fastcall CompressExtListStartDrag(TObject *Sender, + TDragObject *&DragObject); + void __fastcall CompressExtListDragOver(TObject *Sender, TObject *Source, + int X, int Y, TDragState State, bool &Accept); + void __fastcall CompressExtListDragDrop(TObject *Sender, TObject *Source, + int X, int Y); + void __fastcall Button1Click(TObject *Sender); + void __fastcall Button2Click(TObject *Sender); + void __fastcall Button3Click(TObject *Sender); + void __fastcall Button4Click(TObject *Sender); + void __fastcall SetFileNameButtonClick(TObject *Sender); + void __fastcall XP3ArchiveRadioClick(TObject *Sender); + void __fastcall ExecutableRadioClick(TObject *Sender); + void __fastcall CompressLimitCheckClick(TObject *Sender); + void __fastcall CompressLimitSizeEditKeyPress(TObject *Sender, char &Key); + void __fastcall CompressLimitSizeEditExit(TObject *Sender); + void __fastcall SaveProfileButtonClick(TObject *Sender); + void __fastcall LoadProfileButtonClick(TObject *Sender); + void __fastcall OKButtonClick(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall CancelButtonClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); +private: // ユーザー宣言 + void __fastcall SaveProfile(AnsiString name); + void __fastcall SaveProfileToIni(TMemIniFile *ini); +public: + void __fastcall LoadProfile(AnsiString name); +private: + void __fastcall LoadProfileFromIni(TMemIniFile *ini); + void __fastcall LoadExtList(AnsiString ext, TStrings *to, TStrings *f1, TStrings *f2); + AnsiString ProjFolder; + TStringList *FileList; + void __fastcall MoveSelected(TListBox *dest, TListBox *src); + + void __fastcall _CreateArchive(void); + void __fastcall CreateArchive(void); + + bool Aborted; + + bool GoImmediate; + + bool WriteDefaultRPF; + +protected: + void __fastcall WMStart(TMessage &msg); + void __fastcall WMClose(TMessage &msg); + +BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER(WM_USER + 0x10 , TMessage, WMStart); + VCL_MESSAGE_HANDLER(WM_USER + 0x11 , TMessage, WMClose); +END_MESSAGE_MAP(TForm) + +public: // ユーザー宣言 + __fastcall TRelSettingsForm(TComponent* Owner); + + AnsiString __fastcall GetKrKrFileName(); + void __fastcall SetProjFolder(AnsiString folder); + void __fastcall SetFileList(TStringList *list); + void __fastcall SetExtList(TStringList *list); + void __fastcall LoadDefaultProfile(); + + void __fastcall SetGoImmediate(bool b = true) { GoImmediate = b; } + void __fastcall SetWriteDefaultRPF(bool b = true) { WriteDefaultRPF = b; } + void __fastcall SetOutputFilename(AnsiString s) { OutputFileNameEdit->Text = s; } +}; +//--------------------------------------------------------------------------- +extern PACKAGE TRelSettingsForm *RelSettingsForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/SignMainFormUnit.cpp b/tools/win32/krdevui/SignMainFormUnit.cpp new file mode 100644 index 0000000..0ed8e5a --- /dev/null +++ b/tools/win32/krdevui/SignMainFormUnit.cpp @@ -0,0 +1,351 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include + +#define _MSC_VER +#include +#undef _MSC_VER + +#include "SignMainFormUnit.h" +#include "RandomizeFormUnit.h" +#include "SignUnit.h" +#include "KrkrExecutableUnit.h" + + +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TSignMainForm *SignMainForm; +//--------------------------------------------------------------------------- +__fastcall TSignMainForm::TSignMainForm(TComponent* Owner) + : TForm(Owner) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::FormDestroy(TObject *Sender) +{ + Clipboard()->Clear(); +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::CloseButtonClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::CopyPublicKeyButtonClick(TObject *Sender) +{ + GeneratedPublicKeyEdit->SelectAll(); + GeneratedPublicKeyEdit->CopyToClipboard(); +} +//--------------------------------------------------------------------------- + +void __fastcall TSignMainForm::CopyPrivateKeyButtonClick(TObject *Sender) +{ + GeneratedPrivateKeyEdit->SelectAll(); + GeneratedPrivateKeyEdit->CopyToClipboard(); +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::GenerateButtonClick(TObject *Sender) +{ + prng_state prng; + int errnum; + + CopyPublicKeyButton->Enabled = false; + CopyPrivateKeyButton->Enabled = false; + + // initialize random generator + if(!RandomizePRNG(&prng)) return; + + // once process message to display window + KeyGeneratingLabel->Visible = true; + Application->ProcessMessages(); + + // generate key + rsa_key key; + char buf[10240]; + char buf_asc[sizeof(buf)*3/2+2]; + + errnum = rsa_make_key(&prng, find_prng("fortuna"), 128, 65537, &key); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + + + try + { + // export keys + unsigned long outlen, asc_outlen; + + // public key + outlen = sizeof(buf) - 1; + errnum = rsa_export(buf, &outlen, PK_PUBLIC, &key); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + asc_outlen = sizeof(buf_asc) - 1; + base64_encode(buf, outlen, buf_asc, &asc_outlen); + buf_asc[asc_outlen] = 0; + GeneratedPublicKeyEdit->Text = + AnsiString("-----BEGIN PUBLIC KEY-----\r\n") + Split64(buf_asc) + + AnsiString("-----END PUBLIC KEY-----\r\n"); + + // private key + outlen = sizeof(buf) - 1; + errnum = rsa_export(buf, &outlen, PK_PRIVATE, &key); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + asc_outlen = sizeof(buf_asc) - 1; + base64_encode(buf, outlen, buf_asc, &asc_outlen); + buf_asc[asc_outlen] = 0; + GeneratedPrivateKeyEdit->Text = + AnsiString("-----BEGIN RSA PRIVATE KEY-----\r\n") + Split64(buf_asc) + + AnsiString("-----END RSA PRIVATE KEY-----\r\n"); + } + catch(...) + { + rsa_free(&key); + KeyGeneratingLabel->Visible = false; + throw; + } + + rsa_free(&key); + + CopyPublicKeyButton->Enabled = true; + CopyPrivateKeyButton->Enabled = true; + KeyGeneratingLabel->Visible = false; +} +//--------------------------------------------------------------------------- + + + +void __fastcall TSignMainForm::SignFileNameRefButtonClick(TObject *Sender) +{ + OpenDialog->FileName = SignFileNameEdit->Text; + if(OpenDialog->Execute()) + { + SignFileNameEdit->Text = OpenDialog->FileName; + } +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::CheckSignFileNameRefButtonClick(TObject *Sender) +{ + OpenDialog->FileName = CheckSignFileNameEdit->Text; + if(OpenDialog->Execute()) + { + CheckSignFileNameEdit->Text = OpenDialog->FileName; + } + +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::FormShow(TObject *Sender) +{ + DragAcceptFiles(Handle, true); +} +//--------------------------------------------------------------------------- + +void __fastcall TSignMainForm::SignButtonClick(TObject *Sender) +{ +/* +//--------------------------------------------------------------------------- +extern char XOPT_EMBED_AREA_[];// = " OPT_EMBED_AREA_"; +extern char XCORE_SIG_______[];// = " CORE_SIG_______"; +extern char XRELEASE_SIG____[];// = " RELEASE_SIG____"; +//--------------------------------------------------------------------------- +extern int CheckKrkrExecutable(AnsiString fn, const char *mark); +//--------------------------------------------------------------------------- + +*/ + bool result; + + int ignorestart = CheckKrkrExecutable(SignFileNameEdit->Text, XOPT_EMBED_AREA_); + int signofs = CheckKrkrExecutable(SignFileNameEdit->Text, XRELEASE_SIG____); + int xp3ofs = CheckKrkrExecutable(SignFileNameEdit->Text, XP3_SIG); + + if(ignorestart != 0 && signofs != 0) + { + // krkr executable + result = SignFile(SignPrivateKeyEdit->Text, SignFileNameEdit->Text, + ignorestart, xp3ofs?xp3ofs:-1, signofs+ 16+4); + } + else + { + if(ignorestart && !signofs) + { + Application->MessageBox("Warning: Signature area is not found.\n" + "Target kirikiri executable may be too old.", Caption.c_str(), + MB_OK|MB_ICONWARNING); + } + // normal file + result = SignFile(SignPrivateKeyEdit->Text, SignFileNameEdit->Text, -1, -1, -1); + } + + + if(result) + { + Application->MessageBox(SignDoneLabel->Caption.c_str(), Caption.c_str(), + MB_OK|MB_ICONINFORMATION); + } +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::CheckSignatureButtonClick(TObject *Sender) +{ + + bool result; + + int ignorestart = CheckKrkrExecutable(CheckSignFileNameEdit->Text, XOPT_EMBED_AREA_); + int signofs = CheckKrkrExecutable(CheckSignFileNameEdit->Text, XRELEASE_SIG____); + int xp3ofs = CheckKrkrExecutable(CheckSignFileNameEdit->Text, XP3_SIG); + + if(ignorestart != 0 && signofs != 0) + { + // krkr executable + result = CheckSignatureOfFile(CheckSignPublicKeyEdit->Text, + CheckSignFileNameEdit->Text, ignorestart, xp3ofs?xp3ofs:-1, + signofs+ 16+4); + } + else + { + // normal file + result = CheckSignatureOfFile(CheckSignPublicKeyEdit->Text, + CheckSignFileNameEdit->Text, -1, -1, -1); + } + + if(result) + { + Application->MessageBox(SignatureIsValidLabel->Caption.c_str(), + Caption.c_str(), MB_OK|MB_ICONINFORMATION); + } + else + { + Application->MessageBox(SignatureIsInvalidLabel->Caption.c_str(), + Caption.c_str(), MB_OK|MB_ICONINFORMATION); + } +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::SignPrivateKeyEditChange(TObject *Sender) +{ + AnsiString mark1("-----BEGIN RSA PRIVATE KEY-----"); + AnsiString mark2("-----END RSA PRIVATE KEY-----"); + bool state = + strstr(SignPrivateKeyEdit->Text.c_str(), mark1.c_str()) && + strstr(SignPrivateKeyEdit->Text.c_str(), mark2.c_str()) && + FileExists(SignFileNameEdit->Text); + SignButton->Enabled = state; +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::CheckSignPublicKeyEditChange(TObject *Sender) +{ + AnsiString mark1("-----BEGIN PUBLIC KEY-----"); + AnsiString mark2("-----END PUBLIC KEY-----"); + bool state = + strstr(CheckSignPublicKeyEdit->Text.c_str(), mark1.c_str()) && + strstr(CheckSignPublicKeyEdit->Text.c_str(), mark2.c_str()) && + FileExists(CheckSignFileNameEdit->Text) /*&& FileExists(CheckSignFileNameEdit->Text + ".sig")*/; + CheckSignatureButton->Enabled = state; +} +//--------------------------------------------------------------------------- +void __fastcall TSignMainForm::WMDropFiles(TMessage &Msg) +{ + HDROP hd = (HDROP)Msg.WParam; + + char filename[ MAX_PATH ]; + int filecount= + DragQueryFile(hd, 0xFFFFFFFF, NULL, MAX_PATH); + + for(int i = filecount-1; i>=0; i--) + { + DragQueryFile(hd, i, filename, MAX_PATH); + + WIN32_FIND_DATA fd; + HANDLE h; + + // existence checking + if((h = FindFirstFile(filename, &fd)) != INVALID_HANDLE_VALUE) + { + FindClose(h); + + if(PageControl->ActivePage == SignTabSheet) + SignFileNameEdit->Text = filename; + else if(PageControl->ActivePage == CheckSignTabSheet) + CheckSignFileNameEdit->Text = filename; + + break; + } + + } + DragFinish(hd); +} +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +static AnsiString ReadTextFile(AnsiString fn) +{ + // fn を全て読み、AnsiString として返す + TFileStream *s = new TFileStream(fn, fmOpenRead|fmShareDenyWrite); + AnsiString ret; + char *buf = NULL; + try + { + int size = s->Size; + buf = new char [ size + 1]; + s->ReadBuffer(buf, size); + buf[size] = '\0'; + ret = buf; + } + catch(...) + { + if(buf) delete [] buf; + delete s; + throw; + } + if(buf) delete [] buf; + delete s; + return ret; +} +//--------------------------------------------------------------------------- +extern "C" void _export PASCAL UIExecSign() +{ + // check argvs + try + { + int argc = ParamCount(); + if(argc >= 3 && !strcmp(ParamStr(1).c_str(), "-sign")) + { + AnsiString target = ParamStr(2); + AnsiString privkey = ReadTextFile(ParamStr(3)); + AnsiString mark = XRELEASE_SIG____; + if(argc >= 5) mark = ParamStr(4); + + int ignorestart = CheckKrkrExecutable(target, XOPT_EMBED_AREA_); + int signofs = CheckKrkrExecutable(target, mark.c_str()); + int xp3ofs = CheckKrkrExecutable(target, XP3_SIG); + + if(ignorestart != 0 && signofs != 0) + { + // krkr executable + SignFile(privkey, target, + ignorestart, xp3ofs?xp3ofs:-1, signofs+ 16+4); + } + else + { + // normal file + SignFile(privkey, target, -1, -1, -1); + } + return; + } + + + // execute + TSignMainForm * signmainform = new TSignMainForm(Application); + signmainform->ShowModal(); + delete signmainform; + } + catch(Exception &e) + { + MessageBox(NULL, e.Message.c_str(), "Error", MB_OK | MB_ICONEXCLAMATION); + } +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/SignMainFormUnit.dfm b/tools/win32/krdevui/SignMainFormUnit.dfm new file mode 100644 index 0000000..517d647 --- /dev/null +++ b/tools/win32/krdevui/SignMainFormUnit.dfm @@ -0,0 +1,1014 @@ +object SignMainForm: TSignMainForm + Left = 63 + Top = 17 + ActiveControl = PageControl + BorderStyle = bsDialog + Caption = 'キー・署名ツール' + ClientHeight = 384 + ClientWidth = 369 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + Icon.Data = { + 000001000700101000000100200068040000760000003030000001002000A825 + 0000DE0400002020000001002000A8100000862A00002020100001000400E802 + 00002E3B00002020000001000800A8080000163E000010101000010004002801 + 0000BE460000101000000100080068050000E647000028000000100000002000 + 0000010020000000000040040000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000020000001D0000 + 002A000000240000000900000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000170008064C0180 + 6CC410A089E5006156A90000000E000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000002200967EE255D2 + BEFA889796D02ACAC6FF005A5FA2000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000003D00D8B6FF025B + 4E9400000023006672C903798EEA000000000000000000000000000000000000 + 0000000000000000000000000016000000110000000F0000003901AE9BFD008A + 86DD002A31890C88A2F2487C87C8000000160000001200000000000000000000 + 000000000000000000040000002C004E41B10005044A004F49AA0ED5CEFF78C5 + C9FF80C8D5FF7E9AA1E91516174800000034550657BA12011535000000000000 + 000000000004000000252227268B33F2D3FF00A996F808CEC8FF6CA9ACED0B0C + 0C3E000000360000001A0000002F6B086CC0DC15FAF9640B9EEE0000001A0000 + 000C0000001D001F1A5F007F6BE505665CE804DDD6FF6AB1B4F31C1E1E380000 + 00000000000E0000002C5F075FB4E012F7F98C2CBAFB7F34FCFE463076CC0000 + 001F00423795304D48EA08EACFFF02D4CEFF66B8BCF9282A2B45000000000000 + 000B0000002A520653A6E417F2F9BB35FCFC6125B3F833254FE01610223B0505 + 054142CFB9FF00BDA6FC00B8B4FF5FBEC3FC32353656000000080000000A0000 + 002947054797E113EBF9AA10E3FB331F4BD3563E89D300000012000000000000 + 00002A423F8D34DAD5FF57C3C9FE373B3C7000000028000000350000003E3C04 + 3C88DF1AE4F8B350C9FA8F35F1FD57359DEF0000002300000000000000000000 + 000000000004556162A3464B4C77000000254505458CB42EB4F5C432C5FADA10 + DEF8BA40CEF526152C493A2B5A902F23496F0000000000000000000000000000 + 000000000000000000010000000002000252D611D6F88F4390C5683268A5C514 + E5FA4B086E9E0000000000000000000000000000000000000000000000000000 + 00000000000000000000000000002103216AF312F3F8040004610000002C630C + A9F2512193B90000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000025C837C8F69B16A8E2561288CC8845 + EEFE3729567D0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000003E1E3F588C4EA2E17B52ACF44432 + 6A9B00000007000000000000000000000000000000000000000000000000FE3F + 0000FC0F0000FC0F0000FC0F0000E0030000E0010000C0000000008000000100 + 00000201000080030000C0070000F03F0000F03F0000F03F0000F87F00002800 + 0000300000006000000001002000000000008025000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000500000017000000230000002A0000002A0000002400000018000000060000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000110000 + 00290000002B0000002B0000002B0000002B0000002B0000002B0000002A0000 + 0013000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000120000002B0000 + 002B0000002B0000002B0000002B0000002B0000002B0000002B0000002B0000 + 002B000000150000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000080000002A0000002B0000 + 002B0000002B0000002B0000005900000096000000B6000000BA000000A20000 + 006D0000002F0000000A00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000001D0000002B0000002B0000 + 002B0000004E000000CD003A31FF008F78FF00BB9CFF00C0A1FF009F86FF0054 + 48FF000505E60000006400000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000001000000290000002B0000002B0000 + 0063001512F500B396FF00FED5FF05FED6FF38FEDEFF3EFEDFFF0AFAD7FF00F3 + D5FF00C7B5FF002F2CFF0000007E000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000070000002B0000002B000000490013 + 10F400D5B2FF00FED5FF24FEDBFFC7FEF6FFE8FEFBFFE8FDFBFFD5FCF8FF3AEF + DFFF00E4D5FF00D3CCFF003030FF0000005C0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000A0000002B0000002B000000C000A6 + 8BFF00FED5FF00FED5FFBBFEF4FFB1C2C0FF626B6AFF565E5DFF8C9897FFCFF2 + F1FF0ADDD7FF00D4D5FF00B5BCFF00090AEB0000000D00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000060000002B00000047002821FE00FD + D4FF00FED5FF1BFED9FF7B8685FF010101D00000005D0000004D000000AD3135 + 35FE34D2D3FF00CDD5FF00C5D5FF00515AFF0000006600000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000260000007F007562FF00FE + D5FF00FED5FF0AD3B2FF020303D90000000C00000000000000190000002B0000 + 009B005F64FF00C5D5FF00BED5FF00869CFF000000AB00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000180000009B009A81FF00FE + D5FF00FED5FF008772FF0000008500000016000000230000002B0000002B0000 + 0041002024FF00BED5FF00B6D5FF009CBCFF000000CD00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000009000000290000009B029A81FF00FE + D5FF00FAD5FF008070FF0000008B0000002B0000002B0000002B0000002B0000 + 003D001D21FF00B6D5FF00B1D5FF1CA4C1FF000000CD00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000001600000007000000000000 + 0000000000000000000000000007000000280000002B0000007F0A7463FF00FA + D5FF00F3D5FF00BBA9FF000100D7000000300000002B0000002B0000002B0000 + 008D004C5AFF00B1D5FF00B0D5FF67A0ADFF000000AC00000000000000000000 + 00190000000B0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000170000002B00000028000000090000 + 00000000000000000005000000260000002B0000002B00000046002620FE00F1 + D4FF00EBD5FF00E3D5FF00615EFF000000C9000000640000005500000099001A + 20FC00A2C4FF00B0D5FF5FCDE5FF63696BFF0000006700000000000000180000 + 002B000000290000000D00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000140000002B0000002B0000002B000000290000 + 000B00000004000000240000002B0000002B0000002B0000003F000404F100C9 + B7FF00E3D5FF00DCD5FF00D4D5FF00898FFF003F45FF00333AFF005A6BFF00A5 + C8FF01B0D5FF64CEE5FFCBD9DEFF0B0B0CEC0000000E000000150000002B0000 + 002B0000002B0000002A00000010000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000F0000002B0000002B0000002B0000002B000000770000 + 0045000000240000002B0000002B0000002B00000039000201D8009286FF00E3 + D5FF00DCD5FF03D5D5FF44DAE0FF0EC8D7FF00BDD5FF00B6D5FF0BB4D7FF49C6 + E1FFB2E6F2FFDFECF1FF353839FF0000005D000000120000002B0000002B0000 + 002B0000002B0000009100000066000000060000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000005000000250000002B0000002B0000007400211CFD0008 + 07E90000004F0000002B0000002B00000033000000CE008277FF00E3D5FF00DC + D5FF01D4D5FF8DE9ECFFE8F8FBFFE6F7FBFFD2F1F7FFD1EFF7FFE5F5FBFFE8F6 + FBFFC7D3D7FF323536FF000000800000000F0000002B0000002B0000002B0000 + 002B00000087350435FD1E021EF9000000650000000100000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000700000006000000040000002300000067001F1AFA00E2BDFF00BC + 9EFF000E0CEF0000005900000030000000C2007168FF00E3D5FF00DCD5FF00D4 + D5FF7DE6E9FFC0CED0FF424647FF838C8EFFABB6B9FFB0BBBEFF939B9FFF5055 + 57FF060606E3000000550000000C0000002A0000002B0000002B0000002B0000 + 00782C032CFCEA11EBF8D310E0F9220328FC0000007600000002000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00050000002600000027000000080000003D0E1715F601D8B5FF00FED5FF00FE + D5FF00C9A9FF001411F5000000C7006058FF00E3D5FF00DCD5FF00D4D5FF6CE2 + E7FFCAD8DBFF191B1BF70000006400000081000000A8000000AD000000900000 + 0051000000060000000A000000290000002B0000002B0000002B0000006B2202 + 22FAE210E3F9F212FDF8DC12FDF9B611E9FB230433FE00000087000000030000 + 0000000000000000000000000000000000000000000000000000000000040000 + 00240000002B0000002B0000002E000000E38D9B99FF91FEEDFF04FED6FF00FE + D5FF00FAD5FF00CBB2FF00665DFF00E1D3FF00DCD5FF00D4D5FF5BDFE4FFD2E1 + E3FF212424FB0000005000000000000000000000000000000000000000000000 + 000000000008000000280000002B0000002B0000002B0000005F190219F7D910 + DAF9F512FDF8DF12FDF9C912FDFAB212FEFB680CA7FD000000EE000000120000 + 0000000000000000000000000000000000000000000000000002000000220000 + 002B0000002B0000002B000000390000006F0C0D0DEEAABAB8FF8CFEECFF00FA + D5FF00F3D5FF00EBD5FF00E3D5FF00DCD5FF00D4D5FF4CDCE1FFD7E8EBFF2B2E + 2FFE000000600000000000000000000000000000000000000000000000000000 + 0006000000270000002B0000002B0000002B00000054110112F2CE0FCFF9F913 + FEF7E413FEF9D22BFDFAB612FEFB9F12FEFC8812FEFD38097EFE000000C60000 + 0011000000000000000000000000000000030000001500000006000000250000 + 002B0000002B00000033000000CE000404E60000006E070808E721A995FF00F3 + D5FF00EBD5FF00E3D5FF00DCD5FF00D4D5FF3FDADFFFD9EDF0FF363A3BFF0000 + 0072000000000000000000000000000000000000000000000000000000050000 + 00250000002B0000002B0000002B0000004B0B010BECC20EC3FAF912FDF8E712 + FDF9D41FFEF9D572FEFCB440FEFD8B12FEFD7513FFFD6213FFFE3D1591FF0101 + 02D2000000190000000000000002000000210000002B0000001C000000050000 + 002300000030000000C2007B67FF00B89BFF000C0AED0000006F000303E8009E + 8FFF00E3D5FF00DCD5FF00D4D5FF32D7DDFFD8F1F4FF434849FF000000850000 + 0000000000000000000000000000000000000000000000000003000000240000 + 002B0000002B0000002B00000043060006E5B40DB5FAFA12FDF8EA12FDF8D412 + FDFABD12FEFB7F1EB4FDB16DEDFE9748FFFE6413FFFE671FFFFF9C6EFFFF5F46 + 93FF000000DB000000010000001E0000002B0000002B0000002B0000001F0000 + 0007000000B2006958FF00FED5FF00FED5FF00C2A6FF00120FF400211EFC00CD + C1FF00DCD5FF00D4D5FF27D5DBFFD5F3F6FF515758FF00000097000000010000 + 00000000000000000000000000000000000000000002000000220000002B0000 + 002B0000002B0000003C030003DDA50CA5FAFB12FDF8EE12FDF8D712FDF9C112 + FEFB7D0DB6FC030005F21D102EFD9568E6FE8951FFFF9A6AFFFF9D74F4FF241B + 39FF0000006D0000001C0000002B0000002B0000002B0000002D000000780000 + 009E444B4AFF8AFCEAFF03FED5FF00FAD5FF00F2D5FF00C2B0FF00C5B9FF00DC + D5FF00D4D5FF1ED3DAFFCFF3F7FF616769FF000000A800000002000000000000 + 0000000000000000000000000000000000010000001F0000002B0000002B0000 + 002B00000036010001D3940B95FBFD13FEF7F112FDF8DB14FDF9C412FDFAAD12 + FEFB8811E5FC17032DFD000000CB171124FB8E69DDFFA076F9FF2D2146FF0000 + 007F00000000000000120000002B0000002B0000002C000000AB001A16FF0000 + 00DC0D0F0EF3ADBEBCFF42FAE0FF00F2D5FF00EBD5FF00E3D5FF00DCD5FF00D4 + D5FF16D1D9FFC7F2F6FF71797BFF000000B70000000600000000000000000000 + 00000000000000000000000000010000001D0000002B0000002B0000002B0000 + 0031000000C8820982FBFC12FDF8F513FEF7E42FFFF9DC6BFDFCB622FEFC9A13 + FFFC8413FFFD6A18EDFE231939FF000000CE110D1BF730234AFF000000920000 + 000000000000000000000000000F0000002A0000009C004C40FF00F5CEFF005E + 4FFF000000DF030908EF00A893FF00EBD5FF00E3D5FF00DCD5FF00D4D5FF0FD0 + D7FFBDEFF4FF828B8DFF000000C50000000B0000000000000000000000000000 + 000000000000000000000000001A0000002B0000002B0000002B0000002E0000 + 00BC6F0870FCFC12FDF8F612FDF8E212FDF9D12AFEFAC76CEFFCC471FFFD9127 + FFFD7317FFFE9561FFFF9A72F0FF0C0913FF0000009000000097000000020000 + 00000000000000000000000000000000007C063E35FF00F5CEFF00FED5FF00FC + D4FF006E5DFF000000E5000A09FF00CFC2FF00DCD5FF00D4D5FF09CED6FFB2ED + F2FF929C9EFF020202D100000011000000000000000000000000000000000000 + 000000000000000000170000002B0000002B0000002B0000002C000000AE5E07 + 5EFCFB12FCF8F912FDF8E512FDF9CF12FDFAA510E2FB16031FFE5E3C7EFEAC73 + FFFE9661FFFFA378FEFF3F2E62FF0000009F0000000100000000000000000000 + 00000000000000000000000000400B0C0CFEC8E9E4FF3AFEDEFF00FED5FF00FA + D5FF00F2D5FF00786DFF00978EFF00DCD5FF00D4D5FF05CDD6FFA5EAF0FFA1AC + AEFF040505DC0000001900000000000000000000000000000000000000000000 + 0000000000140000002B0000002B0000002B0000002B000000A04E064EFDF812 + F9F8FA12FDF8E912FDF8D212FDFABC12FEFB310547FE000000A7000000B84733 + 6CFFA378FDFF4A3773FF000000AF000000040000000000000000000000000000 + 0000000000000000000000000001000000903F4444FFD5F2EEFF34FADDFF00F2 + D5FF00EBD5FF00E3D5FF00DCD5FF00D4D5FF02CDD5FF97E7EEFFAEBABCFF0809 + 09E500000022000000020000000F000000170000001A000000160000000D0000 + 00120000002B0000002B0000002B0000002B00000090400540FDF512F6F8FD13 + FEF7EE1CFDF9D81DFDFABF12FEFBA812FEFC8110E2FD14032AFC0000006F0000 + 00A91F1730FF000000BE00000008000000000000000000000000000000000000 + 0000000000000000000000000000000000000000007E323737FF74E6D9FF01EB + D5FF00E3D5FF00DCD5FF00D4D5FF00CCD5FF87E4EBFFBAC6C9FF0E0F0FED0000 + 002D00000013000000280000002B0000002B0000002B0000002B0000002B0000 + 002B0000002B0000002B0000002B00000081330433FDF012F1F8FE13FFF7F21A + FFF7E868FFFBD96CFEFCB120FEFC9512FEFD7F13FFFD6011EBFE180A35FE0000 + 007D000000770000000D00000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000006F282B2BFF83E2 + DDFF04DCD6FF00D4D5FF00CCD5FF77E0E8FFC4D2D4FF141616F40000003A0000 + 001C0000002B0000002B0000002B0000002B0000002B0000002B0000002B0000 + 002B0000002B0000002B00000073280328FCE911E9F8FE13FFF7F517FFF7EA63 + FFFADD79FBFC9657B5FDC16FFEFD8C25FFFD6C13FFFE7432FFFF9A71F2FF251B + 39FF0000007F0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000024030303EAA8B5 + B6FFA0EEEFFF07CED6FF66DCE6FFCDDBDEFF1C1E1EF900000047000000180000 + 002B0000002B0000002B0000002B0000002B000000420000006C0000007B0000 + 006E00000046000000671E021EF9E010E1F8FE13FFF7F815FFF7EC5DFFFAE17A + FEFC532F61FE000001EF603F84FEA972FFFE7E40FFFFA275FFFF8865D4FF0D09 + 14F2000000350000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000280707 + 07E29BA7A8FFC0F0F4FFD4E3E6FF252728FC00000056000000090000002B0000 + 002B0000002B0000002B0000005E000000CB250325FD5E075FFC720873FC6107 + 61FC2A032AFE150216FBD50FD6F9FE13FFF7FA14FFF7EE57FFFAE37BFFFC6337 + 73FE000000AF00000011000000BC4A3672FFA378FEFF8F6ADEFF120D1CF70000 + 0042000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 001E030303D8838C8EFF2F3233FE00000067000000000000001C0000002B0000 + 002B0000002B0000009329032AFCBB0EBBF9FE1FFFF7FE42FFF8FD45FEF9FC27 + FDF9FC12FDF8EF11F0F8FC12FDF8FB13FEF7ED32FFF8E67BFFFC744086FD0000 + 00BE000000080000000000000007000000AE3B2B5CFF181225FB000000500000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000016000000CD000000790000000000000000000000280000002B0000 + 002B0000008A400541FDF212F3F7FE2EFFF8FE77FFFAFE7BFFFAFE7BFFFAFD7A + FDFBFC41FDF9FC12FDF8FB12FDF8EC12FEF8D717FFF9834498FD010001CB0000 + 000E000000000000000000000000000000040000009D00000061000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000080000000000000000000000020000002B0000002B0000 + 004C1C021CF9ED12EEF8FE14FFF7FE6DFFFAF979FAFAB256B3FB8F4590FCB256 + B2FCF976F9FBFC1EFDF8EE12FDF8D812FEF9880DAEFB020003D7000000150000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000020000002B0000002B0000 + 00AC980B99FBFD13FEF7FE1EFFF7E26DE3FB2D162DFC000000AC0000007C0000 + 00B72D162DFDD828E2FADB12FDF9C512FEFA7B0DB1FC000000B1000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000260000002C0600 + 06EEEF11F0F8FC12FDF8FE17FFF7401D40FE0000005F00000000000000060000 + 002A0000007B380541FDC912FDFAB213FFFB9A13FCFB0A0113F8000000090000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000001A0000003F2A03 + 2AFEFC12FDF8FC12FDF8DF10E0F9000000D70000000800000011000000260000 + 002B0000002B000000DDA110E2FC9F13FFFB8813FFFC250F42FF0000002E0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000006000000463504 + 35FDFC12FDF8FC12FDF8CD0FCDF9000000C80000002B0000002B0000002B0000 + 002B0000002B000000C9830FD1FC8C13FFFC7F23FFFD33254EFF000000390000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000001D1C06 + 1CFDFC19FDF8FC12FDF8F311F4F80F010FF40000003B0000002B0000002B0000 + 002B0000003C090110F58A12F7FC7813FFFD9156FFFE211934FF000000220000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00D0D748D7FBFC14FDF8FC12FDF88F0A90FB000000CF0000004D0000002B0000 + 004D000000CF510B93FD7C13FFFD813AFFFE9870ECFF040306E7000000010000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0070683269FDFD5CFEFAFC1AFDF8FC12FDF8990BA1FB28032FFE0A010DF91F04 + 30FE5E0CA4FD8014FFFD8842FFFEA378FFFF543E82FF00000088000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0009040204DABC5BBDFBFE74FFFAF849FFF9E228FFF9C917FFF9B215FFFAA121 + FFFC9A3CFFFDA166FFFEA479FFFF8663D0FF07050BE800000013000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000002D0F070FEDB358B6FBEF7BFFFBE27BFFFCD57AFFFCC87AFFFDBB7A + FFFDAE79FFFEA579FFFF805EC7FF0F0B18F50000003E00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000029010102D14F2A58FEA35CC0FDC577F8FDBD7AFFFDAD77 + FAFE825FC8FF413064FF030204DC000000360000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000040000005C000000B6030204EA0D0912FC0403 + 06ED000000BC0000006600000008000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000FFFFFE07FFFF0000FFFFF801FFFF0000FFFFF000FFFF0000FFFF + F0007FFF0000FFFFE0007FFF0000FFFFE0003FFF0000FFFFE0001FFF0000FFFF + C0000FFF0000FFFFE0000FFF0000FFFFE0100FFF0000FFFFE0000FFF0000FFFF + E0000FFF0000FFEFC0000CFF0000FFC78000087F0000FF810000003F0000FF00 + 0000003F0000FF800000001F0000FFC00000000F0000FE40000100070000FC00 + 007F00030000F80000FE00010000E80001FC00000000C40003F8000000008200 + 07F00000000000000FE00001000000001FC00003000080001F8000070000C000 + 3F00001F000080007E00003F0000C0008000007F0000E0000000007F0000F000 + 000000FF0000F000000000FF0000F808000001FF0000FC100001C3FF0000FE30 + 0001E7FF0000FFF00003FFFF0000FFF00007FFFF0000FFF00C07FFFF0000FFF0 + 1003FFFF0000FFF80003FFFF0000FFF80003FFFF0000FFFC0007FFFF0000FFFC + 0007FFFF0000FFFE0007FFFF0000FFFE000FFFFF0000FFFF001FFFFF0000FFFF + C07FFFFF00002800000020000000400000000100200000000000801000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000050000001A000000270000002A00000025000000150000 + 0001000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000008000000280000002B0000002B0000002B0000002B0000002B0000 + 0022000000020000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0001000000240000002B0000002B00000062000C0AB000332BD000241EC60000 + 0090000000280000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000C0000002B0000002D000E0BAB008F78FF02F4CDFF28FEDCFF11FCD8FF00C7 + AFFF003F3AEB0000003800000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00140000002B0004039500B99BFF0AFED7FFB6FEF3FFD8ECEAFFD9F5F3FF45ED + E0FF00D8D1FF003D3FEB00000017000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 001300000038005E4FF700FED5FF4BF2D7FF49504FEA0101018E101111B56294 + 93FF00D1D5FF00AAB8FF00030388000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00090000006800AA8EFF00FED5FF057F6CFF0000002F0000000E0000002A0006 + 06AB00B1C0FF00BAD5FF002931CE000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000D0000007601BC9EFF00FCD5FF00584CF60000002B0000002B0000002B0000 + 007C008DA3FF00B1D5FF0E3942DE000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000160000000B00000000000000000000000A0000 + 00290000005A04947FFF00F3D5FF009185FF000000790000002B000000320014 + 17CB00A9CBFF3AC1DEFF232526BD00000000000000180000000E000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000150000002B0000002A0000000E00000008000000280000 + 002B0000003600473FF800E7D5FF00DBD5FF007477FF002D32DA003842ED0090 + AEFF2DBEDCFF8FA8AEFF00000065000000160000002B0000002B000000110000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000090000002B0000002B0000004E0000008E000000280000002B0000 + 0030001715C400C0B2FF00DCD5FF40DDDFFF5FDBE5FF3ECBDFFF4DC8E2FF8FDB + ECFFC1D0D5FF1F2122C2000000160000002B0000002B00000057010001AC0000 + 000B000000000000000000000000000000000000000000000000000000000000 + 0000000000060000001300000045003F35E8009E84FF000907A50000002F0010 + 0FB700B5A8FF00DCD5FF38DCDEFFA6BABCFF99A3A6FFC1CDD1FFB5C0C4FF7379 + 7CFE131415A80000001E0000002B0000002B0000004D490549EDB80DBEFA1402 + 18BC0000000E0000000000000000000000000000000000000000000000000000 + 001500000029000000232D3533DC14EDCAFF00FED5FF00B599FF001311E100A8 + 9DFF00DCD5FF2CD9DCFFA8C0C2FF101212A70000004B00000072000000660000 + 00270000000D0000002A0000002B000000453C043DE6ED11F2F8DD12FDF99A0F + D1FC07010CC40000000500000000000000000000000000000000000000120000 + 002B0000002B00000051292D2CDBA9E0D7FF10FCD8FF00F3D5FF00DAC9FF00DC + D5FF22D7DBFFACCACDFF171919B6000000060000000000000000000000000000 + 000B0000002A0000002B0000003D310331DEE911ECF8E41AFDF9C115FEFB9E12 + FEFC3D097CFC0000006500000000000000000000000700000017000000150000 + 002B00000046002C25E9000605AC152321D100CCB3FF00E7D5FF00DCD5FF19D6 + D9FFADD3D6FF1F2222C40000000A000000000000000000000000000000080000 + 00290000002B00000037270327D5E110E3F9E712FDF9CD2CFEFABF5BFDFD8418 + FEFD6413FFFE4A2A8FFE0201037600000005000000260000002B0000001C0000 + 002900352CE100EEC7FF00AD93FF000908D200827AFF00DCD5FF12D4D8FFACDA + DDFF282B2CD10000001100000000000000000000000000000006000000270000 + 002B000000321E021ECBD80FD9F9EC12FDF8CB12FDFA700BA1FD331D4AF8935D + F4FE8348FFFF8C67D9FF0E0B16BD000000210000002B0000002C0000008E0101 + 01C992CDC4FF15FCD8FF00F2D5FF00C7B8FF00DCD5FF0BD3D7FFA8DFE3FF3235 + 36DC0000001800000000000000000000000000000005000000260000002B0000 + 002F150216BFCE0FCFF9F214FEF8D423FDFAAE12FEFB710FCDFD0A0219E7271D + 3DF08763D2FF191327CA0000000D00000008000000270006059C00977EFF002D + 25F01E2423EE09D1B9FF00E7D5FF00DCD5FF07D2D6FFA2E3E7FF3D4142E50000 + 002200000000000000000000000000000003000000240000002B0000002C0E01 + 0EB2C10EC2FAF412FDF8DB28FEF9CC6FF8FC9F2FFFFC7A22FFFE855DD8FF0605 + 0AE0020103B2000000140000000000000000020302782D9E8CFF00FED5FF00E9 + C5FF00362FF3005E58FF00DCD5FF03D1D5FF98E4EAFF484D4EED0000002C0000 + 0000000000000000000000000002000000220000002B0000002B080108A4B30D + B4FAF712FDF8DB12FDF9970ECAFC17091FEB8459C1FE9E6EFFFF483571F90000 + 0049000000000000000000000000000000000707078D91A3A1FF4AFCE1FF00F2 + D5FF00DCCBFF00D6D0FF01D0D5FF8DE4EAFF555B5CF400000038000000070000 + 00100000001000000007000000200000002B0000002B04000494A40CA5FAFA12 + FEF8E21BFDF9BE12FEFB7A0EC7FD0C0219BB09070EA93A2B5AFD000000580000 + 000000000000000000000000000000000000000000000304047B5A908AFF14E9 + D8FF00DCD5FF00D0D5FF7EE2E9FF636A6BF90000004A0000001F0000002B0000 + 002B0000002B0000002B0000002B0000002B01000185930B94FAFD13FFF7EE3E + FFF9DC74FEFCAB2BFEFC8013FFFD5D1ED3FF161022C50000004B000000000000 + 0000000000000000000000000000000000000000000000000000020202BCA2D0 + CFFF1CD5DAFF6DDFE7FF737B7CFC00000058000000240000002B0000002B0000 + 002D000000500000005F0000004400000077820982FAFD13FFF7F137FFF9CF70 + EAFC321D3CF7905CC8FE803BFFFE9B6CFFFF402F64F900000040000000000000 + 0000000000000000000000000000000000000000000000000000000000122124 + 24C7B1CDD0FF828C8DFE00000066000000180000002B0000002B0000007A4005 + 40E68A0A8BFB9E0C9FFB79097AFB7E097FFAFD13FEF7F430FFF8D872F1FC321C + 3ADE000000210C0912A87859BBFF523D80FD0000005700000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000B131415B90303037800000000000000270000002B04000491980B98FAFE35 + FFF8FE72FFFAFD75FEFAFC40FDF9FC12FDF8F412FEF8D638F7FA3D2246E70000 + 0025000000000000000205040897000000670000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000400000000000000020000002B00000051750875F9FE15FFF7F470 + F5FA874187FC633064FBAE53AEFCF61FFDF8D912FDF955086FFC000000360000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000029040004A3E710E8F9FE18FFF74E25 + 4FE900000036000000130000008A880E9DFBBD12FEFA670CA5FD0000004A0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000001C270328C7FC12FDF8E410E4F90000 + 009200000018000000290000002B310544E2A013FFFB751DD9FD000000770000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000006200520BFFC15FDF8EF11EFF80901 + 09AF0000002B0000002B00000032320653EF8313FFFD7743D2FE000000700000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000007CD23FD2FAFC13FDF8890A + 89F90200029C000000720E0218C76B0FCFFD863EFFFE5C4490FF000000370000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000164F264FEDFC62FDFAF431 + FEF9B315D8FA7C11B6FC9028EFFD9855FFFE976FEAFF161022BF000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000465A2C5BF3D872 + ECFCD67AFFFCC27AFFFDAF79FFFE8864D3FF221935D90000001B000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000260E08 + 11A2402751E9452E60FB2D2044DB020204850000000E00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000FFFE0FFFFFFC07FFFFF803FFFFF001FFFFF0 + 00FFFFF000FFFFF800FFFFF000FFFE60009FFC20000FFC000007FC000003F000 + 0003E000F001C000F0008001E0000003C00080078001800F00078012000FC000 + 001FE000001FE000003FF100067FFF000FFFFF000FFFFF000FFFFF800FFFFF80 + 0FFFFF801FFFFFC01FFFFFE03FFF280000002000000040000000010004000000 + 0000800200000000000000000000000000000000000000000000000080000080 + 000000808000800000008000800080800000C0C0C000808080000000FF0000FF + 000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0000000000000000000000 + 0000000000000000000000000087888888000000000000000000000008777777 + 77800000000000000000000087777FFF7778000000000000000000088F777888 + F777000000000000000000088F7778008F77000000000000000000088F777780 + 08F7000000000000000000088F77777808F7000000000000000000088F777777 + 8877000888000000000000088777777777770087778000000000007FFF777777 + 7778087F77700000000008FFF7777777778087F777700000000008FF77788777 + 78087F7777700000000088F7778088888887F77788800000007F7F7778000000 + 087F77780000000007FFF7778000000087F77778000000008FFF777800000008 + 7F777788000000008FF7778000000087F777788000000000FF7778000000087F + 77788800000007FFF7778000000007F777800000000007FF7778088777777F77 + 77800000000087F77780887777777777788000000000877778088F7777777777 + 880000000000087780088F777F777778000000000000008880088F7887F77778 + 000000000000000000088F78087F7778000000000000000000088F780087F778 + 000000000000000000088F778008F778000000000000000000088F7778887778 + 0000000000000000000088777777778800000000000000000000088777777880 + 00000000000000000000008888888800000000000000FFFE03FFFFFC01FFFFF8 + 00FFFFF0007FFFE0007FFFE0307FFFE0187FFFE00873FFE00061FFC00040FF80 + 0000FF800000FF800000FC000001F801F80FF003F00FF007E00FF00FC01F801F + 803F000001FF000001FF000001FF000003FF820007FFC60007FFFE0807FFFE0C + 07FFFE0607FFFE0007FFFF000FFFFF801FFFFFC03FFF28000000200000004000 + 0000010008000000000080040000000000000000000000000000000000000000 + 0000000080000080000000808000800000008000800080800000C0C0C000C0DC + C000F0CAA60004040400080808000C0C0C0011111100161616001C1C1C002222 + 220029292900555555004D4D4D004242420039393900807CFF005050FF009300 + D600FFECCC00C6D6EF00D6E7E70090A9AD000000330000006600000099000000 + CC00003300000033330000336600003399000033CC000033FF00006600000066 + 330000666600006699000066CC000066FF000099000000993300009966000099 + 99000099CC000099FF0000CC000000CC330000CC660000CC990000CCCC0000CC + FF0000FF660000FF990000FFCC00330000003300330033006600330099003300 + CC003300FF00333300003333330033336600333399003333CC003333FF003366 + 00003366330033666600336699003366CC003366FF0033990000339933003399 + 6600339999003399CC003399FF0033CC000033CC330033CC660033CC990033CC + CC0033CCFF0033FF330033FF660033FF990033FFCC0033FFFF00660000006600 + 330066006600660099006600CC006600FF006633000066333300663366006633 + 99006633CC006633FF00666600006666330066666600666699006666CC006699 + 00006699330066996600669999006699CC006699FF0066CC000066CC330066CC + 990066CCCC0066CCFF0066FF000066FF330066FF990066FFCC00CC00FF00FF00 + CC009999000099339900990099009900CC009900000099333300990066009933 + CC009900FF00996600009966330099336600996699009966CC009933FF009999 + 330099996600999999009999CC009999FF0099CC000099CC330066CC660099CC + 990099CCCC0099CCFF0099FF000099FF330099CC660099FF990099FFCC0099FF + FF00CC00000099003300CC006600CC009900CC00CC0099330000CC333300CC33 + 6600CC339900CC33CC00CC33FF00CC660000CC66330099666600CC669900CC66 + CC009966FF00CC990000CC993300CC996600CC999900CC99CC00CC99FF00CCCC + 0000CCCC3300CCCC6600CCCC9900CCCCCC00CCCCFF00CCFF0000CCFF330099FF + 6600CCFF9900CCFFCC00CCFFFF00CC003300FF006600FF009900CC330000FF33 + 3300FF336600FF339900FF33CC00FF33FF00FF660000FF663300CC666600FF66 + 9900FF66CC00CC66FF00FF990000FF993300FF996600FF999900FF99CC00FF99 + FF00FFCC0000FFCC3300FFCC6600FFCC9900FFCCCC00FFCCFF00FFFF3300CCFF + 6600FFFF9900FFFFCC006666FF0066FF660066FFFF00FF666600FF66FF00FFFF + 66002100A5005F5F5F00777777008686860096969600CBCBCB00B2B2B200D7D7 + D700DDDDDD00E3E3E300EAEAEA00F1F1F100F8F8F800F0FBFF00A4A0A0008080 + 80000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF000000 + 000000000000000000000000000F0C0C0C0C0C0C000000000000000000000000 + 00000000000000000000000012B6ECECEDEDECEB0E0000000000000000000000 + 000000000000000000000012B61A1AF0F3F3BD93EB0E00000000000000000000 + 0000000000000000000012B61A1ABCFFBDBD1ABD93EB0E000000000000000000 + 0000000000000000001292F31A1AB6EAEAEABD1ABD930E000000000000000000 + 00000000000000000012921B1A1AB6EA0000EABD1AB60E000000000000000000 + 00000000000000000012ECF4BC1A1AB6EA0000EAF3B60E000000000000000000 + 00000000000000000012ECF49A9A1A1AB6EA00EAF4B60E0000000E0E00000000 + 0000000000000000001292F31B9A9A1A1AB6EAEA1A930E000013ECEC0E000000 + 0000000000000000436DECBDF19A9A9A1A1A1A1A1A930E0013EFBCEFEC0E0000 + 0000000000000043B6F3F3F61A1ABD9ABC1A1A1A93EB0E13EFF4BCEFEF0E0000 + 000000000000006DF3F6F61AB6B6BCF4F1F11B93EB0E13EFF4BCEF07EF0E0000 + 00000000000000EBF3F61AB6B6EDECF79393F7EB0E13EFF4BCEF07EFEF0E0000 + 00000000111014EBF61AB6B6ED1512121212121213EFF4BCEF07121212000000 + 00000043B6BDF1F61AB6B6ED1500000000000013EFF4BCEF0712000000000000 + 000043B6F3F6F61AB6B6ED1500000000000013EFF4BCEF07EF12000000000000 + 00006DF3F6F61AB6B6ED1500000000000013EFF4BCEF07EFED12000000000000 + 00006DF3F61AB6B6ED1500000000000013EFF4BCEF07EFED1200000000000043 + 4343F3F61AB6B6ED1500000000000013EFF4BCEF0712121200000000000043B6 + F3BDF61AB6B6ED150E0E0E0E0E0E0EEFF4BCEF07EC00000000000000000043BD + F6F61AB6B6ED1513EDEF070707EFEFF4BCEF07EF12000000000000000000121A + F61AB6B6ED1513EDEF070707EF07F1BCEF07EFED1200000000000000000012B6 + 1AB6B6ED1513EDF3BC0707BCEFF707EF07EF1212000000000000000000000012 + B693ED150013EDF307EF07FFBCEFF707EFEC0E00000000000000000000000000 + 121212000013EDF2076D1207FFBCEFF707ED0E00000000000000000000000000 + 000000000013EFBCEF6D001207FFBC0707ED0E00000000000000000000000000 + 000000000013EDF3EF6D00001207F20707ED0E00000000000000000000000000 + 000000000013EDF307EF6D0000ECF30707ED0E00000000000000000000000000 + 000000000013ECF0BC07EF6D6D6D0707EFED0E00000000000000000000000000 + 00000000000013ECEF0707EF070707EFED120000000000000000000000000000 + 0000000000000013ECEFEF0707EFEFED12000000000000000000000000000000 + 000000000000000013131314131212120000000000000000000000000000FFFE + 03FFFFFC01FFFFF800FFFFF0007FFFE0007FFFE0307FFFE0187FFFE00873FFE0 + 0061FFC00040FF800000FF800000FF800000FC000001F801F80FF003F00FF007 + E00FF00FC01F801F803F000001FF000001FF000001FF000003FF820007FFC600 + 07FFFE0807FFFE0C07FFFE0607FFFE0007FFFF000FFFFF801FFFFFC03FFF2800 + 000010000000200000000100040000000000C000000000000000000000000000 + 0000000000000000000000008000008000000080800080000000800080008080 + 0000C0C0C000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF + 0000FFFFFF000000000888800000000000877778000000000087787780000000 + 0087808780800000088778778878000008F777788F7800088F788888F788008F + F780008F7800008F780008F7880088F788888F7800008F788777777800000880 + 8778778000000000878087800000000087787780000000000877780000000000 + 008880000000FE1F0000FC0F0000FC070000FC450000F8000000F8000000E000 + 0000C1C30000C3830000000F0000000F0000901F0000F11F0000F01F0000F83F + 0000FC7F00002800000010000000200000000100080000000000400100000000 + 0000000000000000000000000000000000000000800000800000008080008000 + 00008000800080800000C0C0C000C0DCC000F0CAA60004040400080808000C0C + 0C0011111100161616001C1C1C002222220029292900555555004D4D4D004242 + 420039393900807CFF005050FF009300D600FFECCC00C6D6EF00D6E7E70090A9 + AD000000330000006600000099000000CC000033000000333300003366000033 + 99000033CC000033FF00006600000066330000666600006699000066CC000066 + FF00009900000099330000996600009999000099CC000099FF0000CC000000CC + 330000CC660000CC990000CCCC0000CCFF0000FF660000FF990000FFCC003300 + 00003300330033006600330099003300CC003300FF0033330000333333003333 + 6600333399003333CC003333FF00336600003366330033666600336699003366 + CC003366FF00339900003399330033996600339999003399CC003399FF0033CC + 000033CC330033CC660033CC990033CCCC0033CCFF0033FF330033FF660033FF + 990033FFCC0033FFFF00660000006600330066006600660099006600CC006600 + FF00663300006633330066336600663399006633CC006633FF00666600006666 + 330066666600666699006666CC00669900006699330066996600669999006699 + CC006699FF0066CC000066CC330066CC990066CCCC0066CCFF0066FF000066FF + 330066FF990066FFCC00CC00FF00FF00CC009999000099339900990099009900 + CC009900000099333300990066009933CC009900FF0099660000996633009933 + 6600996699009966CC009933FF009999330099996600999999009999CC009999 + FF0099CC000099CC330066CC660099CC990099CCCC0099CCFF0099FF000099FF + 330099CC660099FF990099FFCC0099FFFF00CC00000099003300CC006600CC00 + 9900CC00CC0099330000CC333300CC336600CC339900CC33CC00CC33FF00CC66 + 0000CC66330099666600CC669900CC66CC009966FF00CC990000CC993300CC99 + 6600CC999900CC99CC00CC99FF00CCCC0000CCCC3300CCCC6600CCCC9900CCCC + CC00CCCCFF00CCFF0000CCFF330099FF6600CCFF9900CCFFCC00CCFFFF00CC00 + 3300FF006600FF009900CC330000FF333300FF336600FF339900FF33CC00FF33 + FF00FF660000FF663300CC666600FF669900FF66CC00CC66FF00FF990000FF99 + 3300FF996600FF999900FF99CC00FF99FF00FFCC0000FFCC3300FFCC6600FFCC + 9900FFCCCC00FFCCFF00FFFF3300CCFF6600FFFF9900FFFFCC006666FF0066FF + 660066FFFF00FF666600FF66FF00FFFF66002100A5005F5F5F00777777008686 + 860096969600CBCBCB00B2B2B200D7D7D700DDDDDD00E3E3E300EAEAEA00F1F1 + F100F8F8F800F0FBFF00A4A0A000808080000000FF0000FF000000FFFF00FF00 + 0000FF00FF00FFFF0000FFFFFF00000000000000001212121200000000000000 + 000000001213BCBDBC1200000000000000000000131AB6131ABC120000000000 + 00000000139A130013F412001300000000000013ECF19A131A1A1213BC130000 + 00000013F6B6BCF11B1313F4EF120000001313F6B61313131313F4EF12120000 + 13F3F6B61300000013F4EF120000000013F6B61300000013F4EF121200001313 + F6B61313131313F4EF120000000013F6B613131307EFF1EFEF12000000000013 + 130013070713F7EF1300000000000000000013EF130013071300000000000000 + 000013070713F307130000000000000000000013070707130000000000000000 + 0000000013131200000000000000FE1F0000FC0F0000FC070000FC450000F800 + 0000F8000000E0000000C1C30000C3830000000F0000000F0000901F0000F11F + 0000F01F0000F83F0000FC7F0000} + OldCreateOrder = False + OnDestroy = FormDestroy + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 12 + object CloseButton: TButton + Left = 147 + Top = 352 + Width = 75 + Height = 25 + Cancel = True + Caption = '閉じる(&C)' + ModalResult = 1 + TabOrder = 0 + OnClick = CloseButtonClick + end + object PageControl: TPageControl + Left = 8 + Top = 8 + Width = 353 + Height = 337 + ActivePage = KeyGenTabSheet + TabOrder = 1 + object KeyGenTabSheet: TTabSheet + Caption = 'キー生成' + object Label1: TLabel + Left = 8 + Top = 8 + Width = 207 + Height = 12 + Caption = '署名を行うためのキー(鍵)を作成します。' + end + object Label2: TLabel + Left = 8 + Top = 24 + Width = 324 + Height = 12 + Caption = '下の「生成する」ボタンを押すと秘密鍵と公開鍵が生成されます。' + end + object Label3: TLabel + Left = 8 + Top = 40 + Width = 289 + Height = 12 + Caption = 'これらはペアの鍵です。両方とも大切に保管してください。' + end + object Label4: TLabel + Left = 12 + Top = 72 + Width = 321 + Height = 17 + Alignment = taCenter + AutoSize = False + Caption = '秘密鍵の方は公開してはいけません' + Color = clRed + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWhite + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + Layout = tlCenter + end + object Label5: TLabel + Left = 8 + Top = 56 + Width = 179 + Height = 12 + Caption = '公開鍵は必要に応じて公開します。' + end + object Label6: TLabel + Left = 8 + Top = 173 + Width = 98 + Height = 12 + Caption = '生成された公開鍵 :' + end + object Label7: TLabel + Left = 8 + Top = 244 + Width = 98 + Height = 12 + Caption = '生成された秘密鍵 :' + end + object Label8: TLabel + Left = 166 + Top = 128 + Width = 12 + Height = 12 + Caption = '↓' + end + object Label9: TLabel + Left = 9 + Top = 296 + Width = 327 + Height = 12 + Caption = '※ ウィンドウを閉じるときにクリップボードの内容はクリアされます' + end + object KeyGeneratingLabel: TLabel + Left = 16 + Top = 128 + Width = 308 + Height = 12 + Caption = 'キーを生成中です .. これにはしばらく時間がかかります' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [fsBold] + ParentFont = False + Visible = False + end + object GenerateButton: TButton + Left = 135 + Top = 96 + Width = 75 + Height = 25 + Caption = '生成する(&G)' + Default = True + TabOrder = 0 + OnClick = GenerateButtonClick + end + object CopyPublicKeyButton: TButton + Left = 264 + Top = 167 + Width = 75 + Height = 25 + Hint = 'クリップボードに公開鍵をコピーします' + Caption = 'コピー(&B)' + Enabled = False + ParentShowHint = False + ShowHint = True + TabOrder = 2 + OnClick = CopyPublicKeyButtonClick + end + object CopyPrivateKeyButton: TButton + Left = 264 + Top = 238 + Width = 75 + Height = 25 + Hint = 'クリップボードに秘密鍵をコピーします' + Caption = 'コピー(&P)' + Enabled = False + ParentShowHint = False + ShowHint = True + TabOrder = 4 + OnClick = CopyPrivateKeyButtonClick + end + object GeneratedPublicKeyEdit: TMemo + Left = 112 + Top = 144 + Width = 145 + Height = 65 + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 1 + end + object GeneratedPrivateKeyEdit: TMemo + Left = 112 + Top = 216 + Width = 145 + Height = 65 + ReadOnly = True + ScrollBars = ssVertical + TabOrder = 3 + end + end + object SignTabSheet: TTabSheet + Caption = '署名' + ImageIndex = 1 + object Label10: TLabel + Left = 8 + Top = 8 + Width = 210 + Height = 12 + Caption = '署名をします。秘密鍵を指定してください。' + end + object Label11: TLabel + Left = 16 + Top = 61 + Width = 57 + Height = 12 + Caption = '秘密鍵(&P) :' + end + object Label12: TLabel + Left = 8 + Top = 120 + Width = 249 + Height = 12 + Caption = '署名を行う対象となるファイルを指定してください。' + end + object Label13: TLabel + Left = 8 + Top = 288 + Width = 274 + Height = 12 + Caption = '現バージョンでは吉里吉里本体にのみ署名可能です。' + Visible = False + end + object Label14: TLabel + Left = 16 + Top = 148 + Width = 86 + Height = 12 + Caption = '対象ファイル(&T) :' + FocusControl = SignFileNameEdit + end + object Label15: TLabel + Left = 8 + Top = 200 + Width = 232 + Height = 12 + Caption = 'ファイルをこのウィンドウにドロップすることでも' + end + object Label16: TLabel + Left = 8 + Top = 216 + Width = 207 + Height = 12 + Caption = '対象ファイルを指定することが出来ます。' + end + object SignDoneLabel: TLabel + Left = 16 + Top = 264 + Width = 96 + Height = 12 + Caption = '署名を行いました。' + Visible = False + end + object SignFileNameEdit: TEdit + Left = 112 + Top = 144 + Width = 217 + Height = 20 + TabOrder = 0 + OnChange = SignPrivateKeyEditChange + end + object SignFileNameRefButton: TButton + Left = 264 + Top = 174 + Width = 67 + Height = 25 + Caption = '参照(&R) ...' + TabOrder = 1 + OnClick = SignFileNameRefButtonClick + end + object SignButton: TButton + Left = 132 + Top = 256 + Width = 82 + Height = 25 + Caption = '署名する(&S)' + Default = True + Enabled = False + TabOrder = 2 + OnClick = SignButtonClick + end + object SignPrivateKeyEdit: TMemo + Left = 88 + Top = 32 + Width = 241 + Height = 65 + TabOrder = 3 + OnChange = SignPrivateKeyEditChange + end + end + object CheckSignTabSheet: TTabSheet + Caption = '署名確認' + ImageIndex = 2 + object SignatureIsValidLabel: TLabel + Left = 0 + Top = 264 + Width = 124 + Height = 12 + Caption = '署名は正当なものです。' + Visible = False + end + object Label18: TLabel + Left = 8 + Top = 216 + Width = 207 + Height = 12 + Caption = '対象ファイルを指定することが出来ます。' + end + object Label19: TLabel + Left = 8 + Top = 200 + Width = 232 + Height = 12 + Caption = 'ファイルをこのウィンドウにドロップすることでも' + end + object Label20: TLabel + Left = 16 + Top = 148 + Width = 86 + Height = 12 + Caption = '対象ファイル(&T) :' + FocusControl = CheckSignFileNameEdit + end + object Label21: TLabel + Left = 8 + Top = 280 + Width = 274 + Height = 12 + Caption = '現バージョンでは吉里吉里本体にのみ署名可能です。' + Visible = False + end + object Label22: TLabel + Left = 8 + Top = 120 + Width = 290 + Height = 12 + Caption = '署名をチェックする対象となるファイルを指定してください。' + end + object Label23: TLabel + Left = 16 + Top = 61 + Width = 57 + Height = 12 + Caption = '公開鍵(&P) :' + end + object Label24: TLabel + Left = 8 + Top = 8 + Width = 234 + Height = 12 + Caption = '署名を確認します。公開鍵を指定してください。' + end + object SignatureIsInvalidLabel: TLabel + Left = 16 + Top = 296 + Width = 169 + Height = 12 + Caption = '署名は正当な物ではありません。' + Visible = False + end + object CheckSignatureButton: TButton + Left = 132 + Top = 256 + Width = 82 + Height = 25 + Caption = 'チェック(&S)' + Default = True + Enabled = False + TabOrder = 2 + OnClick = CheckSignatureButtonClick + end + object CheckSignFileNameRefButton: TButton + Left = 264 + Top = 174 + Width = 67 + Height = 25 + Caption = '参照(&R) ...' + TabOrder = 1 + OnClick = CheckSignFileNameRefButtonClick + end + object CheckSignFileNameEdit: TEdit + Left = 112 + Top = 144 + Width = 217 + Height = 20 + TabOrder = 0 + OnChange = CheckSignPublicKeyEditChange + end + object CheckSignPublicKeyEdit: TMemo + Left = 88 + Top = 32 + Width = 241 + Height = 65 + TabOrder = 3 + OnChange = CheckSignPublicKeyEditChange + end + end + end + object OpenDialog: TOpenDialog + Left = 268 + Top = 263 + end +end diff --git a/tools/win32/krdevui/SignMainFormUnit.h b/tools/win32/krdevui/SignMainFormUnit.h new file mode 100644 index 0000000..57a85a6 --- /dev/null +++ b/tools/win32/krdevui/SignMainFormUnit.h @@ -0,0 +1,87 @@ +//--------------------------------------------------------------------------- + +#ifndef MainFormUnitH +#define MainFormUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TSignMainForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TButton *CloseButton; + TPageControl *PageControl; + TTabSheet *KeyGenTabSheet; + TLabel *Label1; + TLabel *Label2; + TLabel *Label3; + TLabel *Label4; + TLabel *Label5; + TButton *GenerateButton; + TLabel *Label6; + TLabel *Label7; + TLabel *Label8; + TButton *CopyPublicKeyButton; + TButton *CopyPrivateKeyButton; + TLabel *Label9; + TTabSheet *SignTabSheet; + TLabel *Label10; + TLabel *Label11; + TLabel *Label12; + TLabel *Label13; + TEdit *SignFileNameEdit; + TLabel *Label14; + TButton *SignFileNameRefButton; + TLabel *Label15; + TLabel *Label16; + TButton *SignButton; + TOpenDialog *OpenDialog; + TLabel *SignDoneLabel; + TTabSheet *CheckSignTabSheet; + TLabel *SignatureIsValidLabel; + TButton *CheckSignatureButton; + TLabel *Label18; + TLabel *Label19; + TButton *CheckSignFileNameRefButton; + TEdit *CheckSignFileNameEdit; + TLabel *Label20; + TLabel *Label21; + TLabel *Label22; + TLabel *Label23; + TLabel *Label24; + TLabel *SignatureIsInvalidLabel; + TMemo *GeneratedPublicKeyEdit; + TMemo *GeneratedPrivateKeyEdit; + TLabel *KeyGeneratingLabel; + TMemo *SignPrivateKeyEdit; + TMemo *CheckSignPublicKeyEdit; + void __fastcall GenerateButtonClick(TObject *Sender); + void __fastcall CloseButtonClick(TObject *Sender); + void __fastcall CopyPublicKeyButtonClick(TObject *Sender); + void __fastcall CopyPrivateKeyButtonClick(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall SignFileNameRefButtonClick(TObject *Sender); + void __fastcall SignButtonClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall CheckSignFileNameRefButtonClick(TObject *Sender); + void __fastcall CheckSignatureButtonClick(TObject *Sender); + void __fastcall SignPrivateKeyEditChange(TObject *Sender); + void __fastcall CheckSignPublicKeyEditChange(TObject *Sender); +private: // ユーザー宣言 +protected: +BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER( WM_DROPFILES, TMessage, WMDropFiles); +END_MESSAGE_MAP(TForm) + void __fastcall WMDropFiles(TMessage &Msg); + +public: // ユーザー宣言 + __fastcall TSignMainForm(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TSignMainForm *SignMainForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/SignUnit.cpp b/tools/win32/krdevui/SignUnit.cpp new file mode 100644 index 0000000..c57c839 --- /dev/null +++ b/tools/win32/krdevui/SignUnit.cpp @@ -0,0 +1,289 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "SignUnit.h" +#include "RandomizeFormUnit.h" + +#define _MSC_VER +#include +#undef _MSC_VER + + +#include + +#define HASH_INIT sha256_init +#define HASH_PROCESS sha256_process +#define HASH_DONE sha256_done +#define HASH_DESC sha256_desc +#define HASH_METHOD_STRING "SHA256" +#define HASH_METHOD_INTERNAL_STRING "sha256" +#define HASH_SIZE 32 + +//--------------------------------------------------------------------------- +AnsiString Split64(AnsiString s) +{ + // split s in 64characters intervally + int len = s.Length(); + const char * p = s.c_str(); + AnsiString ret; + while(len > 0) + { + int one_size = len > 64 ? 64 : len; + ret += AnsiString(p, one_size) + "\r\n"; + p += one_size; + len -= one_size; + } + return ret; +} +//--------------------------------------------------------------------------- +static void MakeFileHash(AnsiString fn, unsigned char *hash, int ignorestart, + int ignoreend) +{ + if(find_hash(HASH_METHOD_INTERNAL_STRING) == -1) + { + int errnum = register_hash(&HASH_DESC); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + } + + + TFileStream *fs; + fs = new TFileStream(fn, fmOpenRead | fmShareDenyWrite); + if(ignorestart != -1 && ignoreend == -1) ignoreend = fs->Size; + try + { + hash_state st; + HASH_INIT(&st); + + int read; + unsigned char buf[4096]; + int ofs = 0; + while((read = fs->Read(buf, sizeof(buf))) != 0) + { + if(ignorestart != -1 && read + ofs > ignorestart) + { + read = ignorestart - ofs; + if(read) HASH_PROCESS(&st, buf, read); + break; + } + else + { + HASH_PROCESS(&st, buf, read); + } + ofs += read; + } + + if(ignorestart != -1 && fs->Position != ignoreend) + { + fs->Position = ofs = ignoreend; + + while((read = fs->Read(buf, sizeof(buf))) != 0) + { + HASH_PROCESS(&st, buf, read); + ofs += read; + } + } + + HASH_DONE(&st, hash); + } + catch(...) + { + delete fs; + throw; + } + delete fs; +} +//--------------------------------------------------------------------------- +static void ImportKey(AnsiString inkey, AnsiString startline, AnsiString endline, + rsa_key * key) +{ + const char *pkey = inkey.c_str(); + const char *start = strstr(pkey, startline.c_str()); + if(!start) throw Exception("Cannot find \"" + startline + "\" in the key string"); + const char *end = strstr(pkey, endline.c_str()); + if(!end) throw Exception("Cannot find \"" + endline + "\" in the key string"); + + start += startline.Length(); + char buf[10240]; + unsigned long buf_len; + int errnum; + + buf_len = sizeof(buf) - 1; + errnum = base64_decode((const unsigned char*)(start), + end - start, buf, &buf_len); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + + errnum = rsa_import(buf, buf_len, key); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); +} +//--------------------------------------------------------------------------- +bool SignFile(AnsiString privkey, AnsiString signfn, int ignorestart, int ignoreend, int ofs) +{ + // ofs is -1 : for separeted sinature file (.sig) . + // otherwise the sign is embedded to the target file. + + // sign file + if(privkey == "") throw Exception("Specify private key"); + if(signfn == "") throw Exception("Specify target file"); + + // read privkey + rsa_key key; + int errnum; + + ImportKey(privkey, "-----BEGIN RSA PRIVATE KEY-----", "-----END RSA PRIVATE KEY-----", + &key); + + try + { + char buf[10240]; + unsigned long buf_len; + + // initialize random number generator + prng_state prng; + if(!RandomizePRNGSimple(&prng)) return false; + + // make target hash + unsigned char hash[HASH_SIZE]; + MakeFileHash(signfn, hash, ignorestart, ignoreend); + + // sign + buf_len = sizeof(buf) - 1; + errnum = rsa_sign_hash(hash, HASH_SIZE, buf, &buf_len, + &prng, find_prng("fortuna"), + find_hash(HASH_METHOD_INTERNAL_STRING), HASH_SIZE, + &key); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + + // convert to readable text + char buf_asc[10240*3/2+2]; + unsigned long buf_asc_len; + buf_asc_len = sizeof(buf_asc) - 1; + errnum = base64_encode(buf, buf_len, buf_asc, &buf_asc_len); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + buf_asc[buf_asc_len] = 0; + + AnsiString sign = AnsiString("-- SIGNATURE - " HASH_METHOD_STRING "/PSS/RSA --\r\n") + + Split64(buf_asc); + + // write it to the file + TFileStream * st; + + if(ofs == -1) + { + // separated + st = new TFileStream(signfn + ".sig", fmCreate|fmShareDenyWrite); + } + else + { + // embedded + st = new TFileStream(signfn, fmOpenReadWrite|fmShareDenyWrite); + st->Position = ofs; + } + + try + { + st->Write(sign.c_str(), sign.Length()); + if(ofs != -1) + { + // write a null terminater + st->Write("\0", 1); + } + } + catch(...) + { + delete st; + throw; + } + delete st; + } + catch(...) + { + rsa_free(&key); + throw; + } + rsa_free(&key); + + return true; +} +//--------------------------------------------------------------------------- +bool CheckSignatureOfFile(AnsiString pubkey, AnsiString signfn, + int ignorestart, int ignoreend, int ofs) +{ + // check signature of the file + if(pubkey == "") throw Exception("Specify public key"); + if(signfn == "") throw Exception("Specify target file"); + + // read pubkey + char buf[10240]; + unsigned long buf_len; + char buf_asc[sizeof(buf)*3/2+2]; + unsigned long buf_asc_len; + + rsa_key key; + + ImportKey(pubkey, "-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----", + &key); + + // read signature file + + TFileStream *st; + if(ofs == -1) + { + // separated + st = new TFileStream(signfn + ".sig", fmOpenRead|fmShareDenyWrite); + } + else + { + // embedded + st = new TFileStream(signfn, fmOpenReadWrite|fmShareDenyWrite); + st->Position = ofs; + } + try + { + buf_asc_len = st->Read(buf_asc, sizeof(buf_asc) - 1); + } + catch(...) + { + delete st; + throw; + } + delete st; + + buf_asc[buf_asc_len] = 0; + buf_asc_len = strlen(buf_asc); + + AnsiString signmark("-- SIGNATURE - " HASH_METHOD_STRING "/PSS/RSA --"); + if(strncmp(buf_asc, signmark.c_str(), signmark.Length())) + throw Exception("Invalid signature file format"); + + buf_len = sizeof(buf) - 1; + int errnum = base64_decode((const unsigned char*)(buf_asc + signmark.Length()), + buf_asc_len - signmark.Length(), buf, &buf_len); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + + int stat = 0; + try + { + // make target hash + unsigned char hash[HASH_SIZE]; + MakeFileHash(signfn, hash, ignorestart, ignoreend); + + // check signature + errnum = rsa_verify_hash(buf, buf_len, hash, HASH_SIZE, + find_hash(HASH_METHOD_INTERNAL_STRING), HASH_SIZE, + &stat, &key); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + } + catch(...) + { + rsa_free(&key); + throw; + } + rsa_free(&key); + + return stat; +} +//--------------------------------------------------------------------------- + +#pragma package(smart_init) diff --git a/tools/win32/krdevui/SignUnit.h b/tools/win32/krdevui/SignUnit.h new file mode 100644 index 0000000..708c8ce --- /dev/null +++ b/tools/win32/krdevui/SignUnit.h @@ -0,0 +1,12 @@ +//--------------------------------------------------------------------------- + +#ifndef SignUnitH +#define SignUnitH +//--------------------------------------------------------------------------- +extern AnsiString Split64(AnsiString s); +extern bool SignFile(AnsiString privkey, AnsiString signfn, int ignorestart, int ignoreend, int ofs); +extern bool CheckSignatureOfFile(AnsiString pubkey, AnsiString signfn, int ignorestart, int ignoreend, int ofs); +//--------------------------------------------------------------------------- + + +#endif diff --git a/tools/win32/krdevui/intermediate/dummy.txt b/tools/win32/krdevui/intermediate/dummy.txt new file mode 100644 index 0000000..1e1b037 --- /dev/null +++ b/tools/win32/krdevui/intermediate/dummy.txt @@ -0,0 +1 @@ +このファイルは消していいですよ \ No newline at end of file diff --git a/tools/win32/krdevui/krdevui.bpf b/tools/win32/krdevui/krdevui.bpf new file mode 100644 index 0000000..b00ec72 --- /dev/null +++ b/tools/win32/krdevui/krdevui.bpf @@ -0,0 +1,50 @@ +USEFORM("FolderSelectorUnit.cpp", FolderSelectorForm); +USEFORM("ConfSettingsUnit.cpp", ConfSettingsForm); +USEFORM("ConfMainFrameUnit.cpp", ConfMainFrame); /* TFrame: File Type */ +USEFORM("RelFolderSelectorUnit.cpp", RelFolderSelectorForm); +USEFORM("RelSettingsUnit.cpp", RelSettingsForm); +USEFORM("RelDirSearchUnit.cpp", RelDirSearchForm); +USEFORM("FontMakerUnit.cpp", FontMakerForm); +USEFORM("FontMakerWriteUnit.cpp", FontMakerWriteForm); +USEFORM("FontPreviewUnit.cpp", FontPreviewForm); +USEUNIT("RelMain.cpp"); +USEUNIT("ConfMain.cpp"); +USEUNIT("MainUnit.cpp"); +USEFORM("tpc\ProgressUnit.cpp", ProgressForm); +USEFORM("tpc\TPCMainUnit.cpp", TPCMainForm); +USEFORM("tpc\JPEGQualityUnit.cpp", JPEGQualityForm); +USEFORM("tpc\LogViewerUnit.cpp", LogViewerForm); +USEUNIT("tpc\png\DeePNGUnit.cpp"); +USEUNIT("tpc\psd\DeePSDUnit.cpp"); +USEUNIT("tpc\tlg5\slide.cpp"); +USEUNIT("tpc\tlg5\TLG5Saver.cpp"); +USERES("krdevui.res"); +USELIB("..\..\..\..\..\Lib\zlib.lib"); +USELIB("..\..\..\..\..\Lib\deelibpng.lib"); +USEUNIT("SignUnit.cpp"); +USEUNIT("KrkrExecutableUnit.cpp"); +USEFORM("RandomizeFormUnit.cpp", RandomizeForm); +USEFORM("SignMainFormUnit.cpp", SignMainForm); +USEUNIT("tpc\tlg6\TLG6Saver.cpp"); +USEUNIT("tpc\tlg6\GolombTable.cpp"); +USEUNIT("tpc\TLGMetaInfo.cpp"); +USEUNIT("looptuner2\DSound.cpp"); +USEFORM("looptuner2\EditLabelAttribUnit.cpp", EditLabelAttribFrame); /* TFrame: File Type */ +USEFORM("looptuner2\EditLinkAttribUnit.cpp", EditLinkAttribFrame); /* TFrame: File Type */ +USEFORM("looptuner2\LabelDetailUnit.cpp", LabelDetailForm); +USEFORM("looptuner2\LinkDetailUnit.cpp", LinkDetailForm); +USEUNIT("looptuner2\looptune.cpp"); +USEFORM("looptuner2\LoopTunerMainUnit.cpp", TSSLoopTuner2MainForm); +USEUNIT("looptuner2\RIFFWaveContext.cpp"); +USEUNIT("looptuner2\TSSWaveContext.cpp"); +USEUNIT("looptuner2\WaveReader.cpp"); +USEUNIT("looptuner2\WaveView.cpp"); +USEUNIT("..\..\..\core\base\CharacterSet.cpp"); +USEUNIT("..\..\..\core\sound\win32\tvpsnd.c"); +USELIB("..\..\..\..\..\..\..\Lib\libtomcrypt1.lib"); +USEUNIT("looptuner2\TotalView.cpp"); +USEUNIT("looptuner2\WaveLoopManager.cpp"); +//--------------------------------------------------------------------------- +This file is used by the project manager only and should be treated like the project file + + DllEntryPoint \ No newline at end of file diff --git a/tools/win32/krdevui/krdevui.bpr b/tools/win32/krdevui/krdevui.bpr new file mode 100644 index 0000000..1aea2ae --- /dev/null +++ b/tools/win32/krdevui/krdevui.bpr @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=1 +MajorVer=1 +MinorVer=4 +Release=6 +Build=84 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1041 +CodePage=932 + +[Version Info Keys] +CompanyName= +FileDescription=TVP Development User Interface DLL +FileVersion=1.4.6.84 +InternalName= +LegalCopyright=(C)2001-2009, W.Dee All rights reserved. +LegalTrademarks= +OriginalFilename=krdevui.dll +ProductName= +ProductVersion=1.0.0.0 +Comments=TVP(krkr.eXe) needs this DLL in some developing-phase occasions. + +[Excluded Packages] +$(BCB)\Bin\dcl31w50.bpl=Delphi 1.0 Compatibility Components +$(BCB)\Bin\bcbsmp50.bpl=Borland C++ Sample Components +$(BCB)\Bin\dclqrt50.bpl=QuickReport Components +$(BCB)\Bin\dclbde50.bpl=Borland BDE DB Components +$(BCB)\Bin\dcldb50.bpl=Borland Database Components +$(BCB)\Bin\dcltee50.bpl=TeeChart 5.0 Components +$(BCB)\Bin\dcltqr50.bpl=TeeChart 5.0 for QuickReport Components Design Package +$(BCB)\Bin\dclib50.bpl=InterBase Data Access Components +$(BCB)\Bin\bcbie50.bpl=Borland C++Builder Internet Explorer 5 Components Package +$(BCB)\Bin\dclnet50.bpl=Borland Internet Components +$(BCB)\Bin\DBWEBXPRT.BPL=Borland Web Wizard Package +$(BCB)\Bin\DCLNMF50.bpl=NetMasters Fastnet Tools +$(BCB)\Bin\dclocx50.bpl=Borland Sample Imported ActiveX Controls +$(BCB)\Bin\bcb2kaxserver50.bpl=Borland C++Builder COM Server Components Sample Package +$(BCB)\Bin\dclite50.bpl=Borland Integrated Translation Environment + +[HistoryLists\hlIncludePath] +Count=17 +Item0=..\..\..\core\sound\win32;$(BCB)\include\tomcrypt1;$(BCB)\include\vcl;$(BCB)\projects\comps\o\shlib;$(BCB)\include;..\..\..\core\sound;..\..\..\core\base;looptuner2;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\..\..\..\..\Bin;..\..\..\..;..\..\..\core\tjs2 +Item1=$(BCB)\include\tomcrypt1;$(BCB)\include\vcl;$(BCB)\projects\comps\o\shlib;$(BCB)\include;..\..\..\core\sound;..\..\..\core\base;looptuner2;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\..\..\..\..\Bin;..\..\..\..;..\..\..\core\tjs2 +Item2=$(BCB)\include\tomcrypt1;$(BCB)\include\vcl;$(BCB)\projects\comps\o\shlib;$(BCB)\include;..\..\..\core\sound;..\..\..\core\base;looptuner2;..\..\..\sound\win32;..\..\..\core\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\..\..\..\..\Bin;..\..\..\..;..\..\..\core\tjs2 +Item3=$(BCB)\include\tomcrypt;$(BCB)\include\vcl;$(BCB)\projects\comps\o\shlib;$(BCB)\include;..\..\..\core\sound;..\..\..\core\base;looptuner2;..\..\..\sound\win32;..\..\..\core\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\..\..\..\..\Bin;..\..\..\..;..\..\..\core\tjs2 +Item4=..\..\..\core\sound;..\..\..\core\base;looptuner2;..\..\..\sound\win32;..\..\..\core\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\include\tomcrypt;..\..\..\core\tjs2 +Item5=..\..\..\core\sound;..\..\..\core\base;looptuner2;..\..\..\sound\win32;..\..\..\core\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\include\tomcrypt;..\..\..\core\tjs +Item6=..\..\..\core\sound;..\..\..\core\base;looptuner2;..\..\..\sound\win32;..\..\..\core\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\include\tomcrypt +Item7=..\..\..\sound\win32;..\..\..\core\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\include\tomcrypt +Item8=..\..\..\core\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\include\tomcrypt +Item9=..\..\..\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\include\tomcrypt +Item10=tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\include\tomcrypt +Item11=tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl +Item12=..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl +Item13=..\..\..\..\..\Bin;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl +Item14=$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl +Item15=;;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\include;$(BCB)\include\vcl +Item16=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=9 +Item0=..\..\..\core\sound;..\..\..\core\base;looptuner2;..\..\..\core\sound\win32;..\..\..\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\Projects\Lib;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\lib\obj;$(BCB)\lib +Item1=..\..\..\core\sound\win32;..\..\..\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\Projects\Lib;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\lib\obj;$(BCB)\lib +Item2=..\..\..\sound\win32;looptune;tpc\tlg6;tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\Projects\Lib;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\lib\obj;$(BCB)\lib +Item3=tpc\tlg5;tpc\psd;tpc\png;tpc;..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\Projects\Lib;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\lib\obj;$(BCB)\lib +Item4=..\fgconvert\psd;..\fgconvert\png;..\..\..\..\..\Bin;$(BCB)\Projects\Lib;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\lib\obj;$(BCB)\lib +Item5=..\..\..\..\..\Bin;$(BCB)\Projects\Lib;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\lib\obj;$(BCB)\lib +Item6=$(BCB)\Projects\Lib;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\lib\obj;$(BCB)\lib +Item7=;;$(BCB)\Projects\Lib;$(BCB)\projects\comps\o\shlib;..\..\..\..;$(BCB)\lib\obj;$(BCB)\lib +Item8=$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=7 +Item0=NO_WIN32_LEAN_AND_MEAN;TVP_IN_LOOP_TUNER +Item1=NO_WIN32_LEAN_AND_MEAN;TVP_IN_LOOP_TUNER;_DEBUG +Item2=NO_WIN32_LEAN_AND_MEAN;TVP_IN_LOOP_TUNER;_MSC_VER +Item3=NO_WIN32_LEAN_AND_MEAN +Item4=NO_WIN32_LEAN_AND_MEAN;_DEBUG +Item5=_DEBUG;NO_WIN32_LEAN_AND_MEAN +Item6=_DEBUG + +[HistoryLists\hlIntOutputDir] +Count=2 +Item0=intermediate +Item1=c:\Program Files\Borland\CBuilder5\Projects\tvp2win32\environ\win32\krdevui\intermediate + +[HistoryLists\hlFinalOutputDir] +Count=4 +Item0=..\..\..\..\bin\win32\tools\ +Item1=..\..\..\..\bin\win32\tools +Item2=c:\Program Files\Borland\CBuilder5\Projects\tvp2win32\environ\win32\ +Item3=c:\Program Files\Borland\CBuilder5\Projects\tvp2win32\environ\win32 + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication=C:\Program Files\Borland\CBuilder5\Projects\tvp2win32\kirikiri2\bin\win32\tools\krkrrel.exe +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + + \ No newline at end of file diff --git a/tools/win32/krdevui/krdevui.res b/tools/win32/krdevui/krdevui.res new file mode 100644 index 0000000000000000000000000000000000000000..775108e59a5393e636ad768c4cb3d42a3cd49fbd GIT binary patch literal 1836 zcmb7DOHUI~6#hylRuiKoac`q8z$huc!VZWdGei_3i0(*(r4s72X$uoqy^EVL2`1gU zV&Q+N8&YeeRki>Xq&fIh6JMVih0943f7%{~h{hUbfB5eu=E0-s& z#Au2_g}gv6ApT9Ci%9`|p;WZ+OOdQF8jT1@5we8Q!f#Ypi2f(iKp&BQ`^s1SfHZKQ z4~N4bI0;TNIMEb$zYZOuDXx#Slfzxd&f$UM9Qu6X_^xX^CSU2)TfYX`jdKJWl%@F7X{V<1g`58eePryBOoHwzZ-j*ROS8 z6VBkuA`CO&fhH+Sfg}SMxFlsMs{etDb=E)DqxosAVm&nRgCN#RKBpK2tSrI--}ixb zqWxo)C>btNzKBcwf1P}jJg+d(AN|F}aD*}cpnQsccmqI{9ER8M0*hG2OY&2!a!n|E zFXT29P^py7t&m$(z;O}rT`OOBmyU~%7-|#i*y8sYUQt>$8MaKmCCWnItY2r*Z7bk4 zF2Q1KS?3K3>VoF!%-qR!^w7aBJT$PxwTU_-d)PsX=HHD?6^}5>r;3N{Q!2W}Xa)A# z!Uyh0jrJeeb&Xm*P2%A;ZIYNakuJ7Pt~PV-($_P#8|-Y2QxJ;-a+65gMDl1?VIN)o z?NE}sdPd%1u5C)9O7SpVt%4Zh$V`&ceSm7JylisA-MMiIO9s72TCbN+qrT=%d z7rM)=*}NOXYeeguO^xy%eG*#0Robq`ab-89k7V|uMLV-c3yE-meO5n1S?WplbB$<= z|MofC-nl7&v%Ab3d7JZ7mKj%520pXnqmH-aX->oADpQcj z^f=#LBSrgMq2}>_mvu_KO59CyY6NX?{%!izXeAaccC&4?=*)GQO~^LiO(LCiQgRZa XlMmc6w5TX3y=U^`-a+#k!p% literal 0 HcmV?d00001 diff --git a/tools/win32/krdevui/looptuner2/ColorScheme.h b/tools/win32/krdevui/looptuner2/ColorScheme.h new file mode 100644 index 0000000..a5e3ae3 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/ColorScheme.h @@ -0,0 +1,67 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef __COLORSCHEME_H__ +#define __COLORSCHEME_H__ + +//--------------------------------------------------------------------------- +#define BYTEOF(x, b) (((x) >> ((b)*8)) & 0xff) +#define COLOR_BLEND_8(x, y, ratio) (((x) * (ratio) + (y) * (100-(ratio))) / 100) +#define BLEND_ARGB(x, y, ratio) (\ + (COLOR_BLEND_8(BYTEOF(x, 0), BYTEOF(y, 0), (ratio)) )+ \ + (COLOR_BLEND_8(BYTEOF(x, 1), BYTEOF(y, 1), (ratio))<<8 )+ \ + (COLOR_BLEND_8(BYTEOF(x, 2), BYTEOF(y, 2), (ratio))<<16)+ \ + (COLOR_BLEND_8(BYTEOF(x, 3), BYTEOF(y, 3), (ratio))<<24) ) + +//--------------------------------------------------------------------------- +// Color schemes - currently fixed colors only +//--------------------------------------------------------------------------- +static const TColor C_DISABLEED_CLIENT = clBtnFace; +static const TColor C_CLIENT = ((TColor)0xffffff); +static const TColor C_WAVE = ((TColor)0x000000); +static const TColor C_INF_LINE = ((TColor)0x808080); +static const TColor C_DISABLED_TIME_CLIENT = ((TColor)0xf0f0f0); + +static const TColor C_WAVE_B_FG_BASE = ((TColor)0x800000); +static const TColor C_WAVE_B_BG = ((TColor)0xd0d0e0); +static const TColor C_WAVE_B_FG = ((TColor)BLEND_ARGB(C_WAVE_B_FG_BASE, 0xffffff, 60)); +static const TColor C_WAVE_B_FG_BG = ((TColor)BLEND_ARGB(C_WAVE_B_FG_BASE, 0xe0d0d0, 80)); +static const TColor C_WAVE_A_FG_BASE = ((TColor)0x000080); +static const TColor C_WAVE_A_BG = ((TColor)0xe0d0d0); +static const TColor C_WAVE_A_FG = ((TColor)BLEND_ARGB(C_WAVE_A_FG_BASE, 0xffffff, 60)); +static const TColor C_WAVE_A_FG_BG = ((TColor)BLEND_ARGB(C_WAVE_A_FG_BASE, 0xd0d0e0, 80)); + +static const TColor C_WAVE_CENTER_SPLIT = ((TColor)0xc0c0c0); + +static const TColor C_TIME_CLIENT = clBtnFace; +static const TColor C_TIME_COLOR = ((TColor)0x303030); +static const TColor C_LINK_WAVE_MARK = ((TColor)0x0000f0); +static const TColor C_LINK_CLIENT = clWhite; +static const TColor C_LINK_SEPARETOR = ((TColor)0xe0e0e0); +static const TColor C_LINK_LINE = clBlack; +static const TColor C_LINK_HOVER = ((TColor)0x40d090); +static const TColor C_LINK_FOCUS = clRed; +static const TColor C_LINK_WEAK_LINE = clGray; + +static const TColor C_LABEL_WAVE_MARK = ((TColor)0x00f000); +static const TColor C_LABEL_MARK_LINE = clBlack; +static const TColor C_LABEL_MARK_HOVER = ((TColor)0x40d090); +static const TColor C_LABEL_MARK_FOCUS = clRed; +static const TColor C_LABEL_MARK = clYellow; +static const TColor C_LABEL_TEXT_BG = clWhite; +static const TColor C_LABEL_TEXT = ((TColor)0x000080); +static const TColor C_LABEL_TEXT_HOVER = ((TColor)0x008080); +static const TColor C_LABEL_TEXT_FOCUS = ((TColor)0x0000ff); + +static const TColor C_WAVETHUMB_LINKS = ((TColor)0x8080ff); +static const TColor C_WAVETHUMB_LABELS = ((TColor)0x00a000); + +//--------------------------------------------------------------------------- + +#endif + diff --git a/tools/win32/krdevui/looptuner2/DSound.cpp b/tools/win32/krdevui/looptuner2/DSound.cpp new file mode 100644 index 0000000..c500895 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/DSound.cpp @@ -0,0 +1,450 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include + +#define DIRECTSOUND_VERSION 0x0300 +#include +#include + + +#include +#include +#include + +#include "DSound.h" +#include "WaveLoopManager.h" + +//--------------------------------------------------------------------------- +static void __fastcall ResetSoundBuffer(); +static void __fastcall FillSecondaryBuffer(void); +//--------------------------------------------------------------------------- +static TCriticalSection *WriteLock = NULL; +class TBufferWriteLock // ロック用クラス +{ +public: + __fastcall TBufferWriteLock(void) { if(WriteLock) WriteLock->Enter(); }; + __fastcall ~TBufferWriteLock(void) { if(WriteLock) WriteLock->Leave(); }; +}; +//--------------------------------------------------------------------------- +class TPlayerThread : public TThread +{ +public: + __fastcall TPlayerThread(void) : TThread(true) + { + Priority = tpHigher; + Suspended = false; + } + + __fastcall ~TPlayerThread(void) + { + Suspended = false; + Terminate(); + WaitFor(); + } + + void __fastcall Execute(void) + { + while(!Terminated) + { + FillSecondaryBuffer(); + Sleep(50); + } + } + +} ; +//--------------------------------------------------------------------------- +static HRESULT WINAPI (* procDirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN)=NULL; +static HMODULE DirectSoundDLLHandle=NULL; +static IDirectSound * Sound = NULL; +static IDirectSoundBuffer * SoundPrimaryBuffer = NULL; +static IDirectSoundBuffer * SoundBuffer = NULL; +static DWORD SoundBufferBytes; +static DWORD SoundBufferBytesHalf; +static DSBUFFERDESC SoundBufferDesc; +static int Frequency; +static int Channels; +static int SampleSize; +static bool DecodeEnded; +static int BufferRemainBlock; +static DWORD SoundBufferWritePos; +static bool FirstWrite; +static bool Playing = false; +static tTVPWaveLoopManager * Manager = NULL; +static TPlayerThread *PlayerThread = NULL; +static std::vector Segments[2]; +static std::vector Labels[2]; +//--------------------------------------------------------------------------- +void __fastcall InitDirectSound(HWND wnd) +{ + if(!Sound) + { + // DLL のロード + + if(DirectSoundDLLHandle==NULL) + { + DirectSoundDLLHandle = LoadLibrary("dsound.dll"); + if(!DirectSoundDLLHandle) throw Exception("dsound.dll をロードできません"); + } + + if(procDirectSoundCreate==NULL) + { + procDirectSoundCreate = (HRESULT (WINAPI*)(_GUID *,IDirectSound **,IUnknown*)) + GetProcAddress(DirectSoundDLLHandle,"DirectSoundCreate"); + if(!procDirectSoundCreate) + { + FreeLibrary(DirectSoundDLLHandle); + DirectSoundDLLHandle=NULL; + throw Exception("dsound.dll が異常です"); + } + } + // オブジェクト作成 + HRESULT hr; + hr=procDirectSoundCreate(NULL,&Sound,NULL); + if(FAILED(hr)) + { + throw Exception( + AnsiString("DirectSound を初期化できません(他でWaveを再生中?)/HRESULT:")+ + IntToHex((int)hr,8)); + // 作成に失敗 他に WAVE output が使われていた場合など、 + // こうなる + } + + // 協調レベルの設定 + hr=Sound->SetCooperativeLevel(wnd, DSSCL_PRIORITY); + if(FAILED(hr)) + { + Sound->Release(); // サウンドオブジェクトをリリース + Sound=NULL; + throw Exception(AnsiString("DirectSound の協調レベルの設定に失敗しました(phase1)/HRESULT:")+ + IntToHex((int)hr,8)); + } + +//-- + // プライマリバッファの作成 + + SoundPrimaryBuffer= NULL; // 別に作成できなきゃそれでもいい + + ZeroMemory(&SoundBufferDesc,sizeof(DSBUFFERDESC)); + SoundBufferDesc.dwSize=sizeof(DSBUFFERDESC); + SoundBufferDesc.dwFlags=DSBCAPS_PRIMARYBUFFER; + hr=Sound->CreateSoundBuffer(&SoundBufferDesc, + &SoundPrimaryBuffer,NULL); + + if(FAILED(hr) || SoundPrimaryBuffer == NULL) + { + // DbgMsgAdd("警告:DirectSound プライマリバッファを作成できません"); + hr=Sound->SetCooperativeLevel(wnd, DSSCL_NORMAL); + if(FAILED(hr)) + { + Sound->Release(); // サウンドオブジェクトをリリース + Sound = NULL; + throw Exception(AnsiString("DirectSound の協調レベルの設定に失敗しました(phase2)/HRESULT:")+ + IntToHex((int)hr,8)); + } + } + + + if(SoundPrimaryBuffer) + { + WAVEFORMATEX wfx; + wfx.cbSize=0; + wfx.wFormatTag=WAVE_FORMAT_PCM; + wfx.nChannels=2; + wfx.nSamplesPerSec=44100; + wfx.wBitsPerSample=16; + wfx.nBlockAlign=(WORD)(wfx.wBitsPerSample/8*wfx.nChannels); + wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign; + SoundPrimaryBuffer->SetFormat(&wfx); + } + if(!WriteLock) WriteLock = new TCriticalSection; + + if(!PlayerThread) + PlayerThread= new TPlayerThread(); + } +} +//--------------------------------------------------------------------------- +void __fastcall FreeDirectSound(void) +{ + // サウンドバッファの破棄 + if(PlayerThread) + { + delete PlayerThread; + } + + if(SoundBuffer) + { + SoundBuffer->Release(); + SoundBuffer = NULL; + } + + if(Sound) + { + if(SoundPrimaryBuffer) SoundPrimaryBuffer->Release(); + Sound->Release(); + SoundPrimaryBuffer=NULL; + Sound=NULL; + + // DLL の解放 + if(DirectSoundDLLHandle) + { + FreeLibrary(DirectSoundDLLHandle); + DirectSoundDLLHandle=NULL; + procDirectSoundCreate=NULL; + } + } + + + if(WriteLock) delete WriteLock; +} +//--------------------------------------------------------------------------- +void __fastcall SetPrimaryBufferFormat(WAVEFORMATEX *wfx) +{ + if(SoundPrimaryBuffer) + SoundPrimaryBuffer->SetFormat(wfx); +} +//--------------------------------------------------------------------------- +void __fastcall CreateSoundBuffer(const WAVEFORMATEXTENSIBLE * wfx) +{ + // 0.25 秒間のセカンダリバッファを作成する + + /* wfx.Format の nAvgBytesPerSec や nBlockAlign は変な値になっていないかどうか + チェックが必要 */ + + if(SoundBuffer) + { + SoundBuffer->Release(); + SoundBuffer = NULL; + } + + // プライマリバッファのフォーマットを再設定 + if(SoundPrimaryBuffer) + { + SoundPrimaryBuffer->SetFormat((const WAVEFORMATEX *)wfx); + } + + // セカンダリバッファの作成 + memset(&SoundBufferDesc,0,sizeof(DSBUFFERDESC)); + SoundBufferDesc.dwSize=sizeof(DSBUFFERDESC); + SoundBufferDesc.dwFlags= + DSBCAPS_GETCURRENTPOSITION2/* | DSBCAPS_CTRLPAN */| DSBCAPS_CTRLVOLUME + |DSBCAPS_GLOBALFOCUS ; + SoundBufferDesc.dwBufferBytes = wfx->Format.nAvgBytesPerSec /4; + SoundBufferDesc.dwBufferBytes /= wfx->Format.nBlockAlign * 2; + SoundBufferDesc.dwBufferBytes *= wfx->Format.nBlockAlign * 2; + SoundBufferBytes = SoundBufferDesc.dwBufferBytes; + SoundBufferBytesHalf = SoundBufferBytes / 2; + + Frequency = wfx->Format.nSamplesPerSec; + Channels = wfx->Format.nChannels; + SampleSize = wfx->Format.nBlockAlign; + + SoundBufferDesc.lpwfxFormat = (WAVEFORMATEX*)wfx; + + + // セカンダリバッファを作成する + HRESULT hr = Sound->CreateSoundBuffer(&SoundBufferDesc,&SoundBuffer,NULL); + if(FAILED(hr)) + { + SoundBuffer=NULL; + throw Exception("セカンダリバッファの作成に失敗しました" + "/周波数:"+AnsiString(wfx->Format.nSamplesPerSec)+ + "/チャネル数:"+AnsiString(wfx->Format.nChannels)+ + "/ビット数:"+AnsiString(16)+ + "/HRESULT:"+IntToHex((int)hr,8)); + } + + ResetSoundBuffer(); +} +//--------------------------------------------------------------------------- +void __fastcall DestroySoundBuffer(void) +{ + if(SoundBuffer) + { + SoundBuffer->Release(); + SoundBuffer = NULL; + } +} +//--------------------------------------------------------------------------- +static void __fastcall ResetSoundBuffer() +{ + if(!SoundBuffer) return; + + TBufferWriteLock lock; + + SoundBufferWritePos = 0; + DecodeEnded = false; + BufferRemainBlock = 0; + Playing = false; + + + BYTE *p1,*p2; + DWORD b1,b2; + + if(SUCCEEDED(SoundBuffer->Lock(0,SoundBufferBytes,(void**)&p1, + &b1,(void**)&p2,&b2,0))) + { + ZeroMemory(p1,SoundBufferBytes); + SoundBuffer->Unlock((void*)p1,b1,(void*)p2,b2); + } + + SoundBuffer->SetCurrentPosition(0); + + FirstWrite = true; +} +//--------------------------------------------------------------------------- +void __fastcall StartPlay(const WAVEFORMATEXTENSIBLE * wfx, tTVPWaveLoopManager * manager) +{ + TBufferWriteLock lock; + Manager = manager; + + CreateSoundBuffer(wfx); + + Playing = true; + FillSecondaryBuffer(); + SoundBuffer->Play(0,0,DSBPLAY_LOOPING); +} +//--------------------------------------------------------------------------- +void __fastcall StopPlay(void) +{ + if(!SoundBuffer) return; + + TBufferWriteLock lock; + Playing = false; + SoundBuffer->Stop(); + ResetSoundBuffer(); +} +//--------------------------------------------------------------------------- +static void __fastcall FillSecondaryBuffer(void) +{ + if(!Playing) return; + if(!SoundBuffer) return; + if(!Manager) return; + + TBufferWriteLock lock; + + int writepos; + + if(FirstWrite) + { + FirstWrite = false; + + writepos = 0; + SoundBufferWritePos = 1; + } + else + { + DWORD pp=0,wp=0; + SoundBuffer->GetCurrentPosition(&pp,&wp); + + wp/=SoundBufferBytesHalf; + pp/=SoundBufferBytesHalf; + + DWORD d = wp-SoundBufferWritePos; + if(d<0) d+=2; + + wp-=pp; + if(wp<0) wp+=2; + // この時点で wp =pp と wp の差 + + if(d <= wp) + { + // pp と wp の間は現在演奏中のため、そこに書き込むことはできない + return; + } + + writepos = SoundBufferWritePos?SoundBufferBytesHalf:0; + SoundBufferWritePos ^= 1; + + // pp と wp の区間は演奏中のため、そこに書き込んではならない + } + + if(DecodeEnded) + { + BufferRemainBlock--; + if(!BufferRemainBlock) + { + SoundBuffer->Stop(); + Playing = false; + return; + } + } + + BYTE *p1,*p2; + DWORD b1,b2; + + if(SUCCEEDED(SoundBuffer->Lock(writepos, SoundBufferBytesHalf, + (void**)&p1, &b1, (void**)&p2, &b2, 0))) + { + tjs_uint written; + Manager->Decode(p1, SoundBufferBytesHalf/SampleSize, + written, Segments[writepos ? 1: 0], + Labels[writepos ? 1: 0]); + + written *= SampleSize; + if(written < SoundBufferBytesHalf) + { + // 足りない分は 0 で満たす + if(!DecodeEnded) + { + DecodeEnded = true; + BufferRemainBlock = 2; + } + ZeroMemory(p1 + written, SoundBufferBytesHalf - written); + } + SoundBuffer->Unlock((void*)p1,b1,(void*)p2,b2); + } +} +//--------------------------------------------------------------------------- +DWORD __fastcall GetCurrentPlayingPos(void) +{ + // 現在の演奏位置を得る + if(!Playing) return -1; + + TBufferWriteLock lock; + + DWORD pp=0,wp=0; + SoundBuffer->GetCurrentPosition(&pp,&wp); + + int idx; + if(pp >= SoundBufferBytesHalf) + { + idx = 1; + pp -= SoundBufferBytesHalf; + } + else + { + idx = 0; + } + + pp /= SampleSize; + + tjs_uint pos = 0; + for(unsigned int i = 0 ; i < Segments[idx].size(); i++) + { + tjs_uint limit = pos + (tjs_uint)Segments[idx][i].Length; + if(pp >= pos && pp < limit) + return (DWORD)(Segments[idx][i].Start + (pp - pos)); + pos = limit; + } + + return 0; // will no be reached +} +//--------------------------------------------------------------------------- +bool __fastcall GetPlaying(void) +{ + return Playing; +} +//--------------------------------------------------------------------------- + + +#pragma package(smart_init) diff --git a/tools/win32/krdevui/looptuner2/DSound.h b/tools/win32/krdevui/looptuner2/DSound.h new file mode 100644 index 0000000..b26e318 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/DSound.h @@ -0,0 +1,33 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef DSoundUnitH +#define DSoundUnitH + +//--------------------------------------------------------------------------- +#include "WaveLoopManager.h" +//--------------------------------------------------------------------------- +// プロトタイプ +typedef DWORD __fastcall (__closure *TGetPCMDataEvent) + (__int16 * Buffer, DWORD Offset, DWORD Samples); +void __fastcall InitDirectSound(HWND wnd); +void __fastcall FreeDirectSound(void); +void __fastcall CreateSoundBuffer(const WAVEFORMATEXTENSIBLE * wfx); +void __fastcall DestroySoundBuffer(void); +void __fastcall StartPlay(const WAVEFORMATEXTENSIBLE * wfx, tTVPWaveLoopManager *manager); +void __fastcall StopPlay(void); +bool __fastcall GetPlaying(void); +//--------------------------------------------------------------------------- +DWORD __fastcall GetCurrentPlayingPos(void); +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- + + +#endif diff --git a/tools/win32/krdevui/looptuner2/EditLabelAttribUnit.cpp b/tools/win32/krdevui/looptuner2/EditLabelAttribUnit.cpp new file mode 100644 index 0000000..ce3bc3b --- /dev/null +++ b/tools/win32/krdevui/looptuner2/EditLabelAttribUnit.cpp @@ -0,0 +1,91 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "EditLabelAttribUnit.h" +#include "WaveLoopManager.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TEditLabelAttribFrame *EditLabelAttribFrame; +//--------------------------------------------------------------------------- +__fastcall TEditLabelAttribFrame::TEditLabelAttribFrame(TComponent* Owner) + : TFrame(Owner) +{ + FOnInfoChanged = NULL; + FOnEraseRedo = NULL; + InLoading = false; +} +//--------------------------------------------------------------------------- +void __fastcall TEditLabelAttribFrame::SetLabel(const tTVPWaveLabel &label) +{ + FLabel = label; + + InLoading = true; + + LabelNameEdit->Text = FLabel.Name; + LabelNameEdit->Modified = false; + + InLoading = false; + + AttribChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TEditLabelAttribFrame::SetLabelInfo(tTVPWaveLabel &label) +{ + label.Name = FLabel.Name; +} +//--------------------------------------------------------------------------- +void __fastcall TEditLabelAttribFrame::CheckUncommitted() +{ + LabelNameEditExit(this); +} +//--------------------------------------------------------------------------- +void __fastcall TEditLabelAttribFrame::AttribChanged() +{ +} +//--------------------------------------------------------------------------- +void __fastcall TEditLabelAttribFrame::CommitChanges() +{ + if(InLoading) return; + + FLabel.Name = LabelNameEdit->Text; + + if(OnInfoChanged) OnInfoChanged(this); +} +//--------------------------------------------------------------------------- +void __fastcall TEditLabelAttribFrame::LabelNameEditExit(TObject *Sender) +{ + if(LabelNameEdit->Modified) + { + AttribChanged(); + CommitChanges(); + LabelNameEdit->Modified = false; + } +} +//--------------------------------------------------------------------------- +void __fastcall TEditLabelAttribFrame::LabelNameEditKeyDown( + TObject *Sender, WORD &Key, TShiftState Shift) +{ + if(Key == VK_RETURN) + { + AttribChanged(); + CommitChanges(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TEditLabelAttribFrame::LabelNameEditChange(TObject *Sender) +{ + if(InLoading) return; + if(OnEraseRedo) OnEraseRedo(this); +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/looptuner2/EditLabelAttribUnit.dfm b/tools/win32/krdevui/looptuner2/EditLabelAttribUnit.dfm new file mode 100644 index 0000000..6065e06 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/EditLabelAttribUnit.dfm @@ -0,0 +1,26 @@ +object EditLabelAttribFrame: TEditLabelAttribFrame + Left = 0 + Top = 0 + Width = 383 + Height = 30 + HorzScrollBar.Visible = False + VertScrollBar.Visible = False + TabOrder = 0 + object Label1: TLabel + Left = 8 + Top = 8 + Width = 45 + Height = 12 + Caption = 'ラベル名' + end + object LabelNameEdit: TEdit + Left = 64 + Top = 4 + Width = 305 + Height = 20 + TabOrder = 0 + OnChange = LabelNameEditChange + OnExit = LabelNameEditExit + OnKeyDown = LabelNameEditKeyDown + end +end diff --git a/tools/win32/krdevui/looptuner2/EditLabelAttribUnit.h b/tools/win32/krdevui/looptuner2/EditLabelAttribUnit.h new file mode 100644 index 0000000..8dadb1e --- /dev/null +++ b/tools/win32/krdevui/looptuner2/EditLabelAttribUnit.h @@ -0,0 +1,51 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + + +#ifndef EditLabelAttribUnitH +#define EditLabelAttribUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#include "WaveView.h" +//--------------------------------------------------------------------------- +class TEditLabelAttribFrame : public TFrame +{ +__published: // IDE 管理のコンポーネント + TLabel *Label1; + TEdit *LabelNameEdit; + void __fastcall LabelNameEditExit(TObject *Sender); + void __fastcall LabelNameEditKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall LabelNameEditChange(TObject *Sender); +private: // ユーザー宣言 + tTVPWaveLabel FLabel; + bool InLoading; + TNotifyEvent FOnInfoChanged; + TNotifyEvent FOnEraseRedo; + + void __fastcall AttribChanged(); + void __fastcall CommitChanges(); +public: // ユーザー宣言 + __fastcall TEditLabelAttribFrame(TComponent* Owner); + void __fastcall SetLabel(const tTVPWaveLabel &label); + void __fastcall SetLabelInfo(tTVPWaveLabel &label); + void __fastcall CheckUncommitted(); + + __property TNotifyEvent OnInfoChanged = { read = FOnInfoChanged, write = FOnInfoChanged }; + __property TNotifyEvent OnEraseRedo = { read = FOnEraseRedo, write = FOnEraseRedo }; + +}; +//--------------------------------------------------------------------------- +extern PACKAGE TEditLabelAttribFrame *EditLabelAttribFrame; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/looptuner2/EditLinkAttribUnit.cpp b/tools/win32/krdevui/looptuner2/EditLinkAttribUnit.cpp new file mode 100644 index 0000000..5462ae0 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/EditLinkAttribUnit.cpp @@ -0,0 +1,164 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "EditLinkAttribUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TEditLinkAttribFrame *EditLinkAttribFrame; +//--------------------------------------------------------------------------- +__fastcall TEditLinkAttribFrame::TEditLinkAttribFrame(TComponent* Owner) + : TFrame(Owner) +{ + FOnInfoChanged = NULL; + FOnEraseRedo = NULL; + InLoading = false; +} +//--------------------------------------------------------------------------- +void __fastcall TEditLinkAttribFrame::SetLink(const tTVPWaveLoopLink &link) +{ + InLoading = true; + + FLink = link; + + EnableConditionCheckBox->Checked = FLink.Condition != llcNone; + CondVarComboBox->ItemIndex = (int)FLink.CondVar; + CondRefValueEdit->Text = AnsiString(FLink.RefValue); + ConditionComboBox->ItemIndex = (int)(FLink.Condition == 0 ? 0 : FLink.Condition - 1); + + CondRefValueEdit->Modified = false; + + InLoading = false; + + AttribChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TEditLinkAttribFrame::SetLinkInfo(tTVPWaveLoopLink &link) +{ + link.CondVar = FLink.CondVar; + link.RefValue = FLink.RefValue; + link.Condition = FLink.Condition; +} +//--------------------------------------------------------------------------- +void __fastcall TEditLinkAttribFrame::CheckUncommitted() +{ + CondRefValueEditExit(this); +} +//--------------------------------------------------------------------------- +void __fastcall TEditLinkAttribFrame::AttribChanged() +{ + bool b = EnableConditionCheckBox->Checked; + TColor fc = b ? clWindowText : clGrayText; + CondVarComboBox->Enabled = b; + CondRefValueEdit->Enabled = b; + ConditionComboBox->Enabled = b; + CondVarComboBox->Font->Color = fc; + Label1->Font->Color = fc; + CondRefValueEdit->Font->Color = fc; + ConditionComboBox->Font->Color = fc; +} +//--------------------------------------------------------------------------- +void __fastcall TEditLinkAttribFrame::CommitChanges() +{ + if(InLoading) return; + + if(EnableConditionCheckBox->Checked) + { + FLink.CondVar = CondVarComboBox->ItemIndex; + FLink.RefValue = CondRefValueEdit->Text.ToInt(); + FLink.Condition = (tTVPWaveLoopLinkCondition)(ConditionComboBox->ItemIndex + 1); + } + else + { + FLink.Condition = llcNone; + } + + if(OnInfoChanged) OnInfoChanged(this); +} +//--------------------------------------------------------------------------- +void __fastcall TEditLinkAttribFrame::EnableConditionCheckBoxClick( + TObject *Sender) +{ + AttribChanged(); + CommitChanges(); +} +//--------------------------------------------------------------------------- +void __fastcall TEditLinkAttribFrame::CondVarComboBoxChange( + TObject *Sender) +{ + AttribChanged(); + CommitChanges(); +} +//--------------------------------------------------------------------------- +void __fastcall TEditLinkAttribFrame::ConditionComboBoxChange( + TObject *Sender) +{ + AttribChanged(); + CommitChanges(); +} +//--------------------------------------------------------------------------- +void __fastcall TEditLinkAttribFrame::CondRefValueEditExit(TObject *Sender) +{ + if(CondRefValueEdit->Modified) + { + AttribChanged(); + CommitChanges(); + CondRefValueEdit->Modified = false; + } +} +//--------------------------------------------------------------------------- + +void __fastcall TEditLinkAttribFrame::ConditionComboBoxKeyDown( + TObject *Sender, WORD &Key, TShiftState Shift) +{ + if(Key == VK_RETURN) + { + AttribChanged(); + CommitChanges(); + } +} +//--------------------------------------------------------------------------- + +void __fastcall TEditLinkAttribFrame::CondRefValueEditChange( + TObject *Sender) +{ + if(InLoading) return; + + TEdit *edit = dynamic_cast(Sender); + if(edit) + { + if(edit->Text == "") + { + edit->Text = "0"; + edit->SelStart = 1; + edit->Modified = true; + } + + if(edit->Text != "0" && edit->Text.c_str()[0] == '0') + { + edit->Text = AnsiString(edit->Text.ToInt()); + edit->SelStart = edit->Text.Length(); + edit->Modified = true; + } + } + + if(FOnEraseRedo) FOnEraseRedo(this); +} +//--------------------------------------------------------------------------- + +void __fastcall TEditLinkAttribFrame::CondRefValueEditKeyPress( + TObject *Sender, char &Key) +{ + if(!(Key >= '0' && Key <= '9' || Key < 0x20)) Key = 0; +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/looptuner2/EditLinkAttribUnit.dfm b/tools/win32/krdevui/looptuner2/EditLinkAttribUnit.dfm new file mode 100644 index 0000000..858f42a --- /dev/null +++ b/tools/win32/krdevui/looptuner2/EditLinkAttribUnit.dfm @@ -0,0 +1,86 @@ +object EditLinkAttribFrame: TEditLinkAttribFrame + Left = 0 + Top = 0 + Width = 419 + Height = 30 + HorzScrollBar.Visible = False + VertScrollBar.Visible = False + TabOrder = 0 + object Label1: TLabel + Left = 152 + Top = 8 + Width = 67 + Height = 12 + Caption = '番のフラグが' + end + object EnableConditionCheckBox: TCheckBox + Left = 8 + Top = 6 + Width = 81 + Height = 17 + Caption = '条件付き' + TabOrder = 0 + OnClick = EnableConditionCheckBoxClick + OnKeyDown = ConditionComboBoxKeyDown + end + object CondVarComboBox: TComboBox + Left = 104 + Top = 4 + Width = 41 + Height = 20 + Style = csDropDownList + DropDownCount = 16 + ItemHeight = 12 + TabOrder = 1 + OnChange = CondVarComboBoxChange + OnKeyDown = ConditionComboBoxKeyDown + Items.Strings = ( + '0' + '1' + '2' + '3' + '4' + '5' + '6' + '7' + '8' + '9' + '10' + '11' + '12' + '13' + '14' + '15') + end + object CondRefValueEdit: TEdit + Left = 232 + Top = 4 + Width = 33 + Height = 20 + MaxLength = 4 + TabOrder = 2 + Text = '0' + OnChange = CondRefValueEditChange + OnExit = CondRefValueEditExit + OnKeyDown = ConditionComboBoxKeyDown + OnKeyPress = CondRefValueEditKeyPress + end + object ConditionComboBox: TComboBox + Left = 280 + Top = 4 + Width = 121 + Height = 20 + Style = csDropDownList + ItemHeight = 12 + TabOrder = 3 + OnChange = ConditionComboBoxChange + OnKeyDown = ConditionComboBoxKeyDown + Items.Strings = ( + 'と同じとき' + 'でないとき' + 'より大きいとき' + '以上のとき' + 'より小さいとき' + '以下のとき') + end +end diff --git a/tools/win32/krdevui/looptuner2/EditLinkAttribUnit.h b/tools/win32/krdevui/looptuner2/EditLinkAttribUnit.h new file mode 100644 index 0000000..67ab9b5 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/EditLinkAttribUnit.h @@ -0,0 +1,63 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + + +#ifndef EditLinkAttribUnitH +#define EditLinkAttribUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#include "WaveView.h" +//--------------------------------------------------------------------------- +class TEditLinkAttribFrame : public TFrame +{ +__published: // IDE 管理のコンポーネント + TCheckBox *EnableConditionCheckBox; + TComboBox *CondVarComboBox; + TLabel *Label1; + TEdit *CondRefValueEdit; + TComboBox *ConditionComboBox; + void __fastcall EnableConditionCheckBoxClick(TObject *Sender); + void __fastcall CondVarComboBoxChange(TObject *Sender); + void __fastcall ConditionComboBoxChange(TObject *Sender); + void __fastcall CondRefValueEditExit(TObject *Sender); + void __fastcall ConditionComboBoxKeyDown(TObject *Sender, WORD &Key, + TShiftState Shift); + void __fastcall CondRefValueEditChange(TObject *Sender); + void __fastcall CondRefValueEditKeyPress(TObject *Sender, char &Key); +private: // ユーザー宣言 + tTVPWaveLoopLink FLink; + bool InLoading; + + void __fastcall SetLinkNum(int num); + + void __fastcall AttribChanged(); + void __fastcall CommitChanges(); + + TNotifyEvent FOnInfoChanged; + TNotifyEvent FOnEraseRedo; + +public: // ユーザー宣言 + __fastcall TEditLinkAttribFrame(TComponent* Owner); + + void __fastcall SetLink(const tTVPWaveLoopLink &link); + void __fastcall SetLinkInfo(tTVPWaveLoopLink &link); + + void __fastcall CheckUncommitted(); + + __property TNotifyEvent OnInfoChanged = { read = FOnInfoChanged, write = FOnInfoChanged }; + __property TNotifyEvent OnEraseRedo = { read = FOnEraseRedo, write = FOnEraseRedo }; +}; +//--------------------------------------------------------------------------- +extern PACKAGE TEditLinkAttribFrame *EditLinkAttribFrame; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/looptuner2/LabelDetailUnit.cpp b/tools/win32/krdevui/looptuner2/LabelDetailUnit.cpp new file mode 100644 index 0000000..b8a2fe2 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/LabelDetailUnit.cpp @@ -0,0 +1,82 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "LabelDetailUnit.h" +#include "WaveLoopManager.h" +#include "looptune.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "EditLabelAttribUnit" +#pragma resource "*.dfm" +TLabelDetailForm *LabelDetailForm; +//--------------------------------------------------------------------------- +__fastcall TLabelDetailForm::TLabelDetailForm(TComponent* Owner) + : TForm(Owner) +{ + + // window position and size + ReadWindowBasicInformationFromIniFile("LabelDetail", this); +} +//--------------------------------------------------------------------------- + +void __fastcall TLabelDetailForm::FormClose(TObject *Sender, + TCloseAction &Action) +{ + // write information to ini file + WriteWindowBasicInformationToIniFile("LabelDetail", this); +} +//--------------------------------------------------------------------------- +void __fastcall TLabelDetailForm::SetLabel(const tTVPWaveLabel & label) +{ + FLabel = label; + EditLabelAttribFrame->SetLabel(label); +} +//--------------------------------------------------------------------------- +void __fastcall TLabelDetailForm::EditLabelAttribFrameInfoChanged(TObject * Sender) +{ + EditLabelAttribFrame->SetLabelInfo(FLabel); +} +//--------------------------------------------------------------------------- +void __fastcall TLabelDetailForm::OKButtonClick(TObject *Sender) +{ + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- +void __fastcall TLabelDetailForm::CancelButtonClick(TObject *Sender) +{ + ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- + + +void __fastcall TLabelDetailForm::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + + if(ModalResult == mrOk) + { + EditLabelAttribFrame->CheckUncommitted(); + EditLabelAttribFrame->SetLabelInfo(FLabel); + if(FLabel.Name.c_str()[0] == ':' && !tTVPWaveLoopManager::GetLabelExpression(FLabel.Name)) + { + Application->MessageBox("式の文法が間違っています", "エラー", MB_OK|MB_ICONEXCLAMATION); + CanClose = false; + } + if(FLabel.Name.AnsiPos("'") != 0) + { + Application->MessageBox("ラベル名にアポストロフィー (') を含める事はできません", "エラー", MB_OK|MB_ICONEXCLAMATION); + CanClose = false; + } + } +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/looptuner2/LabelDetailUnit.dfm b/tools/win32/krdevui/looptuner2/LabelDetailUnit.dfm new file mode 100644 index 0000000..ec900de --- /dev/null +++ b/tools/win32/krdevui/looptuner2/LabelDetailUnit.dfm @@ -0,0 +1,45 @@ +object LabelDetailForm: TLabelDetailForm + Left = 151 + Top = 185 + ActiveControl = EditLabelAttribFrame.LabelNameEdit + BorderStyle = bsDialog + BorderWidth = 8 + Caption = 'ラベルの編集' + ClientHeight = 66 + ClientWidth = 380 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + OnClose = FormClose + OnCloseQuery = FormCloseQuery + PixelsPerInch = 96 + TextHeight = 12 + inline EditLabelAttribFrame: TEditLabelAttribFrame + Width = 380 + Align = alTop + end + object OKButton: TButton + Left = 202 + Top = 40 + Width = 75 + Height = 25 + Caption = 'OK' + Default = True + TabOrder = 1 + OnClick = OKButtonClick + end + object CancelButton: TButton + Left = 290 + Top = 40 + Width = 75 + Height = 25 + Cancel = True + Caption = 'キャンセル' + TabOrder = 2 + OnClick = CancelButtonClick + end +end diff --git a/tools/win32/krdevui/looptuner2/LabelDetailUnit.h b/tools/win32/krdevui/looptuner2/LabelDetailUnit.h new file mode 100644 index 0000000..2a4d1e6 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/LabelDetailUnit.h @@ -0,0 +1,48 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef LabelDetailUnitH +#define LabelDetailUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include "EditLabelAttribUnit.h" +//--------------------------------------------------------------------------- +class TLabelDetailForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TEditLabelAttribFrame *EditLabelAttribFrame; + TButton *OKButton; + TButton *CancelButton; + void __fastcall OKButtonClick(TObject *Sender); + void __fastcall CancelButtonClick(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); +private: // ユーザー宣言 + int LabelNum; // label number + tTVPWaveLabel FLabel; // current editting label + + + +public: // ユーザー宣言 + __fastcall TLabelDetailForm(TComponent* Owner); + + void __fastcall SetLabel(const tTVPWaveLabel & label); + + const tTVPWaveLabel & GetLabel() const { return FLabel ; } + +private: + void __fastcall EditLabelAttribFrameInfoChanged(TObject * Sender); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TLabelDetailForm *LabelDetailForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/looptuner2/LinkDetailUnit.cpp b/tools/win32/krdevui/looptuner2/LinkDetailUnit.cpp new file mode 100644 index 0000000..9896d45 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/LinkDetailUnit.cpp @@ -0,0 +1,835 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "DSound.h" +#include "LinkDetailUnit.h" +#include "LoopTunerMainUnit.h" +#include "looptune.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "EditLinkAttribUnit" +#pragma resource "*.dfm" +#include "ColorScheme.h" + + +TLinkDetailForm *LinkDetailForm; +//--------------------------------------------------------------------------- +__fastcall TLinkDetailForm::TLinkDetailForm(TComponent* Owner) + : TForm(Owner) +{ + StopPlay(); + + FReader = NULL; + FMagnify = 0; + FManager = NULL; + LinkNum = 0; + + Dragging = false; + BeforeOrAfter = false; + FirstMouseDownPos = 0; + FirstMouseDownX = 0; + + WaveAreaHasFocus = true; + + WaveAreaPanel->DoubleBuffered = true; + PlayBeforePaintBoxPanel->DoubleBuffered = true; + + PlayBeforeLength = 0; + PlayStartPos = 0; + + EditLinkAttribFrame->OnInfoChanged = EditLinkAttribFrameInfoChanged; + EditLinkAttribFrame->OnEraseRedo = EditLinkAttribFrameEraseRedo; + + BeforeLinkLabel->Font->Color = C_WAVE_B_FG_BASE; + AfterLinkLabel ->Font->Color = C_WAVE_A_FG_BASE; + + UpdateLayout(); + UpdateDisplay(); + + + // window position and size + ReadWindowBasicInformationFromIniFile("LinkDetail", this); + + // assign mainwindow's icon + Icon->Assign(((TForm*)Owner)->Icon); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::FormDestroy(TObject *Sender) +{ + StopPlay(); + if(FManager) delete FManager, FManager = NULL; +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::FormClose(TObject *Sender, + TCloseAction &Action) +{ + if(ModalResult == mrOk) + { + EditLinkAttribFrame->CheckUncommitted(); + EditLinkAttribFrame->SetLinkInfo(FLink); + UpdateMainWindowParams(true); + } + else + { + FLink = FLinkOriginal; + UpdateMainWindowParams(false); + } + + // write information to ini file + WriteWindowBasicInformationToIniFile("LinkDetail", this); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::OKButtonClick(TObject *Sender) +{ + ModalResult = mrOk; +} +//--------------------------------------------------------------------------- + +void __fastcall TLinkDetailForm::CancelButtonClick(TObject *Sender) +{ + ModalResult = mrCancel; +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::SetReaderAndLink(TWaveReader * reader, + tTVPWaveLoopLink link, int linknum) +{ + // set the reader and the link + FReader = reader; + FLink = FLinkOriginal = link; + LinkNum = linknum; + + EditLinkAttribFrame->SetLink(FLink); + + if(FManager) delete FManager, FManager = NULL; + FManager = new tTVPWaveLoopManager(); + FManager->SetDecoder(FReader); + + // show link attributes + SmoothAction->Checked = FLink.Smooth; +} +//--------------------------------------------------------------------------- +int __fastcall TLinkDetailForm::PixelToSample(int pixel) +{ + if(FMagnify <= 0) + { + // shrink + return pixel << (-FMagnify); + } + else + { + // expand + return pixel >> FMagnify; + } +} +//--------------------------------------------------------------------------- +int __fastcall TLinkDetailForm::SampleToPixel(int sample) +{ + if(FMagnify <= 0) + { + // shrink + return sample >> (-FMagnify); + } + else + { + // expand + return sample << FMagnify; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::UpdateMainWindowParams(bool push_undo) +{ + // update main window's waveview link information + TWaveView *waveview = ((TTSSLoopTuner2MainForm*)(Owner))->GetWaveView(); + + tTVPWaveLoopLink &link = waveview->GetLinks()[LinkNum]; + + waveview->InvalidateLink(LinkNum); + + link = FLink; + + waveview->NotifyLinkChanged(); + + waveview->InvalidateLink(LinkNum); + + if(push_undo) waveview->PushUndo(); //==== push undo +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::UpdateDisplay() +{ + // update labels + MagnifyLabel->Caption = "/" + AnsiString(1<<-FMagnify); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::UpdateLayout() +{ + PosAdjustToolBar->Left = (ToolBarPanel->Width - PosAdjustToolBar->Width) /2 + 1; +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::PlayLink(int before, int after) +{ + // play the link + + // stop current playing sound + StopPlay(); + + std::vector links; + tTVPWaveLoopLink link = FLink; + link.Condition = llcNone; // disable the condition + links.push_back(link); + FManager->SetLinks(links); // set new links to the manager + + const WAVEFORMATEXTENSIBLE * wfx; + wfx = FReader->GetWindowsFormat(); + int before_samples = FReader->Frequency * before / 1000; + PlayStartPos = PlayLastPos = FLink.From - before_samples < 0 ? 0 : FLink.From - before_samples; + PlayBeforeLength = FLink.From - PlayStartPos; + + FManager->SetPosition(PlayStartPos); + StartPlay(wfx, FManager); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::FormResize(TObject *Sender) +{ + UpdateLayout(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::WavePaintBoxPaint(TObject *Sender) +{ + // draw waveform + TCanvas * canvas = WavePaintBox->Canvas; + + // check reader validity + if(!FReader || !FReader->ReadDone) + { + TRect r; + r.left = canvas->ClipRect.left, r.top = 0, + r.right = canvas->ClipRect.right, + r.bottom = WavePaintBox->Height; + canvas->Brush->Style = bsSolid; + canvas->Brush->Color = C_DISABLEED_CLIENT; + canvas->FillRect(r); + return ; // reader not available + } + + + // calc dimentions + int xstep = 1<<(-FMagnify); + const int sstep = 1; + + int one_height = ((WavePaintBox->Height) / FReader->Channels) & ~1; + int one_height_half = one_height >> 1; + int one_client_height = one_height - 2; // 2 : padding margin + + int center = WavePaintBox->Width / 2; // center line + + // calc start point + int dest_left = canvas->ClipRect.left; + int dest_right = canvas->ClipRect.right; + + int before_pos = PixelToSample(dest_left - center) + FLink.From; + int after_pos = PixelToSample(dest_left - center) + FLink.To; + + + // clear the background + #define CONV_Y(v, ch) ((((v) * one_client_height) / -65536) + \ + one_height_half + (ch) * one_height) + + //- main + if(dest_left < dest_right) + { + TRect r; + r.left = dest_left, r.top = 0, r.right = dest_right, r.bottom = + WavePaintBox->Height; + canvas->Brush->Style = bsSolid; + canvas->Brush->Color = C_CLIENT; + canvas->FillRect(r); + } + + //- draw -Inf line + canvas->Pen->Color = C_INF_LINE; + for(int ch = 0; ch < FReader->Channels; ch ++) + { + canvas->MoveTo(dest_left, CONV_Y(0, ch)); + canvas->LineTo(dest_right, CONV_Y(0, ch)); + } + + // draw waveform + for(int x = dest_left; x < dest_right; x++, before_pos += xstep, after_pos += xstep) + { + for(int ch = 0; ch < FReader->Channels; ch ++) + { + // get "before" min max + int before_high, before_low; + if(before_pos >= 0 && before_pos + xstep <= FReader->NumSamples) + FReader->GetPeak(before_high, before_low, before_pos, ch, sstep); + else + before_high = before_low = 0; + + if(before_high > 0 && before_low > 0) + before_low = 0; + if(before_high < 0 && before_low < 0) + before_high = 0; + + before_high = CONV_Y(before_high, ch); + before_low = CONV_Y(before_low , ch); + + // get "after" min max + int after_high, after_low; + if(after_pos >= 0 && after_pos + xstep <= FReader->NumSamples) + FReader->GetPeak(after_high, after_low, after_pos, ch, sstep); + else + after_high = after_low = 0; + + if(after_high > 0 && after_low > 0) + after_low = 0; + if(after_high < 0 && after_low < 0) + after_high = 0; + + after_high = CONV_Y(after_high, ch); + after_low = CONV_Y(after_low , ch); + + // detect bg and fg + int bg_high, bg_low; + int fg_high, fg_low; + if(x < center) + { + bg_high = after_high; + bg_low = after_low; + fg_high = before_high; + fg_low = before_low; + } + else + { + bg_high = before_high; + bg_low = before_low; + fg_high = after_high; + fg_low = after_low; + } + + // draw waveform + int fg_bg_high; + int fg_bg_low; + if(bg_high < fg_high) + { + // draw bg only + canvas->Pen->Color = x < center ? C_WAVE_B_BG : C_WAVE_A_BG; + canvas->MoveTo(x, bg_high); + canvas->LineTo(x, fg_high); + fg_bg_high = fg_high; + + } + else + { + // draw fg only + canvas->Pen->Color = x < center ? C_WAVE_B_FG : C_WAVE_A_FG; + canvas->MoveTo(x, fg_high); + canvas->LineTo(x, bg_high); + fg_bg_high = bg_high; + } + + if(bg_low < fg_low) + { + // draw fg only + canvas->Pen->Color = x < center ? C_WAVE_B_FG : C_WAVE_A_FG; + canvas->MoveTo(x, bg_low); + canvas->LineTo(x, fg_low); + fg_bg_low = bg_low; + } + else + { + // draw bg only + canvas->Pen->Color = x < center ? C_WAVE_B_BG : C_WAVE_A_BG; + canvas->MoveTo(x, fg_low); + canvas->LineTo(x, bg_low); + fg_bg_low = fg_low; + } + + // draw fg-bg + canvas->Pen->Color = x < center ? C_WAVE_B_FG_BG : C_WAVE_A_FG_BG; + canvas->MoveTo(x, fg_bg_high); + canvas->LineTo(x, fg_bg_low); + } + } + + // draw center split + canvas->Pen->Color = C_WAVE_CENTER_SPLIT; + canvas->MoveTo(center, 0); + canvas->LineTo(center, WavePaintBox->Height); + + // draw focus frame + if(WaveAreaHasFocus) + { + canvas->Pen->Color = (TColor)((~C_CLIENT)&0xffffff); + canvas->MoveTo(0, 0); + canvas->LineTo(WavePaintBox->Width-1, 0); + canvas->LineTo(WavePaintBox->Width-1, WavePaintBox->Height-1); + canvas->LineTo(0, WavePaintBox->Height-1); + canvas->LineTo(0, 0); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::WaveAreaPanelEnter(TObject *Sender) +{ + WaveAreaHasFocus = true; + WaveAreaPanel->Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::WaveAreaPanelExit(TObject *Sender) +{ + WaveAreaHasFocus = false; + WaveAreaPanel->Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::WavePaintBoxMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + WaveAreaPanel->SetFocus(); + if(Button == mbLeft) + { + Dragging = true; + int center = WavePaintBox->Width / 2; + BeforeOrAfter = X < center; + FirstMouseDownPos = + (BeforeOrAfter ? FLink.From : FLink.To); + FirstMouseDownX = X; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::WavePaintBoxMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if(Dragging) + { + if(BeforeOrAfter) + { + FLink.From = FirstMouseDownPos - PixelToSample(X - FirstMouseDownX); + if(FLink.From < 0) FLink.From = 0; + if(FLink.From >= FReader->NumSamples) FLink.From = FReader->NumSamples - 1; + } + else + { + FLink.To = FirstMouseDownPos - PixelToSample(X - FirstMouseDownX); + if(FLink.To < 0) FLink.To = 0; + if(FLink.To >= FReader->NumSamples) FLink.To = FReader->NumSamples - 1; + } + WavePaintBox->Invalidate(); + UpdateMainWindowParams(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::WavePaintBoxMouseUp(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if(Dragging) + { + Dragging = false; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::WavePaintBoxDblClick(TObject *Sender) +{ + PlayLink(); +} +//--------------------------------------------------------------------------- + +void __fastcall TLinkDetailForm::PlayActionExecute(TObject *Sender) +{ + PlayLink(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::PlayMenuItemClick(TObject *Sender) +{ + PlayLink(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::FormMouseWheel(TObject *Sender, + TShiftState Shift, int WheelDelta, TPoint &MousePos, bool &Handled) +{ + // mouse wheel; + // check mouse cursor position + TPoint pos = MousePos; + +// pos = ClientToScreen(pos); + pos = WavePaintBox->ScreenToClient(pos); + + int center = WavePaintBox->Width / 2; // center line + if(pos.x > center) + { + // after link + StepAfter(WheelDelta / 120); + } + else + { + // before link + StepBefore(WheelDelta / 120); + } + + Handled = true; +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::ZoomInActionExecute(TObject *Sender) +{ + if(FMagnify < 0) FMagnify ++; + WavePaintBox->Invalidate(); + UpdateDisplay(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::ZoomOutActionExecute(TObject *Sender) +{ + if(FMagnify > -10) FMagnify --; + WavePaintBox->Invalidate(); + UpdateDisplay(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::SmoothActionExecute(TObject *Sender) +{ + SmoothAction->Checked = ! SmoothAction->Checked; + FLink.Smooth = SmoothAction->Checked; + UpdateMainWindowParams(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::BeforePrevCrossActionExecute( + TObject *Sender) +{ + int found = SearchCrossingPoint(FLink.From, 1); + if(found != -1) + { + FLink.From = found; + WavePaintBox->Invalidate(); + UpdateMainWindowParams(); + UpdateDisplay(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::BeforePrevFastActionExecute( + TObject *Sender) +{ + StepBefore(20); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::BeforePrevStepActionExecute( + TObject *Sender) +{ + StepBefore(1); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::BeforeNextStepActionExecute( + TObject *Sender) +{ + StepBefore(-1); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::BeforeNextFastActionExecute( + TObject *Sender) +{ + StepBefore(-20); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::BeforeNextCrossActionExecute( + TObject *Sender) +{ + int found = SearchCrossingPoint(FLink.From, -1); + if(found != -1) + { + FLink.From = found; + WavePaintBox->Invalidate(); + UpdateMainWindowParams(); + UpdateDisplay(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::AfterPrevCrossActionExecute( + TObject *Sender) +{ + int found = SearchCrossingPoint(FLink.To, 1); + if(found != -1) + { + FLink.To = found; + WavePaintBox->Invalidate(); + UpdateMainWindowParams(); + UpdateDisplay(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::AfterPrevFastActionExecute( + TObject *Sender) +{ + StepAfter(20); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::AfterPrevStepActionExecute( + TObject *Sender) +{ + StepAfter(1); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::AfterNextStepActionExecute( + TObject *Sender) +{ + StepAfter(-1); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::AfterNextFastActionExecute( + TObject *Sender) +{ + StepAfter(-20); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::AfterNextCrossActionExecute( + TObject *Sender) +{ + int found = SearchCrossingPoint(FLink.To, -1); + if(found != -1) + { + FLink.To = found; + WavePaintBox->Invalidate(); + UpdateMainWindowParams(); + UpdateDisplay(); + } +} +//--------------------------------------------------------------------------- +int __fastcall TLinkDetailForm::SearchCrossingPoint(int from, int direction) +{ + // search previous(direction=-1) or next(direction=1) crossing point + // from the point 'from'. + // returns the found point, -1 for not-found. + bool *signs = NULL; // array of sign; true for positive, false for negative + int found_point = -1; + + try + { + int ptr = from; + + // allocate memory for signs + signs = new bool [FReader->Channels]; + + // set initial signs + for(int i = 0; i < FReader->Channels; i++) + signs[i] = FReader->GetSampleAt(ptr, i) >= 0; + + // step + ptr += direction; + + while(ptr >= 0 && ptr < FReader->NumSamples) + { + // find any points that one of signs changes. + for(int i = 0; i < FReader->Channels; i++) + { + if(signs[i] != (FReader->GetSampleAt(ptr, i) >= 0)) + { + found_point = ptr; + break; + } + } + if(found_point != -1) break; + + ptr += direction; + } + } + catch(...) + { + if(signs) delete [] signs; + throw; + } + if(signs) delete [] signs; + return found_point; +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::StepBefore(int step) +{ + if(step < 0) + { + step = (1<<-FMagnify) * -step; + if(FLink.From > step) + FLink.From -= step; + else + FLink.From = 0; + } + else + { + step = (1<<-FMagnify) * step; + if((FReader->NumSamples - 1) - FLink.From > step ) + FLink.From += step; + else + FLink.From = FReader->NumSamples - 1; + } + + WavePaintBox->Invalidate(); + UpdateMainWindowParams(); + UpdateDisplay(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::StepAfter(int step) +{ + if(step < 0) + { + step = (1<<-FMagnify) * -step; + if(FLink.To > step) + FLink.To -= step; + else + FLink.To = 0; + } + else + { + step = (1<<-FMagnify) * step; + if((FReader->NumSamples - 1) - FLink.To > step ) + FLink.To += step; + else + FLink.To = FReader->NumSamples - 1; + } + + WavePaintBox->Invalidate(); + UpdateMainWindowParams(); + UpdateDisplay(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::PlayLink() +{ + int ms = 500; + if (PlayHalfSecToolButton->Marked) ms = 500; + else if(Play1SecToolButton->Marked) ms = 1000; + else if(Play2SecToolButton->Marked) ms = 2000; + else if(Play3SecToolButton->Marked) ms = 3000; + else if(Play5SecToolButton->Marked) ms = 5000; + PlayLink(ms); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::MarkPlayButton(TObject * button) +{ + PlayHalfSecToolButton->Marked = PlayHalfSecToolButton == button; + Play1SecToolButton->Marked = Play1SecToolButton == button; + Play2SecToolButton->Marked = Play2SecToolButton == button; + Play3SecToolButton->Marked = Play3SecToolButton == button; + Play5SecToolButton->Marked = Play5SecToolButton == button; +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::StopPlayActionExecute(TObject *Sender) +{ + StopPlay(); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::PlayHalfSecActionExecute(TObject *Sender) +{ + MarkPlayButton(PlayHalfSecToolButton); + PlayLink(500); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::Play1SecActionExecute(TObject *Sender) +{ + MarkPlayButton(Play1SecToolButton); + PlayLink(1000); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::Play2SecActionExecute(TObject *Sender) +{ + MarkPlayButton(Play2SecToolButton); + PlayLink(2000); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::Play3SecActionExecute(TObject *Sender) +{ + MarkPlayButton(Play3SecToolButton); + PlayLink(3000); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::Play5SecActionExecute(TObject *Sender) +{ + MarkPlayButton(Play5SecToolButton); + PlayLink(5000); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::ApplicationEventsIdle(TObject *Sender, + bool &Done) +{ + int pos = (int)GetCurrentPlayingPos(); + + if(pos != -1) + { + Sleep(1); // this will make the cpu usage low + Done = false; + + PlayBeforePaintBox->Invalidate(); + } + else + { + if(PlayBeforeLength) + { + PlayBeforeLength = 0; + PlayBeforePaintBox->Invalidate(); + } + Done = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::PlayBeforePaintBoxPaint(TObject *Sender) +{ + if(PlayBeforeLength) + { + int current_pos = GetCurrentPlayingPos(); + int elapsed = current_pos - PlayStartPos; + if(elapsed < 0 || elapsed >= PlayBeforeLength || current_pos < PlayLastPos) + { + PlayBeforeLength = 0; + } + + if(PlayBeforeLength == 0) + { + PlayBeforeLabel->Visible = false; + return; // do nothing + } + + PlayLastPos = current_pos; + + TRect r; + r.left = 0; + r.top = 0; + r.right = PlayBeforePaintBox->Width * elapsed / PlayBeforeLength; + r.bottom = PlayBeforePaintBox->Height; + PlayBeforePaintBox->Canvas->Brush->Color = clGreen; + PlayBeforePaintBox->Canvas->FillRect(r); + + r.left = r.right; + r.right = PlayBeforePaintBox->Width; + PlayBeforePaintBox->Canvas->Brush->Color = clYellow; + PlayBeforePaintBox->Canvas->FillRect(r); + + AnsiString str; + str.sprintf(PlayBeforeLabel->Hint.c_str(), + (double)(PlayBeforeLength - elapsed) / FReader->Frequency); + PlayBeforeLabel->Caption = str; + PlayBeforeLabel->Visible = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::EditLinkAttribFrameInfoChanged(TObject * Sender) +{ + EditLinkAttribFrame->SetLinkInfo(FLink); + UpdateMainWindowParams(false); +} +//--------------------------------------------------------------------------- +void __fastcall TLinkDetailForm::EditLinkAttribFrameEraseRedo(TObject * Sender) +{ + // do nothing +} +//--------------------------------------------------------------------------- + + + + + + + + + + + + diff --git a/tools/win32/krdevui/looptuner2/LinkDetailUnit.dfm b/tools/win32/krdevui/looptuner2/LinkDetailUnit.dfm new file mode 100644 index 0000000..3c894a1 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/LinkDetailUnit.dfm @@ -0,0 +1,630 @@ +object LinkDetailForm: TLinkDetailForm + Left = 43 + Top = 230 + Width = 637 + Height = 350 + ActiveControl = WaveAreaPanel + Caption = 'リンクの編集' + Color = clBtnFace + Constraints.MinHeight = 189 + Constraints.MinWidth = 612 + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + OnClose = FormClose + OnDestroy = FormDestroy + OnMouseWheel = FormMouseWheel + OnResize = FormResize + PixelsPerInch = 96 + TextHeight = 12 + inline EditLinkAttribFrame: TEditLinkAttribFrame + Width = 629 + Align = alTop + TabOrder = 3 + end + object ToolBarPanel: TPanel + Left = 0 + Top = 252 + Width = 629 + Height = 31 + Align = alBottom + BevelOuter = bvNone + TabOrder = 0 + object PosAdjustToolBar: TToolBar + Left = 175 + Top = 4 + Width = 284 + Height = 22 + Align = alNone + AutoSize = True + Caption = 'PosAdjustToolBar' + EdgeBorders = [] + Flat = True + Images = TSSLoopTuner2MainForm.ImageList + TabOrder = 0 + object BeforePrevCrossToolButton: TToolButton + Left = 0 + Top = 0 + Action = BeforePrevCrossAction + ParentShowHint = False + ShowHint = True + end + object BeforePrevFastToolButton: TToolButton + Left = 23 + Top = 0 + Action = BeforePrevFastAction + ParentShowHint = False + ShowHint = True + end + object BeforePrevStepToolButton: TToolButton + Left = 46 + Top = 0 + Action = BeforePrevStepAction + ParentShowHint = False + ShowHint = True + end + object BeforeNextStepToolButton: TToolButton + Left = 69 + Top = 0 + Action = BeforeNextStepAction + ParentShowHint = False + ShowHint = True + end + object BeforeNextFastToolButton: TToolButton + Left = 92 + Top = 0 + Action = BeforeNextFastAction + ParentShowHint = False + ShowHint = True + end + object BeforeNextCrossToolButton: TToolButton + Left = 115 + Top = 0 + Action = BeforeNextCrossAction + ParentShowHint = False + ShowHint = True + end + object ToolButton2: TToolButton + Left = 138 + Top = 0 + Width = 8 + Caption = 'ToolButton2' + ImageIndex = 20 + Style = tbsSeparator + end + object AfterPrevCrossToolButton: TToolButton + Left = 146 + Top = 0 + Action = AfterPrevCrossAction + ParentShowHint = False + ShowHint = True + end + object AfterPrevFastToolButton: TToolButton + Left = 169 + Top = 0 + Action = AfterPrevFastAction + ParentShowHint = False + ShowHint = True + end + object AfterPrevStepToolButton: TToolButton + Left = 192 + Top = 0 + Action = AfterPrevStepAction + ParentShowHint = False + ShowHint = True + end + object AfterNextStepToolButton: TToolButton + Left = 215 + Top = 0 + Action = AfterNextStepAction + ParentShowHint = False + ShowHint = True + end + object AfterNextFastToolButton: TToolButton + Left = 238 + Top = 0 + Action = AfterNextFastAction + ParentShowHint = False + ShowHint = True + end + object AfterNextCrossToolButton: TToolButton + Left = 261 + Top = 0 + Action = AfterNextCrossAction + ParentShowHint = False + ShowHint = True + end + end + end + object BottomPanel: TPanel + Left = 0 + Top = 283 + Width = 629 + Height = 33 + Align = alBottom + BevelOuter = bvNone + BorderWidth = 4 + TabOrder = 1 + object PlayBeforeLabel: TLabel + Left = 304 + Top = 5 + Width = 109 + Height = 12 + Hint = 'リンクまであと %.1f 秒' + Caption = 'リンクまであと %.1f 秒' + Visible = False + end + object BottomToolBar: TToolBar + Left = 4 + Top = 4 + Width = 288 + Height = 25 + Align = alLeft + AutoSize = True + ButtonWidth = 25 + Caption = 'BottomToolBar' + EdgeBorders = [] + Flat = True + Images = TSSLoopTuner2MainForm.ImageList + TabOrder = 0 + object ZoomInToolButton: TToolButton + Left = 0 + Top = 0 + Action = ZoomInAction + ParentShowHint = False + ShowHint = True + end + object ZoomOutToolButton: TToolButton + Left = 25 + Top = 0 + Action = ZoomOutAction + ParentShowHint = False + ShowHint = True + end + object MagnifyLabel: TLabel + Left = 50 + Top = 0 + Width = 47 + Height = 22 + Alignment = taCenter + AutoSize = False + Caption = '/1024' + Layout = tlCenter + end + object ToolButton17: TToolButton + Left = 97 + Top = 0 + Width = 8 + Caption = 'ToolButton17' + ImageIndex = 13 + Style = tbsSeparator + end + object SmoothToolButton: TToolButton + Left = 105 + Top = 0 + Action = SmoothAction + ParentShowHint = False + ShowHint = True + end + object ToolButton15: TToolButton + Left = 130 + Top = 0 + Width = 8 + Caption = 'ToolButton15' + ImageIndex = 25 + Style = tbsSeparator + end + object StopPlayToolButton: TToolButton + Left = 138 + Top = 0 + Action = StopPlayAction + ParentShowHint = False + ShowHint = True + end + object PlayHalfSecToolButton: TToolButton + Left = 163 + Top = 0 + Action = PlayHalfSecAction + ParentShowHint = False + ShowHint = True + end + object Play1SecToolButton: TToolButton + Left = 188 + Top = 0 + Action = Play1SecAction + ParentShowHint = False + ShowHint = True + end + object Play2SecToolButton: TToolButton + Left = 213 + Top = 0 + Action = Play2SecAction + Marked = True + ParentShowHint = False + ShowHint = True + end + object Play3SecToolButton: TToolButton + Left = 238 + Top = 0 + Action = Play3SecAction + ParentShowHint = False + ShowHint = True + end + object Play5SecToolButton: TToolButton + Left = 263 + Top = 0 + Action = Play5SecAction + ParentShowHint = False + ShowHint = True + end + end + object OKButton: TButton + Left = 454 + Top = 2 + Width = 75 + Height = 25 + Anchors = [akTop, akRight] + Caption = 'OK' + Default = True + TabOrder = 2 + OnClick = OKButtonClick + end + object CancelButton: TButton + Left = 542 + Top = 2 + Width = 75 + Height = 25 + Anchors = [akTop, akRight] + Cancel = True + Caption = 'キャンセル' + TabOrder = 3 + OnClick = CancelButtonClick + end + object PlayBeforePaintBoxPanel: TPanel + Left = 304 + Top = 18 + Width = 105 + Height = 7 + BevelOuter = bvLowered + TabOrder = 1 + object PlayBeforePaintBox: TPaintBox + Left = 1 + Top = 1 + Width = 103 + Height = 5 + Align = alClient + OnPaint = PlayBeforePaintBoxPaint + end + end + end + object WaveAreaPanel: TPanel + Left = 0 + Top = 30 + Width = 629 + Height = 222 + Align = alClient + BevelOuter = bvLowered + PopupMenu = WaveAreaPopupMenu + TabOrder = 2 + OnEnter = WaveAreaPanelEnter + OnExit = WaveAreaPanelExit + object WavePaintBox: TPaintBox + Left = 1 + Top = 1 + Width = 627 + Height = 220 + Align = alClient + OnDblClick = WavePaintBoxDblClick + OnMouseDown = WavePaintBoxMouseDown + OnMouseMove = WavePaintBoxMouseMove + OnMouseUp = WavePaintBoxMouseUp + OnPaint = WavePaintBoxPaint + end + object AfterLinkLabel: TLabel + Left = 568 + Top = 8 + Width = 45 + Height = 12 + Anchors = [akTop, akRight] + Caption = 'リンク後' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [fsBold] + ParentFont = False + Transparent = True + end + object BeforeLinkLabel: TLabel + Left = 16 + Top = 8 + Width = 45 + Height = 12 + Caption = 'リンク前' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [fsBold] + ParentFont = False + Transparent = True + end + end + object ActionList: TActionList + Images = TSSLoopTuner2MainForm.ImageList + Left = 456 + Top = 24 + object StopPlayAction: TAction + Category = '再生' + Caption = '再生停止(&Q)' + Hint = '再生を停止' + ImageIndex = 4 + ShortCut = 81 + OnExecute = StopPlayActionExecute + end + object ZoomInAction: TAction + Category = '表示' + Caption = 'ズーム・イン(&I)' + Hint = '波形を拡大する' + ImageIndex = 9 + ShortCut = 73 + OnExecute = ZoomInActionExecute + end + object ZoomOutAction: TAction + Category = '表示' + Caption = 'ズーム・アウト(&O)' + Hint = '波形を縮小する' + ImageIndex = 10 + ShortCut = 79 + OnExecute = ZoomOutActionExecute + end + object PlayHalfSecAction: TAction + Category = '再生' + Caption = '0.5秒前から再生(&0)' + Hint = '0.5秒前から再生' + ImageIndex = 25 + ShortCut = 16432 + OnExecute = PlayHalfSecActionExecute + end + object Play1SecAction: TAction + Category = '再生' + Caption = '1秒前から再生(&1)' + Hint = '1秒前から再生' + ImageIndex = 26 + ShortCut = 16433 + OnExecute = Play1SecActionExecute + end + object Play2SecAction: TAction + Category = '再生' + Caption = '2秒前から再生(&2)' + Hint = '2秒前から再生' + ImageIndex = 27 + ShortCut = 16434 + OnExecute = Play2SecActionExecute + end + object Play3SecAction: TAction + Category = '再生' + Caption = '3秒前から再生(&3)' + Hint = '3秒前から再生' + ImageIndex = 28 + ShortCut = 16435 + OnExecute = Play3SecActionExecute + end + object Play5SecAction: TAction + Category = '再生' + Caption = '5秒前から再生(&5)' + Hint = '5秒前から再生' + ImageIndex = 29 + ShortCut = 16437 + OnExecute = Play5SecActionExecute + end + object SmoothAction: TAction + Category = '属性' + Caption = 'スムーズ(&S)' + Hint = 'リンクをスムーズにする' + ImageIndex = 30 + ShortCut = 77 + OnExecute = SmoothActionExecute + end + object BeforePrevCrossAction: TAction + Category = 'リンク前' + Caption = '前のクロッシング・ポイントへ(&A)' + Hint = '前のクロッシング・ポイントへ' + ImageIndex = 22 + ShortCut = 65 + OnExecute = BeforePrevCrossActionExecute + end + object BeforePrevFastAction: TAction + Category = 'リンク前' + Caption = '前へ20ステップ(&S)' + Hint = '前へ20ステップ' + ImageIndex = 23 + ShortCut = 83 + OnExecute = BeforePrevFastActionExecute + end + object BeforePrevStepAction: TAction + Category = 'リンク前' + Caption = '前へ1ステップ(&D)' + Hint = '前へ1ステップ' + ImageIndex = 21 + ShortCut = 68 + OnExecute = BeforePrevStepActionExecute + end + object BeforeNextStepAction: TAction + Category = 'リンク前' + Caption = '次へ1ステップ(&F)' + Hint = '次へ1ステップ' + ImageIndex = 18 + ShortCut = 70 + OnExecute = BeforeNextStepActionExecute + end + object BeforeNextFastAction: TAction + Category = 'リンク前' + Caption = '次へ20ステップ(&G)' + Hint = '次へ20ステップ' + ImageIndex = 20 + ShortCut = 71 + OnExecute = BeforeNextFastActionExecute + end + object BeforeNextCrossAction: TAction + Category = 'リンク前' + Caption = '次のクロッシング・ポイントへ(&H)' + Hint = '次のクロッシング・ポイントへ' + ImageIndex = 19 + ShortCut = 72 + OnExecute = BeforeNextCrossActionExecute + end + object AfterPrevCrossAction: TAction + Category = 'リンク後' + Caption = '前のクロッシング・ポイントへ(&Z)' + Hint = '前のクロッシング・ポイントへ' + ImageIndex = 22 + ShortCut = 90 + OnExecute = AfterPrevCrossActionExecute + end + object AfterPrevFastAction: TAction + Category = 'リンク後' + Caption = '前へ20ステップ(&X)' + Hint = '前へ20ステップ' + ImageIndex = 23 + ShortCut = 88 + OnExecute = AfterPrevFastActionExecute + end + object AfterPrevStepAction: TAction + Category = 'リンク後' + Caption = '前へ1ステップ(&C)' + Hint = '前へ1ステップ' + ImageIndex = 21 + ShortCut = 67 + OnExecute = AfterPrevStepActionExecute + end + object AfterNextStepAction: TAction + Category = 'リンク後' + Caption = '次へ1ステップ(&V)' + Hint = '次へ1ステップ' + ImageIndex = 18 + ShortCut = 86 + OnExecute = AfterNextStepActionExecute + end + object AfterNextFastAction: TAction + Category = 'リンク後' + Caption = '次へ20ステップ(&B)' + Hint = '次へ20ステップ' + ImageIndex = 20 + ShortCut = 66 + OnExecute = AfterNextFastActionExecute + end + object AfterNextCrossAction: TAction + Category = 'リンク後' + Caption = '次のクロッシング・ポイントへ(&N)' + Hint = '次のクロッシング・ポイントへ' + ImageIndex = 19 + ShortCut = 78 + OnExecute = AfterNextCrossActionExecute + end + object PlayAction: TAction + Category = '再生' + Caption = 'PlayAction' + ImageIndex = 24 + ShortCut = 32 + OnExecute = PlayActionExecute + end + end + object ApplicationEvents: TApplicationEvents + OnIdle = ApplicationEventsIdle + Left = 488 + Top = 24 + end + object WaveAreaPopupMenu: TPopupMenu + Images = TSSLoopTuner2MainForm.ImageList + Left = 520 + Top = 24 + object ZoomInMenuItem: TMenuItem + Action = ZoomInAction + end + object ZoomOutMenuItem: TMenuItem + Action = ZoomOutAction + end + object N1: TMenuItem + Caption = '-' + end + object PlayMenuItem: TMenuItem + Caption = '再生' + Default = True + ImageIndex = 24 + ShortCut = 32 + OnClick = PlayMenuItemClick + end + object StopPlayMenuItem: TMenuItem + Action = StopPlayAction + end + object PlayHalfSecMenuItem: TMenuItem + Action = PlayHalfSecAction + end + object Play1SecMenuItem: TMenuItem + Action = Play1SecAction + end + object Play2SecMenuItem: TMenuItem + Action = Play2SecAction + end + object Play3SecMenuItem: TMenuItem + Action = Play3SecAction + end + object Play5SecMenuItem: TMenuItem + Action = Play5SecAction + end + object BeforePrevCrossMenuItem: TMenuItem + Action = BeforePrevCrossAction + Break = mbBarBreak + Caption = ' ' + end + object BeforePrevFastMenuItem: TMenuItem + Action = BeforePrevFastAction + Caption = ' ' + end + object BeforePrevSepMenuItem: TMenuItem + Action = BeforePrevStepAction + Caption = ' ' + end + object BeforeNextStepMenuItem: TMenuItem + Action = BeforeNextStepAction + Caption = ' ' + end + object BeforeNextFastMenuItem: TMenuItem + Action = BeforeNextFastAction + Caption = ' ' + end + object BeforeNextCrossMenuItem: TMenuItem + Action = BeforeNextCrossAction + Caption = ' ' + end + object AfterPrevCrossMenuItem: TMenuItem + Action = AfterPrevCrossAction + Break = mbBarBreak + Caption = ' ' + end + object AfterPrevFastMenuItem: TMenuItem + Action = AfterPrevFastAction + Caption = ' ' + end + object AfterPrevSepMenuItem: TMenuItem + Action = AfterPrevStepAction + Caption = ' ' + end + object AfterNextStepMenuItem: TMenuItem + Action = AfterNextStepAction + Caption = ' ' + end + object AfterNextFastMenuItem: TMenuItem + Action = AfterNextFastAction + Caption = ' ' + end + object AfterNextCrossMenuItem: TMenuItem + Action = AfterNextCrossAction + Caption = ' ' + end + end +end diff --git a/tools/win32/krdevui/looptuner2/LinkDetailUnit.h b/tools/win32/krdevui/looptuner2/LinkDetailUnit.h new file mode 100644 index 0000000..b47148f --- /dev/null +++ b/tools/win32/krdevui/looptuner2/LinkDetailUnit.h @@ -0,0 +1,181 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef LinkDetailUnitH +#define LinkDetailUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#include "WaveReader.h" +#include "WaveLoopManager.h" +#include +#include +#include "EditLinkAttribUnit.h" +#include +//--------------------------------------------------------------------------- +class TLinkDetailForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TPanel *ToolBarPanel; + TToolBar *PosAdjustToolBar; + TToolButton *BeforePrevCrossToolButton; + TToolButton *BeforePrevFastToolButton; + TToolButton *BeforePrevStepToolButton; + TToolButton *BeforeNextStepToolButton; + TToolButton *BeforeNextFastToolButton; + TToolButton *BeforeNextCrossToolButton; + TToolButton *AfterPrevCrossToolButton; + TToolButton *AfterPrevFastToolButton; + TToolButton *AfterPrevStepToolButton; + TToolButton *AfterNextStepToolButton; + TToolButton *AfterNextFastToolButton; + TToolButton *AfterNextCrossToolButton; + TPanel *BottomPanel; + TToolBar *BottomToolBar; + TToolButton *ZoomInToolButton; + TToolButton *ZoomOutToolButton; + TButton *OKButton; + TButton *CancelButton; + TPanel *WaveAreaPanel; + TPaintBox *WavePaintBox; + TToolButton *ToolButton17; + TToolButton *ToolButton15; + TToolButton *PlayHalfSecToolButton; + TToolButton *Play1SecToolButton; + TToolButton *Play2SecToolButton; + TToolButton *Play3SecToolButton; + TToolButton *Play5SecToolButton; + TLabel *MagnifyLabel; + TActionList *ActionList; + TAction *ZoomInAction; + TAction *ZoomOutAction; + TAction *PlayHalfSecAction; + TAction *Play1SecAction; + TAction *Play2SecAction; + TAction *Play3SecAction; + TAction *Play5SecAction; + TAction *SmoothAction; + TToolButton *SmoothToolButton; + TAction *BeforePrevCrossAction; + TAction *BeforePrevFastAction; + TAction *BeforePrevStepAction; + TAction *BeforeNextStepAction; + TAction *BeforeNextFastAction; + TAction *BeforeNextCrossAction; + TToolButton *ToolButton2; + TApplicationEvents *ApplicationEvents; + TPanel *PlayBeforePaintBoxPanel; + TPaintBox *PlayBeforePaintBox; + TLabel *PlayBeforeLabel; + TEditLinkAttribFrame *EditLinkAttribFrame; + TToolButton *StopPlayToolButton; + TAction *StopPlayAction; + TLabel *AfterLinkLabel; + TLabel *BeforeLinkLabel; + TPopupMenu *WaveAreaPopupMenu; + TMenuItem *ZoomInMenuItem; + TMenuItem *ZoomOutMenuItem; + TMenuItem *N1; + TMenuItem *StopPlayMenuItem; + TMenuItem *BeforePrevCrossMenuItem; + TMenuItem *BeforePrevFastMenuItem; + TMenuItem *PlayMenuItem; + TAction *PlayAction; + void __fastcall WavePaintBoxPaint(TObject *Sender); + void __fastcall ZoomInActionExecute(TObject *Sender); + void __fastcall ZoomOutActionExecute(TObject *Sender); + void __fastcall BeforePrevCrossActionExecute(TObject *Sender); + void __fastcall BeforePrevFastActionExecute(TObject *Sender); + void __fastcall BeforePrevStepActionExecute(TObject *Sender); + void __fastcall BeforeNextStepActionExecute(TObject *Sender); + void __fastcall BeforeNextFastActionExecute(TObject *Sender); + void __fastcall BeforeNextCrossActionExecute(TObject *Sender); + void __fastcall AfterPrevCrossActionExecute(TObject *Sender); + void __fastcall AfterPrevFastActionExecute(TObject *Sender); + void __fastcall AfterPrevStepActionExecute(TObject *Sender); + void __fastcall AfterNextStepActionExecute(TObject *Sender); + void __fastcall AfterNextFastActionExecute(TObject *Sender); + void __fastcall AfterNextCrossActionExecute(TObject *Sender); + void __fastcall FormResize(TObject *Sender); + void __fastcall WavePaintBoxMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y); + void __fastcall WavePaintBoxMouseMove(TObject *Sender, TShiftState Shift, + int X, int Y); + void __fastcall WavePaintBoxMouseUp(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall PlayHalfSecActionExecute(TObject *Sender); + void __fastcall Play1SecActionExecute(TObject *Sender); + void __fastcall Play2SecActionExecute(TObject *Sender); + void __fastcall Play3SecActionExecute(TObject *Sender); + void __fastcall Play5SecActionExecute(TObject *Sender); + void __fastcall ApplicationEventsIdle(TObject *Sender, bool &Done); + void __fastcall PlayBeforePaintBoxPaint(TObject *Sender); + void __fastcall SmoothActionExecute(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall OKButtonClick(TObject *Sender); + void __fastcall CancelButtonClick(TObject *Sender); + void __fastcall StopPlayActionExecute(TObject *Sender); + void __fastcall WavePaintBoxDblClick(TObject *Sender); + void __fastcall WaveAreaPanelEnter(TObject *Sender); + void __fastcall WaveAreaPanelExit(TObject *Sender); + void __fastcall FormMouseWheel(TObject *Sender, TShiftState Shift, + int WheelDelta, TPoint &MousePos, bool &Handled); + void __fastcall PlayActionExecute(TObject *Sender); + void __fastcall PlayMenuItemClick(TObject *Sender); +private: // ユーザー宣言 + TWaveReader * FReader; // wave reader + tTVPWaveLoopManager * FManager; // wave loop manager + int LinkNum; // link number + tTVPWaveLoopLink FLink; // current editting link + tTVPWaveLoopLink FLinkOriginal; // the original information of editting link + int FMagnify; // magnification level (in logarithm based 2) + + bool WaveAreaHasFocus; + + bool Dragging; + bool BeforeOrAfter; + int FirstMouseDownPos; + int FirstMouseDownX; + + int PlayBeforeLength; + int PlayStartPos; + int PlayLastPos; + +public: // ユーザー宣言 + __fastcall TLinkDetailForm(TComponent* Owner); + void __fastcall SetReaderAndLink(TWaveReader * reader, tTVPWaveLoopLink link, int linknum); + +public: + int __fastcall PixelToSample(int pixel); + int __fastcall SampleToPixel(int sample); + +private: + void __fastcall UpdateMainWindowParams(bool push_undo = false); + void __fastcall UpdateDisplay(); + void __fastcall UpdateLayout(); + int __fastcall SearchCrossingPoint(int from, int direction); + void __fastcall StepBefore(int step); + void __fastcall StepAfter(int step); + void __fastcall PlayLink(int before, int after = 5000); + void __fastcall PlayLink(); + void __fastcall MarkPlayButton(TObject * button); + void __fastcall EditLinkAttribFrameInfoChanged(TObject * Sender); + void __fastcall EditLinkAttribFrameEraseRedo(TObject * Sender); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TLinkDetailForm *LinkDetailForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/looptuner2/LoopTunerMainUnit.cpp b/tools/win32/krdevui/looptuner2/LoopTunerMainUnit.cpp new file mode 100644 index 0000000..aa84937 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/LoopTunerMainUnit.cpp @@ -0,0 +1,1006 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop +#include + +#include "DSound.h" +#include "LoopTunerMainUnit.h" +#include "LinkDetailUnit.h" +#include "LabelDetailUnit.h" +#include "looptune.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "EditLabelAttribUnit" +#pragma link "EditLinkAttribUnit" +#pragma resource "*.dfm" +TTSSLoopTuner2MainForm *TSSLoopTuner2MainForm; +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// the tool bar icon "Follow Marker" blinks when checked. +// these are indices of icons, in ImageList +#define FOLLOW_BLINK_NORMAL 11 +#define FOLLOW_BLINK_BLINK 37 +#define FOLLOW_BLINK_BLINK2 38 + + +//--------------------------------------------------------------------------- +AnsiString __fastcall GetLongFileName(AnsiString fn) +{ + // fn をロングファイル名に変換して返す + char buf[MAX_PATH]; + char *fnp=0; + GetFullPathName(fn.c_str(),MAX_PATH,buf,&fnp); + return AnsiString(buf); +} +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +static AnsiString OrgCaption; +__fastcall TTSSLoopTuner2MainForm::TTSSLoopTuner2MainForm(TComponent* Owner) + : TForm(Owner) +{ + TotalView = new TTotalView(this); + TotalView->Parent = this; + TotalView->Align = alTop; + TotalView->Top = ClientHeight; + TotalView->OnPoint = TotalViewPoint; + TotalView->OnDoubleClick = TotalViewDoubleClick; + + Reader = new TWaveReader(); + Reader->OnReadProgress = OnReaderProgress; + InitDirectSound(Handle); + Manager = NULL; + ActiveControl = WaveView; + CreateWaveView(); + ResettingFlags = false; + + Application->HintHidePause = 24*60*60*1000; + // not to hide tool tip hint immediately + + ReadFromIni(); + Caption = OrgCaption = "Loop Tuner"; + + // open a file specified in command line argument + int i; + int paramcount = ParamCount(); + for(i=1; i<=paramcount; i++) + { + if(FileExists(ParamStr(i))) + { + OpenDialog->FileName = GetLongFileName(ParamStr(i)); + Open(); + break; + } + } +} +//--------------------------------------------------------------------------- +__fastcall TTSSLoopTuner2MainForm::~TTSSLoopTuner2MainForm() +{ +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ReadFromIni() +{ + // read information from ini file + const char * section = "Main"; + + // window position and size + ReadWindowBasicInformationFromIniFile(section, this); + + bool b; + + b = GetIniFile()->ReadBool(section, "ShowEditFlags", false); + if(b) ShowEditFlagsAction->Execute(); + + b = GetIniFile()->ReadBool(section, "ShowToolBar", true); + if(b) ShowToolBarAction->Execute(); + + b = GetIniFile()->ReadBool(section, "ShowTotalView", true); + if(b) ShowTotalViewAction->Execute(); + + b = GetIniFile()->ReadBool(section, "ShowStatusBar", true); + if(b) ShowStatusBarAction->Execute(); + + OpenDialog->InitialDir = GetIniFile()->ReadString("Folder", "InitialDir", ""); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WriteToIni() +{ + // write information to ini file + const char * section = "Main"; + WriteWindowBasicInformationToIniFile(section, this); + GetIniFile()->WriteBool(section, "ShowEditFlags", ShowEditFlagsAction->Checked); + GetIniFile()->WriteBool(section, "ShowToolBar", ShowToolBarAction->Checked); + GetIniFile()->WriteBool(section, "ShowTotalView", ShowTotalViewAction->Checked); + GetIniFile()->WriteBool(section, "ShowStatusBar", ShowStatusBarAction->Checked); + + if(OpenDialog->FileName != "") + { + GetIniFile()->WriteString("Folder", "InitialDir",ExtractFilePath( + OpenDialog->FileName)); + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FormShow(TObject *Sender) +{ + DragAcceptFiles(Handle,true); +} +//--------------------------------------------------------------------------- +bool __fastcall TTSSLoopTuner2MainForm::GetCanClose() +{ + // get whether the document can be closed + if(!Manager) return true; + if(WaveView->Modified) + { + int r = MessageDlg("ファイル " + FileName + ".sli は変更されています。\n" + "変更を保存しますか?", mtWarning, TMsgDlgButtons() << mbYes << mbNo << mbCancel, 0); + if(r == mrYes) + { + SaveAction->Execute(); + } + else if(r == mrCancel) + { + return false; + } + } + return true; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FormClose(TObject *Sender, + TCloseAction &Action) +{ + WriteToIni(); + StopPlay(); + FreeDirectSound(); + WaveView->ClearAll(); + if(Manager) delete Manager, Manager = NULL; + delete Reader; +// if(WaveView) delete WaveView; // the framework will free this +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + CanClose = GetCanClose(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::CloseActionExecute(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ShowHelpActionExecute( + TObject *Sender) +{ + ShellExecute(NULL,"open", (ExtractFilePath(ParamStr(0)) + + "..\\kr2doc\\contents\\LoopTuner.html").c_str(), + NULL,"",SW_SHOWNORMAL); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ShowAboutActionExecute( + TObject *Sender) +{ + static VS_FIXEDFILEINFO *FixedFileInfo; + static BYTE VersionInfo[16384]; + static AnsiString VersionString; + long VersionNumber; + + static bool DoGet=true; + if(DoGet) + { + DoGet=false; + + UINT dum; + + char krdevui_path[MAX_PATH+1]; + if(0 == GetModuleFileName(GetModuleHandle("krdevui.dll"), krdevui_path, MAX_PATH)) + GetModuleFileName(GetModuleHandle("looptune.exe"), krdevui_path, MAX_PATH); + + GetFileVersionInfo(krdevui_path,0,16384,(void*)VersionInfo); + VerQueryValue((void*)VersionInfo,"\\",(void**)(&FixedFileInfo), + &dum); + + char *buf; + VerQueryValue((void*)VersionInfo, + "\\StringFileInfo\\041103A4\\FileVersion", + (void**)&buf,&dum); + VersionString=buf; + } + + MessageDlg("Loop Tuner 2 version " + VersionString + + " (C) 2000 W.Dee All rights reserved.\n" + "各プラグインのバージョン情報は plugin フォルダの中の" + "各 DLL のプロパティを参照してください", + mtInformation, TMsgDlgButtons() << mbOK, 0); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::CreateWaveView() +{ + if(!WaveView) + { + WaveView = new TWaveView(this); + WaveView->Parent = this; + WaveView->Align = alClient; + } + + WaveView->ClearAll(); + WaveView->Reader = NULL; + WaveView->OnStopFollowingMarker = WaveViewStopFollowingMarker; + WaveView->OnRangeChanged = WaveViewRangeChanged; + WaveView->OnCaretStateChanged = WaveViewCaretStateChanged; + WaveView->OnMarkerStateChanged = WaveViewMarkerStateChanged; + WaveView->OnWaveDoubleClick = WaveViewWaveDoubleClick; + WaveView->OnLinkDoubleClick = WaveViewLinkDoubleClick; + WaveView->OnLabelDoubleClick = WaveViewLabelDoubleClick; + WaveView->OnNotifyPopup = WaveViewNotifyPopup; + WaveView->OnShowCaret = WaveViewShowCaret; + WaveView->OnLinkSelected = WaveViewLinkSelected; + WaveView->OnLabelSelected = WaveViewLabelSelected; + WaveView->OnSelectionLost = WaveViewSelectionLost; + WaveView->OnLinkModified = WaveViewLinkModified; + WaveView->OnLabelModified = WaveViewLabelModified; + + ActiveControl = WaveView; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ApplicationEventsHint(TObject *Sender) +{ + StatusBar->Panels->Items[4]->Text = GetLongHint(Application->Hint); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::OnReaderProgress(TObject *sender) +{ + int pct = Reader->SamplesRead / (Reader->NumSamples / 100); + if(pct > 100) pct = 100; + Caption = ExtractFileName(FileName) + " - 読み込み中 " + AnsiString(pct) + "%"; + if(Reader->ReadDone) + { + WaveView->Reader = Reader; // reset the reader + TotalView->Reader = Reader; + Manager->SetDecoder(Reader); + + // note that below two wiil call OnLinkModified/OnLabelModified event. + // but it's ok because the handler will write back the same data to the waveview. + WaveView->SetLinks(Manager->GetLinks()); + WaveView->SetLabels(Manager->GetLabels()); + TotalView->SetLinks(WaveView->GetLinks()); + TotalView->SetLabels(WaveView->GetLabels()); + WaveView->PushFirstUndoState(); + + WaveView->SetInitialMagnify(); + StatusBar->Panels->Items[0]->Text = WaveView->GetMagnifyString(); + + Caption = ExtractFileName(FileName) + " - " + OrgCaption; + Application->Title = Caption; + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::Open() +{ + // check the extension ".sli" + if(OpenDialog->FileName.Length() >= 4) + { + if(!_mbsicmp(OpenDialog->FileName.c_str() + + (OpenDialog->FileName.Length() - 4), ".sli")) + { + AnsiString n = OpenDialog->FileName; + n.SetLength(n.Length() - 4); + OpenDialog->FileName = n; + } + } + + FileName = OpenDialog->FileName; + + // stop playing + StopPlay(); + + // reset all + Caption = OrgCaption; + Application->Title = Caption; + CreateWaveView(); + TotalView->ResetAll(); + FollowMarkerAction->Checked = true; + + // create manager + if(Manager) delete Manager, Manager = NULL; + Manager = new tTVPWaveLoopManager(); + IgnoreLinksAction->Checked = false; + FlagsClearSpeedButtonClick(this); + + // load link and label information + if(FileExists(FileName + ".sli")) + { + char *mem = NULL; + TFileStream *fs = new TFileStream(FileName + ".sli", fmShareDenyWrite | fmOpenRead); + try + { + try + { + // load into memory + int size = fs->Size; + mem = new char [size + 1]; + fs->Read(mem, size); + mem[size] = '\0'; + } + catch(...) + { + delete fs; + throw; + } + delete fs; + + // read from the memory + if(!Manager->ReadInformation(mem))// note that this method can destory the buffer + { + throw Exception(FileName + ".sli は文法が間違っているか、" + "不正な形式のため、読み込むことができません"); + } + } + catch(...) + { + if(mem) delete [] mem; + throw; + } + if(mem) delete [] mem; + } + + // load wave + Reader->LoadWave(FileName); +} +//--------------------------------------------------------------------------- + +void __fastcall TTSSLoopTuner2MainForm::OpenActionExecute(TObject *Sender) +{ + if(!GetCanClose()) return; + OpenDialog->Filter = Reader->FilterString; + if(OpenDialog->Execute()) + { + Open(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::SaveActionExecute(TObject *Sender) +{ + // save current loop information + TFileStream * fs = new TFileStream(FileName + ".sli" , fmShareDenyWrite | fmCreate); + try + { + Manager->SetLinks(WaveView->GetLinks()); + Manager->SetLabels(WaveView->GetLabels()); + AnsiString str; + Manager->WriteInformation(str); + fs->Write(str.c_str(), str.Length()); + WaveView->Modified = false; + } + catch(...) + { + delete fs; + throw; + } + delete fs; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WMDoOpen(TMessage &msg) +{ + if(!GetCanClose()) return; + Open(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WMShowFront(TMessage &msg) +{ + Application->Restore(); + Application->BringToFront(); + this->BringToFront(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WMCopyData(TWMCopyData &msg) +{ + if(msg.CopyDataStruct->dwData == 0x746f8ab3) + { + if(msg.CopyDataStruct->lpData && msg.CopyDataStruct->cbData >= 6 && + !memcmp((const char*)msg.CopyDataStruct->lpData, "open:", 5)) + { + // open action + const char *filename = (const char*)(msg.CopyDataStruct->lpData) + 5; + + OpenDialog->FileName = GetLongFileName(filename); + ::PostMessage(Handle, WM_DOOPEN, 0, 0); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WMDropFiles(TMessage &msg) +{ + HDROP hd=(HDROP)msg.WParam; + + char FileName[ MAX_PATH ]; + int FileCount= + DragQueryFile(hd,0xFFFFFFFF,NULL,MAX_PATH); + //いくつ落とされたか + + for(int i=FileCount-1;i>=0;i--) + { + DragQueryFile(hd, i, FileName, MAX_PATH ); + WIN32_FIND_DATA fd; + HANDLE h; + if((h = FindFirstFile(FileName,&fd))!=INVALID_HANDLE_VALUE) + { + FindClose(h); + + DragFinish(hd); + + OpenDialog->FileName = GetLongFileName(FileName); + ::PostMessage(Handle, WM_DOOPEN, 0, 0); + + return; + } + + } + DragFinish(hd); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ZoomInActionExecute(TObject *Sender) +{ + WaveView->Magnify ++; + StatusBar->Panels->Items[0]->Text = WaveView->GetMagnifyString(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ZoomOutActionExecute(TObject *Sender) +{ + WaveView->Magnify --; + StatusBar->Panels->Items[0]->Text = WaveView->GetMagnifyString(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::UndoActionExecute(TObject *Sender) +{ + WaveView->Undo(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::RedoActionExecute(TObject *Sender) +{ + WaveView->Redo(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::DeleteActionExecute(TObject *Sender) +{ + WaveView->DeleteItem(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::NewLinkActionExecute(TObject *Sender) +{ + WaveViewStopFollowingMarker(this); + WaveView->CreateNewLink(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::NewLabelActionExecute(TObject *Sender) +{ + WaveViewStopFollowingMarker(this); + WaveView->CreateNewLabel(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::EditLinkDetailActionExecute( + TObject *Sender) +{ + WaveView->PerformLinkDoubleClick(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::EditLabelDetailActionExecute( + TObject *Sender) +{ + WaveView->PerformLabelDoubleClick(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ClearAllLabelsActionExecute(TObject *Sender) +{ + WaveView->ClearAllLabels(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::NewLinkOnPlayActionExecute( + TObject *Sender) +{ + int pos = (int)GetCurrentPlayingPos(); + if(pos != -1) + WaveView->CreateNewLabel(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::PlayFromStartActionExecute(TObject *Sender) +{ + PlayFrom(0); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::PlayFromCaretActionExecute( + TObject *Sender) +{ + PlayFrom(WaveView->CaretPos); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::StopPlayActionExecute(TObject *Sender) +{ + StopPlay(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ShowEditFlagsActionExecute( + TObject *Sender) +{ + ShowEditFlagsAction->Checked = !ShowEditFlagsAction->Checked; + FlagsPanel->Visible = ShowEditFlagsAction->Checked; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ShowStatusBarActionExecute( + TObject *Sender) +{ + ShowStatusBarAction->Checked = !ShowStatusBarAction->Checked; + StatusBar->Visible = ShowStatusBarAction->Checked; +} +//--------------------------------------------------------------------------- + +void __fastcall TTSSLoopTuner2MainForm::ShowTotalViewActionExecute( + TObject *Sender) +{ + ShowTotalViewAction->Checked = !ShowTotalViewAction->Checked; + TotalView->Visible = ShowTotalViewAction->Checked; +} +//--------------------------------------------------------------------------- + +void __fastcall TTSSLoopTuner2MainForm::ShowToolBarActionExecute( + TObject *Sender) +{ + ShowToolBarAction->Checked = !ShowToolBarAction->Checked; + ToolBar->Visible = ShowToolBarAction->Checked; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::IgnoreLinksActionExecute( + TObject *Sender) +{ + IgnoreLinksAction->Checked = !IgnoreLinksAction->Checked; + if(Manager) Manager->SetIgnoreLinks(IgnoreLinksAction->Checked); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::PlayFrom(int pos) +{ + if(Reader->ReadDone) + { + StopPlay(); + const WAVEFORMATEXTENSIBLE * wfx; + wfx = Reader->GetWindowsFormat(); + Manager->SetPosition(pos); + WaveView->ResetMarkerFollow(); + StartPlay(wfx, Manager); + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::BlinkTimerTimer(TObject *Sender) +{ + if(FollowMarkerAction->Checked && (int)GetCurrentPlayingPos() != -1) + { + FollowMarkerToolButton->ImageIndex = + ((GetTickCount() / 500) & 1) ? FOLLOW_BLINK_BLINK2 : FOLLOW_BLINK_BLINK; + } + else + { + FollowMarkerToolButton->ImageIndex = FOLLOW_BLINK_NORMAL; + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FollowMarkerActionExecute( + TObject *Sender) +{ + FollowMarkerAction->Checked = !FollowMarkerAction->Checked; + WaveView->FollowingMarker = FollowMarkerAction->Checked; + FollowMarkerToolButton->ImageIndex = FOLLOW_BLINK_NORMAL; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewStopFollowingMarker(TObject *Sender) +{ + FollowMarkerAction->Checked = false; + WaveView->FollowingMarker = FollowMarkerAction->Checked; + FollowMarkerToolButton->ImageIndex = FOLLOW_BLINK_NORMAL; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewRangeChanged(TObject *Sender, int start, int length) +{ + TotalView->SetViewRange(start, length); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewCaretStateChanged(TObject *Sender, int pos, bool visible) +{ + TotalView->SetCaretState(pos, visible); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewMarkerStateChanged(TObject *Sender, int pos, bool visible) +{ + TotalView->SetMarkerState(pos, visible); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::GotoLinkFromActionExecute( + TObject *Sender) +{ + if(WaveView->FocusedLink != -1) + { + WaveViewStopFollowingMarker(this); + WaveView->CaretPos = WaveView->GetLinks()[WaveView->FocusedLink].From; + WaveView->EnsureView(WaveView->CaretPos); + WaveView->ShowCaret = true; + } +} +//--------------------------------------------------------------------------- + +void __fastcall TTSSLoopTuner2MainForm::GotoLinkToActionExecute( + TObject *Sender) +{ + if(WaveView->FocusedLink != -1) + { + WaveViewStopFollowingMarker(this); + WaveView->CaretPos = WaveView->GetLinks()[WaveView->FocusedLink].To; + WaveView->EnsureView(WaveView->CaretPos); + WaveView->ShowCaret = true; + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ApplicationEventsIdle(TObject *Sender, + bool &Done) +{ + int pos = (int)GetCurrentPlayingPos(); + + if(pos != -1) + { + Sleep(1); // this will make the cpu usage low + Done = false; + + WaveView->MarkerPos = pos; + + StatusBar->Panels->Items[3]->Text = "再生中 " + Reader->SamplePosToTimeString(pos); + StopPlayAction->Enabled = true; + NewLinkOnPlayAction->Enabled = true; + } + else + { + Done = true; + WaveView->MarkerPos = -1; + + StatusBar->Panels->Items[3]->Text = "停止"; + StopPlayAction->Enabled = false; + NewLinkOnPlayAction->Enabled = false; + } + + UndoAction->Enabled = WaveView->CanUndo(); + RedoAction->Enabled = WaveView->CanRedo(); + DeleteAction->Enabled = WaveView->CanDeleteItem(); + EditLinkDetailAction->Enabled = WaveView->FocusedLink != -1; + EditLabelDetailAction->Enabled = WaveView->FocusedLabel != -1; + GotoLinkFromAction->Enabled = WaveView->FocusedLink != -1; + GotoLinkToAction->Enabled = WaveView->FocusedLink != -1; + ClearAllLabelsAction->Enabled = WaveView->GetLabels().size() != 0; + + bool en = Reader && Reader->ReadDone; + SaveAction ->Enabled = en; + PlayFromCaretAction ->Enabled = en; + PlayFromStartAction ->Enabled = en; + ZoomInAction ->Enabled = en; + ZoomOutAction ->Enabled = en; + NewLinkAction ->Enabled = en; + NewLabelAction ->Enabled = en; + + if(Manager && Manager->GetFlagsModifiedByLabelExpression()) ResetFlagsEditFromLoopManager(); + + POINT mouse_pt; + GetCursorPos(&mouse_pt); + mouse_pt = WaveView->ScreenToClient(*(TPoint*)&mouse_pt); + AnsiString cursor_pos, cursor_ch; + WaveView->GetPositionStringAt(mouse_pt.x, mouse_pt.y, cursor_pos, cursor_ch); + + StatusBar->Panels->Items[1]->Text = cursor_ch; + StatusBar->Panels->Items[2]->Text = cursor_pos; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewWaveDoubleClick(TObject *Sender, int pos) +{ + PlayFrom(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewLinkDoubleClick(TObject *Sender, int num, tTVPWaveLoopLink &link) +{ + bool org_waveview_followingmarker = WaveView->FollowingMarker; + WaveView->FollowingMarker = true; // temporarily enable the marker + + TLinkDetailForm * ldf = new TLinkDetailForm(this); + try + { + ldf->SetReaderAndLink(Reader, link, num); + ldf->ShowModal(); + } + catch(...) + { + WaveView->FollowingMarker = org_waveview_followingmarker; + delete ldf; + throw; + } + WaveView->FollowingMarker = org_waveview_followingmarker; + delete ldf; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewLabelDoubleClick(TObject *Sender, + int num, tTVPWaveLabel &label) +{ + TLabelDetailForm * ldf = new TLabelDetailForm(this); + try + { + ldf->SetLabel(label); + if(ldf->ShowModal() == mrOk) + { + WaveView->InvalidateLabel(num); + label = ldf->GetLabel(); + WaveView->NotifyLabelChanged(); + WaveView->InvalidateLabel(num); + WaveView->PushUndo(); //==== push undo + } + } + catch(...) + { + delete ldf; + throw; + } + delete ldf; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewNotifyPopup(TObject *Sender, AnsiString type, + const TPoint &point) +{ + if(type == "Link") + { + ForLinkPopupMenu->Popup(point.x, point.y); + } + else if(type == "Label") + { + ForLabelPopupMenu->Popup(point.x, point.y); + } + else if(type == "Wave") + { + ForWavePopupMenu->Popup(point.x, point.y); + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewShowCaret(TObject *Sender, int pos) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewLinkSelected(TObject *Sender, int num, tTVPWaveLoopLink &link) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewLabelSelected(TObject *Sender, int num, tTVPWaveLabel &label) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewSelectionLost(TObject *Sender) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewLinkModified(TObject *Sender) +{ + Manager->SetLinks(WaveView->GetLinks()); + TotalView->SetLinks(WaveView->GetLinks()); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::WaveViewLabelModified(TObject *Sender) +{ + Manager->SetLabels(WaveView->GetLabels()); + TotalView->SetLabels(WaveView->GetLabels()); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::TotalViewPoint(TObject *Sender, int pos) +{ + WaveViewStopFollowingMarker(this); + WaveView->SetView(pos); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FlagsEditToggleMenuItemClick( + TObject *Sender) +{ + TEdit *edit = dynamic_cast(ActiveControl); + if(edit) + { + if(edit->Text.ToInt()) + edit->Text = "0"; + else + edit->Text = "1"; + edit->SelStart = 1; + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FlagEdit15Enter(TObject *Sender) +{ + // select nothing + WaveView->ShowCaret = false; + WaveView->FocusedLink = -1; + WaveView->FocusedLabel = -1; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FlagEdit0DblClick(TObject *Sender) +{ + TEdit *edit = dynamic_cast(ActiveControl); + if(edit) + { + if(edit->Text.ToInt()) + edit->Text = "0"; + else + edit->Text = "1"; + edit->SelStart = 1; + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FlagsEditZeroMenuItemClick( + TObject *Sender) +{ + TEdit *edit = dynamic_cast(ActiveControl); + if(edit) + edit->Text = "0"; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FlasgEditOneMenuItemClick(TObject *Sender) +{ + TEdit *edit = dynamic_cast(ActiveControl); + if(edit) + edit->Text = "1"; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FlagEdit0MouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + TWinControl *control = dynamic_cast(Sender); + if(control) control->SetFocus(); +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FlagEdit0Change(TObject *Sender) +{ + if(ResettingFlags) return; + + TEdit *edit = dynamic_cast(Sender); + if(edit) + { + if(edit->Text == "") + { + edit->Text = "0"; + edit->SelStart = 1; + } + + if(edit->Text != "0" && edit->Text.c_str()[0] == '0') + { + edit->Text = AnsiString(edit->Text.ToInt()); + edit->SelStart = edit->Text.Length(); + } + + if(edit->Text.ToInt() > TVP_WL_MAX_FLAG_VALUE) + edit->Text = AnsiString(TVP_WL_MAX_FLAG_VALUE); + } + + // refrect all controls + if(Manager) + { + int count = FlagsPanel->ControlCount; + for(int i = 0; i < count ; i++) + { + TControl * comp = FlagsPanel->Controls[i]; + TEdit * edit = dynamic_cast(comp); + if(edit) + { + if(edit->Name.AnsiPos("FlagEdit") == 1) + { + int num = atoi(edit->Name.c_str() + 8); + Manager->SetFlag(num, edit->Text.ToInt()); + } + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FlagEdit0KeyPress(TObject *Sender, + char &Key) +{ + if(!(Key >= '0' && Key <= '9' || Key < 0x20)) Key = 0; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::ResetFlagsEditFromLoopManager() +{ + // display flags from waveloopmanager + if(!Manager) return; + + ResettingFlags = true; + tjs_int flags[TVP_WL_MAX_FLAGS]; + Manager->CopyFlags(flags); + + int count = FlagsPanel->ControlCount; + for(int i = 0; i < count ; i++) + { + TControl * comp = FlagsPanel->Controls[i]; + TEdit * edit = dynamic_cast(comp); + if(edit) + { + if(edit->Name.AnsiPos("FlagEdit") == 1) + { + int num = atoi(edit->Name.c_str() + 8); + edit->Text = AnsiString(flags[num]); + } + } + } + ResettingFlags = false; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::FlagsClearSpeedButtonClick( + TObject *Sender) +{ + ResettingFlags = true; + + int count = FlagsPanel->ControlCount; + for(int i = 0; i < count ; i++) + { + TControl * comp = FlagsPanel->Controls[i]; + TEdit * edit = dynamic_cast(comp); + if(edit) + { + if(edit->Name.AnsiPos("FlagEdit") == 1) + { + edit->Text = "0"; + } + } + } + + if(Manager) Manager->ClearFlags(); + + ResettingFlags = false; +} +//--------------------------------------------------------------------------- +void __fastcall TTSSLoopTuner2MainForm::TotalViewDoubleClick(TObject *Sender, int pos) +{ + PlayFrom(pos); + if(!FollowMarkerAction->Checked) FollowMarkerActionExecute(this); +} +//--------------------------------------------------------------------------- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/win32/krdevui/looptuner2/LoopTunerMainUnit.dfm b/tools/win32/krdevui/looptuner2/LoopTunerMainUnit.dfm new file mode 100644 index 0000000..55e90ab --- /dev/null +++ b/tools/win32/krdevui/looptuner2/LoopTunerMainUnit.dfm @@ -0,0 +1,2086 @@ +object TSSLoopTuner2MainForm: TTSSLoopTuner2MainForm + Left = 61 + Top = 23 + Width = 638 + Height = 354 + Caption = '(//designing//)' + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + Icon.Data = { + 000001000500101000000100200068040000560000003030000001002000A825 + 0000BE0400002020000001002000A8100000662A00002020100001000400E802 + 00000E3B0000101010000100040028010000F63D000028000000100000002000 + 0000010020000000000040040000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000080000000A000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000001B67005D0206001C0000001C000000090000 + 000E000000060000000300000000000000000000000000000000000000000000 + 000000000000000000000000000035CC00DB30B600C600394D610079B2DC007A + C9FF0059A6D50012253600000003000000000000000000000000000000000000 + 000000000000000000000B2A002640F200FF2DCC28FF01A7D9FF008FD0FC0075 + C1F70075DEFF00489CC50000000E000000000000000000000000000000000000 + 00000000000000000000289A006F3AE409FF03B5CDFF119E77FF248E04BF0000 + 0028004C95B8005BCBFF00060F2F000000000000000000000000000000000000 + 0000000000000000000033C200B915BC7AFF0DAB90FF39DA00FF42FA00FF2BA2 + 00B2000B173F005ACCFF0023585C000000000000000000000000000000000000 + 0000000000000000000B2FBD0AF701C2D5FF30C50EFF3DE900FF43FF00FF43FE + 00FF299C00AB004BAEF000296871000000060000000000000000000000000000 + 0000000000001D6D004D20CC56FF11BE8AFF3ADF00FF40F500FF43FF00FF43FF + 00FF43FD00FF198354FF00245B6B0000001A0000000500000000000000000000 + 0000000000002FB400970EC99DFF23C03DFF3AE000FF43FE00FF43FF00FF43FF + 00FF43FF00FF42FC00FF258B00A10000001C0000001900000004000000000000 + 00000000000035C800E001CCCFFF2FBE0DFF3CE600FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF42FA00FF248A00930000001C00000017000000010000 + 00000D32002B39D900FF00DCE5FF32C200FF3DEA00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF41F800FF268F008100000000000000000000 + 00002A9E00743ADD00FF00E9F2FF2FBB06FF3EEC00FF43FF00FF43FF00FF43FF + 00FF43FF00FF3BE000FB34C800C92EAE008A1A65004B00000002000000000000 + 000033C400BE3FEF00FF00D7E0FF22B93BFF3DE900FF3ADE00FA34C700C71A8D + 4AF0095D6FDD0000000F00000000000000000000000000000000000000000000 + 000E3BDF00FA3ADD00F905BCB2F504BCBCFE0C40157F000305320062929A0080 + D3FE003A694A0000000000000000000000000000000000000000000000000615 + 0019185B00430000000A008A927400DDF6FF00BCE2FF00A1D5FF009AE0FF0054 + 867C000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000004008EA19800A5C7F7008FBCDB0055795C0000 + 000000000000000000000000000000000000000000000000000000000000FDFF + 0000F17F0000F01F0000E00F0000E00F0000E00F0000C00F0000C0070000C003 + 0000C00100008003000080030000801F0000003F0000007F0000F0FF00002800 + 0000300000006000000001002000000000008025000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000E000000050000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000180000001A0000000400000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000040000001C0000001C0000001900000004000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000001F0000 + 0000000000000000000C0000001C0000001C0000001C00000019000000030000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000A2600B50512 + 007700000000000000140000001C0000001C0000001C0000001C000000180000 + 0003000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000009217F00F630B6 + 00FF040E006F0000001B0000001C0000001C0000001C0000001C0000001C0000 + 0018000000040000002200000037000000270000000D00000013000000160000 + 0012000000060000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000004933C400FF43FF + 00FF2EAF00FE020900760000001C0000001C0000001C0000001C0000003A0012 + 1B9E004163EB005B8FFF0062A2FF005591FF003661EC000A1393000000280000 + 001C0000001C0000000B00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000081F009342FC00FF43FF + 00FF43FF00FF2CA700FD0206006E0000001C00000022000F1492005B81FA0098 + DEFF0098E6FF0091E4FF008AE3FF0083E1FF007CDFFF006BCAFF002549DF0000 + 003D0000001C0000001C00000006000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000001B6600DC43FF00FF43FF + 00FF43FF00FF43FF00FF2AA000FC0103007A002D3CCE0096CCFF00A6E9FF009F + E8FF0098E6FF0091E4FF008AE3FF0083E1FF007CDFFF0075DEFF006DD9FF0026 + 4FE4000000300000001C00000015000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000272AA200FF43FF00FF43FF + 00FF43FF00FF43FF00FF3ADD00FF064F4AFF00ADE4FF00ADEBFF00A6E9FF009F + E8FF0098E6FF0091E4FF008AE3FF0083E1FF007CDFFF0075DEFF006EDCFF0063 + D1FF00132ABA0000001C0000001C000000050000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000010500713DE900FF43FF00FF43FF + 00FF43FF00FF3CE600FF095C4AFF00B7EAFF00B4EDFF00ADEBFF00A6E9FF009F + E8FF0098E6FF0091E4FF008AE3FF0083E1FF007CDFFF0075DEFF006EDCFF0067 + DAFF004498FF000000580000001C0000000E0000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000134A00BA43FF00FF43FF00FF43FF + 00FF41F700FF0E5F34FF00BBE8FF00BBEEFF00B4EDFF00ADEBFF00A1E2FF0066 + 95FF004061E5003452D0003C63EA0060A5FF007CDFFF0075DEFF006EDCFF0067 + DAFF0060D8FF001634C00000001C000000140000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000C228300F843FF00FF43FF00FF43FF + 00FF1B7814FF00B3D7FF00C1F0FF00BBEEFF00B4EDFF00769FFF0C4219FF0000 + 00760000001C0000001C0000001D0000005F003057E60072D8FF006EDCFF0067 + DAFF0060D9FF00337AFD00000033000000190000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000004E35C900FF43FF00FF43FF00FF2FB4 + 00FF008FA8FF00C8F2FF00C1F0FF00B9EDFF045F69FF299E00FF3ADF00FF1B69 + 00F1000000490000001C0000001C0000001C00000036002E59E8006EDCFF0067 + DAFF0060D9FF004EBCFF000000750000001C0000000100000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000A24009842FD00FF43FF00FF40F300FF0866 + 55FF00CFF3FF00C8F2FF00C1EFFF055D5DFF30B800FF3ADF00FF3ADF00FF3FF0 + 00FF1D6F00ED000000430000001C0000001C0000001C0000005D004D9CFF0067 + DAFF0060D9FF0059D7FF000F26AB0000001C0000000200000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000001C6900E143FF00FF43FF00FF20840CFF00C1 + DCFF00CFF3FF00C8F2FF026D7BFF2EB200FF3ADF00FF3ADF00FF3BE300FF43FE + 00FF43FD00FF1B6800E90000003E0000001C0000001C0000001C001F3FCB0067 + DAFF0060D9FF0059D7FF002050D60000001C0000000400000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000002C2CA700FF43FF00FF3CE500FF02777BFF00D6 + F5FF00CFF3FF0095B4FF258F02FF3ADF00FF3ADF00FF3ADF00FF3FF200FF43FF + 00FF43FF00FF42FC00FE196000E60000003A0000001C0000001C000001750059 + BDFF0060D9FF0059D7FF002866F60000001D0000000400000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000020700763EED00FF43FF00FF1D7D11FF00D1E9FF00D6 + F5FF00C7E9FF13621EFF3ADF00FF3ADF00FF3ADF00FF3BE200FF43FE00FF43FF + 00FF43FF00FE43FF00FF42FA00FF175900E2000000360000001C00000035003D + 82FF0060D9FF0059D7FF002F79FF0000002B0000000300000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000154E00BF43FF00FF3EEC00FF037878FF00DDF7FF00D6 + F5FF037177FF35CA00FF3ADF00FF3ADF00FF3ADF00FF3FF000FF43FF00FF43FF + 00FF43FF00FE43FF00FF43FF00FF41F800FF165300DD000000320000001C002C + 5FEA0060D9FF0059D7FF003587FF000000390000000D00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000F238700FA43FF00FF248E05FF00CDE0FF00DDF7FF00C4 + DFFF1F7F0AFF3ADF00FF3ADF00FF3ADF00FF3AE000FF42FD00FF43FF00FF43FF + 00FF43FF00FE43FF00FF43FF00FF43FF00FF41F600FF144C00D90000002E0022 + 49CA0060D9FF0059D7FF00378DFF000000400000001C0000000C000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000005436CE00FF43FE00FF0A7051FF00E4F8FF00DDF7FF0372 + 74FF39DB00FF3ADF00FF3ADF00FF3ADF00FF3DEA00FF43FF00FF43FF00FF43FF + 00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF40F300FF124600D40018 + 33C60060D9FF0059D7FF00378CFF000000400000001C0000001C0000000B0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000B2A009D43FE00FF34C500FF00A3AEFF00E4F8FF00D6EEFF1C7A + 12FF3BE200FF3ADF00FF3ADF00FF3ADF00FF41F700FF43FF00FF43FF00FF43FF + 00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF3FF000FF0E3D + 14FF005BCDFF0059D7FF003485FF000000380000001C0000001C0000001C0000 + 000A000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000011D6D00E643FF00FF1D7E10FF00E5F4FF00E4F8FF0091A1FF34C7 + 00FF3ADF00FF3ADF00FF3ADF00FF3BE200FF43FF00FF43FF00FF43FF00FF43FF + 00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF3EEC + 00FF0C4534FF0055CEFF002F77FF000000290000001C0000001C0000001C0000 + 001C000000090000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000312DAC00FF43FF00FF097558FF00EBFAFF00E4F8FF0B6F4BFF3EEC + 00FF3ADF00FF3ADF00FF3ADF00FF3EEC00FF43FF00FF43FF00FF43FF00FF43FF + 00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF3DE900FF0B4039FF002560F70000001C0000001C0000001C0000001C0000 + 001C0000001B0000000800000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000030A007B3FF000FF39D900FF00999FFF00EBFAFF00DCEFFF208309FF3BE2 + 00FF3ADF00FF3ADF00FF3ADF00FF40F600FF43FF00FF43FF00FF43FF00FE43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF3CE400FF0A2703EA000000210000001C0000001C0000001C0000 + 001C0000001C0000001B00000007000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000165300C543FF00FF289900FF00D7DFFF00EBFAFF00A7B5FF31BB00FF3ADF + 00FF3ADF00FF3ADF00FF3AE000FF43FE00FF43FF00FF43FF00FF43FF00FE43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF3BE000FF0B2B00B50000001F0000001C0000001C0000 + 001C0000001C0000001C0000001B000000070000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0012258B00FC43FF00FF197C1DFF00F2FCFF00EBFAFF02787BFF3DE900FF3ADF + 00FF3ADF00FF3ADF00FF3CE600FF43FF00FF43FF00FF43FF00FF43FF00FE43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF3ADB00FF0A2600AE0000001E0000001C0000 + 001C0000001C0000001C0000001C0000001A0000000600000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 005937D300FF43FF00FF0C7B50FF00F2FCFF00EBFAFF0D764AFF3DE800FF3ADF + 00FF3ADF00FF3ADF00FF3EED00FF43FF00FF43FF00FF43FF00FE43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF38D600FF092100A70000001D0000 + 001C0000001C0000001C0000001C0000001C0000001A00000005000000000000 + 0000000000000000000000000000000000000000000000000000000000000C2F + 00A243FF00FF42FB00FF027E7BFF00F2FCFF00EBFAFF187B23FF3BE100FF3ADF + 00FF3ADF00FF3ADF00FF40F400FF43FF00FF43FF00FF43FF00FE43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF37D000FF081D009F0000 + 001C0000001C0000001C0000001C0000001C0000001C0000001A000000050000 + 0000000000000000000000000000000000000000000000000000000000021E71 + 00EA43FF00FF3ADD00FF009CA0FF00F2FCFF00EAF9FF1F7B06FF3ADF00FF3ADF + 00FF3ADF00FF3ADF00FF41F900FF43FF00FF43FF00FF43FF00FE43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF35CA00FF0618 + 00970000001C0000001C0000001C0000001C0000001800000011000000080000 + 0000000000000000000000000000000000000000000000000000000000362EB1 + 00FF43FF00FF32BF00FF00BABDFF00F2FCFF00DDEAFF238500FF3ADF00FF3ADF + 00FF3ADF00FF3ADF00FF43FE00FF43FF00FF43FF00FE43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF33C4 + 00FF0515008E000000110000000A000000030000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000040E008040F3 + 00FF43FF00FF2CA900FF00D0D3FF00F2FCFF00D3DFFF248B00FF3ADF00FF3ADF + 00FF3ADF00FF3BE100FF43FF00FF43FF00FF43FF00FE43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF32BD00FF0513007700000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000175700CA43FF + 00FF43FF00FF299B00FF00DEE2FF00F2FCFF00D2DFFF238800FF3ADF00FF3ADF + 00FF3ADF00FF3BE400FF43FF00FF43FF00FF43FF00FE43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF30B600FF040F006E000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000016269000FD43FF + 00FF43FF00FF279400FF00E5E9FF00F2FCFF00DDEAFF217E00FF3ADF00FF3ADF + 00FF3ADF00FF3CE500FF43FF00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF3ADC + 00FF299C00FF1C6A00E1061900A0000000110000000000000000000000000000 + 000000000000000000000000000000000000000000000000005E39D800FF43FF + 00FF43FF00FF279500FF00E4E8FF00F2FCFF00EAF9FF1B7008FF3ADF00FF3ADF + 00FF3ADF00FF3CE500FF43FF00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF39D900FF289A00FF1B6800DE0C2D009F0000 + 0060000000210000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000E3500A743FF00FF43FF + 00FF43FF00FF2A9E00FF00DBDFFF00F2FCFF00EBFAFF126F2DFF3ADF00FF3ADF + 00FF3ADF00FF3BE400FF43FF00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FE00FF38D7 + 00FF289800FF1B6700DC0B2A009C0000005D0000001E00000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000041F7400ED43FF00FF43FF + 00FF43FF00FF2EB100FF00C8CCFF00F2FCFF00EBFAFF067061FF3ADE00FF3ADF + 00FF3ADF00FF3BE200FF43FF00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FE00FF38D400FF279500FF176721FF062A24FE0000 + 00680000001C0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000003C30B600FF43FF00FF43FF + 00FF43FF00FF36CD00FF00ABAFFF00F2FCFF00EBFAFF009CA9FF2EB100FF3ADF + 00FF3ADF00FF3ADF00FF43FD00FE43FF00FF43FF00FF43FF00FF43FD00FF37D2 + 00FF279300FE196100DC062E29FF005593FF006FC9FF0072D9FF00172DAF0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000512008541F600FF43FF00FF43FF + 00FF43FF00FF40F300FF008687FF00F2FCFF00EBFAFF00DEF2FF166B16FF3ADF + 00FF3ADF00FF3ADF00FF40F500FE36CF00FF269100FE1A6100D4092100950000 + 0056000000180014209D0078C6FF0083E1FF007CDFFF00437EF9000000270000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000185B00CF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF0B7A53FF00F2FCFF00EBFAFF00E4F8FF01848EFF2797 + 00FF207C00FE155200D7071A009E000000650000001A00000000000000000000 + 000500111B950074B7FF008AE3FF0083E1FF006EC7FF000C1688000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000001A279400FE43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF1B7D14FF00F0F9FF00EBFAFF00E4F8FF00DBF4FF0042 + 4BF3000000440000001C0000001C0000001C0000001C000000160000002A001E + 2CBB007EBFFF0091E4FF008AE3FF0082E0FF00294AD700000009000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000633ADD00FF43FF00FF42FA00FF34C8 + 00FF248A00FC185C00CC051500A800B4BBFF00EBFAFF00E4F8FF00DDF7FF00CF + EDFF005765E9000202740000002F0000002100000043000B0F8F004E6EF00096 + DCFF0098E6FF0091E4FF008AE3FF00497DF70000003200000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000071C00AD248800FB185A00CA0617008B0000 + 004C000000100000000000000003005E62E000EBFAFF00E4F8FF00DDF7FF00D6 + F5FF00CFF3FF00A9CCFF006F8AFF00617CFF00769BFF00A1DBFF00A6E9FF009F + E8FF0098E6FF0091E4FF0063A2FF000508610000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000380000000E00000000000000000000 + 00000000000000000000000000000007076900C2CFFF00E4F8FF00DDF7FF00D6 + F5FF00CFF3FF00C8F2FF00C1F0FF00BBEEFF00B4EDFF00ADEBFF00A6E9FF009F + E8FF0098E6FF006FAFFF000C1480000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000004004146CB00E0F3FF00DDF7FF00D6 + F5FF00CFF3FF00C8F2FF00C1F0FF00BBEEFF00B4EDFF00ADEBFF00A6E9FF009F + E8FF006DA5FF000D158100000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000022005D65E800DBF4FF00D6 + F5FF00CFF3FF00C8F2FF00C1F0FF00BBEEFF00B4EDFF00ADEBFF00A3E6FF0054 + 7BF6000508600000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000002700464FD600B8 + D3FF00CFF3FF00C8F2FF00C1F0FF00BBEEFF00B2EAFF0077A2FF002939BC0000 + 0028000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000080006 + 076D004552C7005F73F4005F76FA004D62DC001D269D0000003D000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000FFFFBFFFFFFF0000FFFF9FFFFFFF0000FFFF8FFFFFFF0000FFFB + 07FFFFFF0000FFF903FFFFFF0000FFF80101FFFF0000FFF000007FFF0000FFF0 + 00007FFF0000FFF000003FFF0000FFE000003FFF0000FFE000001FFF0000FFE0 + 00001FFF0000FFC000001FFF0000FFC000001FFF0000FFC000001FFF0000FFC0 + 00001FFF0000FF8000001FFF0000FF8000001FFF0000FF8000000FFF0000FF00 + 000007FF0000FF00000003FF0000FF00000001FF0000FF00000001FF0000FE00 + 000000FF0000FE000000007F0000FE000000003F0000FC000000001F0000FC00 + 0000000F0000FC00000000070000FC00000000070000F8000000003F0000F800 + 0000007F0000F8000000003F0000F0000000001F0000F000000000FF0000F000 + 00000FFF0000F0000000FFFF0000E0000003FFFF0000E0000003FFFF0000E000 + 0E07FFFF0000C000000FFFFF0000C000000FFFFF0000C0C0001FFFFF0000CFC0 + 003FFFFF0000FFE0007FFFFF0000FFE000FFFFFF0000FFF001FFFFFF0000FFFC + 07FFFFFF00002800000020000000400000000100200000000000801000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000000000000000B0000 + 0007000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000140000 + 001B000000070000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000900000036000000010000001B0000 + 001C0000001B0000000600000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000030B00492A9E00EE030D00390000001C0000 + 001C0000001C0000001A000000060000001B0000001D0000000A0000000E0000 + 000A000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000001A65009243FF00FF2DAA00ED020600420000 + 001C0000002500283A8A005C8AE6006EB0FF0067B0FF004985E5001427730000 + 001C000000140000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000289900DC43FF00FF43FF00FF2BA400E90006 + 0565006285DF00A0E4FF0099E6FF008FE4FF0085E1FF007ADFFF0064C5FF001B + 398D0000001C0000000C00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000002636CD00FF43FF00FF43FF00FF34CA05FF0385 + 9FFF00AEEBFF00A4E9FF0099E6FF008FE4FF0085E1FF007ADFFF0070DCFF0054 + B4FE00050C510000001700000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000F38007043FE00FF43FF00FF39DA01FF058D99FF00B9 + EEFF00AEEBFF0098D8FF006597F400578AE20065ADFD007ADFFF0070DCFF0065 + DAFF002E6AC40000001C00000003000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000238600BA43FF00FF41F800FF0C876AFF00C3F0FF00B9 + EEFF067B87FF165E0CEF000000350000001C0000003A00396ACD006FDBFF0065 + DAFF0046A5FE0000003600000008000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000B2EB000F843FF00FF209C26FF00C7EBFF00C3F0FF0B79 + 66FF35CA00FF3AE000FF228300D80000002D0000001C0000002C00458BE90065 + DAFF005AD5FF000A19730000000B000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000040F004E3FF000FF3ADD00FF02A3B2FF00CEF3FF078683FF35CB + 00FF3ADF00FF3EEE00FF43FE00FF217E00D20000002A0000001C00162C820064 + D7FF005BD7FF0020519E0000000C000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000001C6A009743FF00FF199840FF00D8F5FF00A9C5FF2CAE05FF3ADF + 00FF3AE100FF42FD00FF43FF00FF43FD00FF1F7700CD0000002700000037004E + A9FF005BD7FF00296ABA0000000B000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000299B00E13BE200FF01A9B5FF00D8F5FF178B39FF3ADF00FF3ADF + 00FF3EED00FF43FF00FF43FF00FE43FF00FF42FC00FF1D7000C700000025003E + 88EB005BD7FF002D74C800000015000000010000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000002B37D200FF21A126FF00E2F7FF01A3B3FF35CC00FF3ADF00FF3ADF + 00FF42FA00FF43FF00FF43FF00FE43FF00FF43FF00FF42FA00FF1C6900C10036 + 78D8005BD7FF002E76CB0000001C000000140000000100000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000113F007543FE00FF099B82FF00E3F8FF179749FF3AE000FF3ADF00FF3CE6 + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF41F800FF1360 + 35FF0059D3FF002C71C40000001C0000001C0000001400000001000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000248900BF36CD00FF00C8D4FF00CFE2FF2DB003FF3ADF00FF3ADF00FF3FF1 + 00FF43FF00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF41F6 + 00FF115E47FF002560B20000001C0000001C0000001C00000013000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000E2FB300FA23A621FF00EDFAFF049C9AFF3CE500FF3ADF00FF3ADF00FF42FA + 00FF43FF00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF40F300FF144E02C10000001E0000001C0000001C0000001C000000120000 + 0000000000000000000000000000000000000000000000000000000000000514 + 005340F300FF13A45EFF00EDFAFF139F5BFF3BE200FF3ADF00FF3BE300FF43FF + 00FF43FF00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF3FF000FF155100A50000001D0000001C0000001C0000001C0000 + 0011000000000000000000000000000000000000000000000000000000001D6F + 009C43FF00FF06A391FF00EDFAFF1F9F2BFF3ADF00FF3ADF00FF3DEA00FF43FF + 00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF3EED00FF144B009D0000001C0000001C0000001C0000 + 001C00000010000000000000000000000000000000000000000000000001299E + 00E53FEE00FF00B4B8FF00ECFAFF279D09FF3ADF00FF3ADF00FF3FF000FF43FF + 00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF3DE900FF124500950000001C0000001C0000 + 001B0000001600000005000000000000000000000000000000000000003139D7 + 00FF37D100FF00D1D6FF00E1EEFF2BA400FF3ADF00FF3ADF00FF40F400FF43FF + 00FF43FF00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF3CE500FF11420089000000080000 + 00010000000000000000000000000000000000000000000000001347007A43FF + 00FF32BE00FF00E3E9FF00DCE8FF2BA500FF3ADF00FF3ADF00FF41F700FF43FF + 00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF3BE000FF114200750000 + 0000000000000000000000000000000000000000000000000000258C00C443FF + 00FF30B700FF00EAF0FF00E6F3FF289B00FF3ADF00FF3ADF00FF41F800FF43FF + 00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF + 00FF43FF00FF43FF00FF43FF00FF3ADC00FF2CA600F1238400B50E3400760000 + 000800000000000000000000000000000000000000000000001230B700FC43FF + 00FF32BD00FF00E5EAFF00EDFAFF219517FF3ADF00FF3ADF00FF41F800FF43FF + 00FE43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF43FF00FF39DA + 00FF2BA500EF228200B3103E0074000000350000000300000000000000000000 + 00000000000000000000000000000000000000000000071A005840F500FF43FF + 00FF37CF00FF00D2D7FF00EDFAFF14944CFF3ADF00FF3ADF00FF40F500FF43FF + 00FF43FF00FF43FF00FF43FE00FF38D700FF28A110FF177E45FF073D42F40000 + 0038000000030000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000001E7300A243FF00FF43FF + 00FF3FF000FF00B1B5FF00EDFAFF039E9FFF37D200FF3ADF00FF3FEF00FE38D5 + 00FF2BA200EB217F00AE0E37006F00253DC40080DAFF0078DAFF002242830000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000022AA000E943FF00FF43FF + 00FF43FF00FF0AA381FF00EDFAFF00DFF3FF126E2DFA1B6800B40A28007C0000 + 00400000000800000009002E47940082D0FF0085E1FF004A85DE0000000B0000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000363ADC00FF42FD00FF37D0 + 00FF2A9F00E70A6641D800EDFAFF00E3F8FF00BDD6FF003B459A000000320000 + 002400070A5B005174CD0091DAFF008FE4FF006BB5FC000D163E000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000006150065207900A60C2C00670000 + 0028000000010003032F00C1CCFE00E3F8FF00D8F5FF00CBEFFF0094B6FF0081 + A6FF009ED5FF00A4E9FF0099E6FF0080CBFF0022397100000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000005C63A400E1F6FF00D8F5FF00CEF3FF00C3F0FF00B9 + EEFF00AEEBFF00A4E9FF0086C9FF002A42810000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000F00707CCE00D4F1FF00CEF3FF00C3F0FF00B9 + EEFF00AEEBFF0074A4F300213060000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000B00444E87007E95E200819FFC0071 + 91DE003F548E0000001B00000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000FFEFFFFFFFE7FFFFFFA3FFFFFF0107FFFF00 + 03FFFF0001FFFE0001FFFE0001FFFE0001FFFC0000FFFC0000FFFC0000FFFC00 + 00FFF800007FF800003FF800001FF000000FF0000007F0000003F0000003E000 + 001FE000000FE000000FC000007FC00007FFC0000FFFC0060FFF80001FFF8400 + 3FFFFE007FFFFE00FFFFFF01FFFF280000002000000040000000010004000000 + 0000800200000000000000000000000000000000000000000000000080000080 + 000000808000800000008000800080800000C0C0C000808080000000FF0000FF + 000000FFFF00FF000000FF00FF00FFFF0000FFFFFF0000000000000033333333 + 300000000000000000000033BBBBBBBBB330000000000000000033BBBBBBBBBB + BBB33000000000000003BBBBBBBBBBBBBBBBB30000000000003FBBBBBFFFFFFF + BBBBBB300000000003FBBBBFF3333333FFBBBBB30000000003FBBBF330000000 + 33FBBBB3000000003FBBBF3000000000003FBBBB300000003FBBB30000000000 + 0003FBBB30000003FBBBB300000000000003FBBBB3000003FBBB300000000000 + 00003FBBB3000003FBBB30000000000000003FBBB3000003FBBB300000000000 + 00003FBBB3000003FBBB30000000000000003FBBB3000003FBBB300000000000 + 00003FBBB3000003FBBB30000000000000003FBBB3000003FBBB300000A00000 + 00003BBBB3000003FBBBB30000AA00000003FBBBB30000003FBBB30000AAA000 + 0003FBBB300000003FBBBB3000AAAA00003BBBBB3000000003FBBBB330AAAAA0 + 33BBBBB30000000003FBBBBBB0AAAAAA0BBBBBB300000000003FBBBBB0AAAAAA + A0BBBF30000000000003FFBBB0AAAAAAAA0FF30000000000000033FFB0AAAAAA + A0F330000000000000000033F0AAAAAA03300000000000000000000030AAAAA0 + 30000000000000000000000000AAAA0000000000000000000000000000AAA000 + 00000000000000000000000000AA000000000000000000000000000000A00000 + 00000000000000000000000000000000000000000000FFF007FFFFC001FFFF00 + 007FFE00003FFC00001FF800000FF807F00FF01FFC07F03FFE07E03FFE03E07F + FF03E07FFF03E07FFF03E07FFF03E07FFF03E079FF03E078FF03E0387E03F038 + 3E07F0181C07F800000FF800000FFC00001FFE00003FFF00007FFFC001FFFFF0 + 07FFFFF81FFFFFF83FFFFFF87FFFFFF8FFFFFFF9FFFF28000000100000002000 + 00000100040000000000C0000000000000000000000000000000000000000000 + 000000008000008000000080800080000000800080008080000080808000C0C0 + C0000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFFFF000000 + 000000000000000000BBBB0000000000BBBBBBBB0000000BBB0000BBB000000B + B000000BB00000BB00000000BB0000BB00000000BB0000BB00000000BB0000BB + 000A0000BB00000BB00AA00BB000000BBB0AAA0BB0000000BB0AAAA000000000 + 000AAA0000000000000AA00000000000000A000000000000000000000000FC3F + 0000F00F0000E0070000C0030000C3C3000087E1000087E1000084E100008461 + 0000C0030000C0030000E0070000F01F0000FC3F0000FC7F0000FCFF0000} + Menu = MainMenu + OldCreateOrder = False + OnClose = FormClose + OnCloseQuery = FormCloseQuery + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 12 + object StatusBar: TStatusBar + Left = 0 + Top = 281 + Width = 630 + Height = 19 + Panels = < + item + Alignment = taRightJustify + Width = 45 + end + item + Text = '-' + Width = 37 + end + item + Alignment = taRightJustify + Text = '-' + Width = 75 + end + item + Text = '-' + Width = 110 + end + item + Width = 210 + end> + SimplePanel = False + end + object ToolBar: TToolBar + Left = 0 + Top = 0 + Width = 630 + Height = 26 + AutoSize = True + Caption = 'ToolBar' + EdgeBorders = [ebTop, ebBottom] + Flat = True + Images = ImageList + TabOrder = 1 + object OpenToolButton: TToolButton + Left = 0 + Top = 0 + Action = OpenAction + ParentShowHint = False + ShowHint = True + end + object SaveToolButton: TToolButton + Left = 23 + Top = 0 + Action = SaveAction + ParentShowHint = False + ShowHint = True + end + object ToolButton2: TToolButton + Left = 46 + Top = 0 + Width = 8 + Caption = 'ToolButton2' + ImageIndex = 6 + Style = tbsSeparator + end + object UndoToolButton: TToolButton + Left = 54 + Top = 0 + Action = UndoAction + ParentShowHint = False + ShowHint = True + end + object RedoToolButton: TToolButton + Left = 77 + Top = 0 + Action = RedoAction + ParentShowHint = False + ShowHint = True + end + object ToolButton3: TToolButton + Left = 100 + Top = 0 + Width = 8 + Caption = 'ToolButton3' + ImageIndex = 14 + Style = tbsSeparator + end + object DeleteToolButton: TToolButton + Left = 108 + Top = 0 + Action = DeleteAction + ParentShowHint = False + ShowHint = True + end + object ToolButton5: TToolButton + Left = 131 + Top = 0 + Width = 8 + Caption = 'ToolButton5' + ImageIndex = 5 + Style = tbsSeparator + end + object NewLinkToolButton: TToolButton + Left = 139 + Top = 0 + Action = NewLinkAction + ParentShowHint = False + ShowHint = True + end + object NewLabelToolButton: TToolButton + Left = 162 + Top = 0 + Action = NewLabelAction + ParentShowHint = False + ShowHint = True + end + object ToolButton7: TToolButton + Left = 185 + Top = 0 + Width = 8 + Caption = 'ToolButton7' + ImageIndex = 5 + Style = tbsSeparator + end + object ZoomInToolButton: TToolButton + Left = 193 + Top = 0 + Action = ZoomInAction + ParentShowHint = False + ShowHint = True + end + object ZoomOutToolButton: TToolButton + Left = 216 + Top = 0 + Action = ZoomOutAction + ParentShowHint = False + ShowHint = True + end + object ToolButton4: TToolButton + Left = 239 + Top = 0 + Width = 8 + Caption = 'ToolButton4' + ImageIndex = 5 + Style = tbsSeparator + end + object ShowEditFlagToolButton: TToolButton + Left = 247 + Top = 0 + Action = ShowEditFlagsAction + ParentShowHint = False + ShowHint = True + end + object ToolButton1: TToolButton + Left = 270 + Top = 0 + Width = 8 + Caption = 'ToolButton1' + ImageIndex = 11 + Style = tbsSeparator + end + object StopToolButton: TToolButton + Left = 278 + Top = 0 + Action = StopPlayAction + ParentShowHint = False + ShowHint = True + end + object PlayToolButton: TToolButton + Left = 301 + Top = 0 + Action = PlayFromStartAction + ParentShowHint = False + ShowHint = True + end + object PlayFromCursorToolButton: TToolButton + Left = 324 + Top = 0 + Action = PlayFromCaretAction + ParentShowHint = False + ShowHint = True + end + object IgnoreLinksToolButton: TToolButton + Left = 347 + Top = 0 + Action = IgnoreLinksAction + ParentShowHint = False + ShowHint = True + end + object ToolButton6: TToolButton + Left = 370 + Top = 0 + Width = 8 + Caption = 'ToolButton6' + ImageIndex = 2 + Style = tbsSeparator + end + object FollowMarkerToolButton: TToolButton + Left = 378 + Top = 0 + Action = FollowMarkerAction + ParentShowHint = False + ShowHint = True + end + end + object FlagsPanel: TPanel + Left = 0 + Top = 26 + Width = 630 + Height = 23 + Align = alTop + BevelOuter = bvNone + TabOrder = 2 + Visible = False + object Bevel1: TBevel + Left = 0 + Top = 21 + Width = 630 + Height = 2 + Align = alBottom + Shape = bsBottomLine + end + object FlagLabel0: TLabel + Left = 20 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 0' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel1: TLabel + Left = 75 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 1' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel2: TLabel + Left = 130 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 2' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel3: TLabel + Left = 185 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 3' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel4: TLabel + Left = 240 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 4' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel5: TLabel + Left = 295 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 5' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel6: TLabel + Left = 350 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 6' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel7: TLabel + Left = 405 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 7' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel8: TLabel + Left = 460 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 8' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel9: TLabel + Left = 515 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = ' 9' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel10: TLabel + Left = 570 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = '10' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel11: TLabel + Left = 625 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = '11' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel12: TLabel + Left = 680 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = '12' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel13: TLabel + Left = 735 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = '13' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel14: TLabel + Left = 790 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = '14' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagLabel15: TLabel + Left = 845 + Top = 0 + Width = 17 + Height = 20 + AutoSize = False + Caption = '15' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Style = [] + ParentFont = False + Layout = tlCenter + end + object FlagsClearSpeedButton: TSpeedButton + Left = 2 + Top = 2 + Width = 17 + Height = 17 + Hint = 'フラグを全て0にします' + Caption = 'C' + Flat = True + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [fsBold] + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = FlagsClearSpeedButtonClick + end + object FlagEdit0: TEdit + Left = 36 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 1 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit1: TEdit + Left = 91 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 2 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit2: TEdit + Left = 146 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 3 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit3: TEdit + Left = 201 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 4 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit4: TEdit + Left = 256 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 5 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit5: TEdit + Left = 311 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 6 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit6: TEdit + Left = 366 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 7 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit7: TEdit + Left = 421 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 8 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit8: TEdit + Left = 476 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 9 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit9: TEdit + Left = 531 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 10 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit10: TEdit + Left = 586 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 11 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit11: TEdit + Left = 641 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 12 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit12: TEdit + Left = 696 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 13 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit13: TEdit + Left = 751 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 14 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit14: TEdit + Left = 806 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 15 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + object FlagEdit15: TEdit + Left = 861 + Top = 0 + Width = 33 + Height = 20 + MaxLength = 4 + PopupMenu = FlagsEditPopupMenu + TabOrder = 0 + Text = '0' + OnChange = FlagEdit0Change + OnDblClick = FlagEdit0DblClick + OnEnter = FlagEdit15Enter + OnKeyPress = FlagEdit0KeyPress + OnMouseDown = FlagEdit0MouseDown + end + end + object MainMenu: TMainMenu + Images = ImageList + Left = 40 + Top = 64 + object FileMenu: TMenuItem + Caption = 'ファイル(&F)' + object OpenMenuItem: TMenuItem + Action = OpenAction + end + object SaveMenuItem: TMenuItem + Action = SaveAction + end + object N1: TMenuItem + Caption = '-' + end + object CloseMenuItem: TMenuItem + Action = CloseAction + end + end + object EditMenu: TMenuItem + Caption = '編集(&E)' + object UndoMenuItem: TMenuItem + Action = UndoAction + end + object RedoMenuItem: TMenuItem + Action = RedoAction + end + object DeleteMenuItem: TMenuItem + Action = DeleteAction + end + object NewLinkMenuItem: TMenuItem + Action = NewLinkAction + end + object NewLabelMenuItem: TMenuItem + Action = NewLabelAction + end + object EditLinkDetailMenuItem: TMenuItem + Action = EditLinkDetailAction + end + object NewLinkOnPlayMenuItem: TMenuItem + Action = NewLinkOnPlayAction + Caption = '再生位置にラベルを作成(&A)'#9'A または S' + end + object NewLinkOnPlay_A_MenuItem: TMenuItem + Action = NewLinkOnPlayAction + ShortCut = 65 + Visible = False + end + object NewLinkOnPlay_S_MenuItem: TMenuItem + Action = NewLinkOnPlayAction + ShortCut = 83 + Visible = False + end + object ClearAllLabelsMenuItem: TMenuItem + Action = ClearAllLabelsAction + ShortCut = 16465 + end + end + object ViewMenu: TMenuItem + Caption = '表示(&V)' + object ZoomInMenuItem: TMenuItem + Action = ZoomInAction + end + object ZoomOutMenuItem: TMenuItem + Action = ZoomOutAction + end + object FollowMarkerMenuItem: TMenuItem + Action = FollowMarkerAction + end + object ShowToolBarMenuItem: TMenuItem + Action = ShowToolBarAction + end + object ShowEditFlagMenuItem: TMenuItem + Action = ShowEditFlagsAction + end + object ShowTotalViewMenuItem: TMenuItem + Action = ShowTotalViewAction + end + object ShowStatusBarMenuItem: TMenuItem + Action = ShowStatusBarAction + end + end + object PlayMenu: TMenuItem + Caption = '再生(&P)' + object StopPlayMenuItem: TMenuItem + Action = StopPlayAction + end + object PlayFromStartMenuItem: TMenuItem + Action = PlayFromStartAction + end + object PlayFromCaretMenuItem: TMenuItem + Action = PlayFromCaretAction + end + object IgnoreLinksMenuItem: TMenuItem + Action = IgnoreLinksAction + end + end + object HelpMenu: TMenuItem + Caption = 'ヘルプ(&H)' + object ShowHelpMenuItem: TMenuItem + Action = ShowHelpAction + end + object ShowAboutMenuItem: TMenuItem + Action = ShowAboutAction + end + end + end + object ActionList: TActionList + Images = ImageList + Left = 8 + Top = 64 + object ShowStatusBarAction: TAction + Category = '表示' + Caption = 'ステータスバーの表示(&S)' + Hint = 'ステータスバーを表示します' + OnExecute = ShowStatusBarActionExecute + end + object ShowTotalViewAction: TAction + Category = '表示' + Caption = '縮小波形の表示(&E)' + Hint = 'サウンド全体を見渡せる波形を表示します' + OnExecute = ShowTotalViewActionExecute + end + object StopPlayAction: TAction + Category = '再生' + Caption = '停止(&Q)' + Hint = '現在の再生を停止します' + ImageIndex = 4 + ShortCut = 81 + OnExecute = StopPlayActionExecute + end + object PlayFromCaretAction: TAction + Category = '再生' + Caption = '現在位置から再生(&C)' + Hint = '現在のキャレット位置から再生します' + ImageIndex = 1 + ShortCut = 32 + OnExecute = PlayFromCaretActionExecute + end + object PlayFromStartAction: TAction + Category = '再生' + Caption = '初めから再生(&P)' + Hint = 'サウンドの先頭から再生します' + ImageIndex = 0 + ShortCut = 80 + OnExecute = PlayFromStartActionExecute + end + object ShowToolBarAction: TAction + Category = '表示' + Caption = 'ツールバーの表示(&T)' + Hint = 'ツールバーを表示します' + OnExecute = ShowToolBarActionExecute + end + object ZoomInAction: TAction + Category = '表示' + Caption = 'ズーム・イン(&I)' + Hint = '波形をズームインします' + ImageIndex = 9 + ShortCut = 73 + OnExecute = ZoomInActionExecute + end + object OpenAction: TAction + Category = 'ファイル' + Caption = '開く(&O)...' + Hint = 'ファイルを開きます' + ImageIndex = 5 + ShortCut = 16463 + OnExecute = OpenActionExecute + end + object ZoomOutAction: TAction + Category = '表示' + Caption = 'ズーム・アウト(&O)' + Hint = '波形をズームアウトします' + ImageIndex = 10 + ShortCut = 79 + OnExecute = ZoomOutActionExecute + end + object ShowEditFlagsAction: TAction + Category = '表示' + Caption = 'フラグの表示(&G)' + Hint = 'フラグ編集バーを表示します' + ImageIndex = 35 + OnExecute = ShowEditFlagsActionExecute + end + object FollowMarkerAction: TAction + Category = '表示' + Caption = '再生位置に画面を追従(&F)' + Hint = '再生位置に画面を追従します' + ImageIndex = 11 + ShortCut = 70 + OnExecute = FollowMarkerActionExecute + end + object SaveAction: TAction + Category = 'ファイル' + Caption = '保存(&S)' + Hint = 'ファイルを保存します' + ImageIndex = 6 + ShortCut = 16467 + OnExecute = SaveActionExecute + end + object UndoAction: TAction + Category = '編集' + Caption = '元に戻す(&U)' + Hint = '最後の編集を取り消し、直前の状態に戻します' + ImageIndex = 12 + ShortCut = 16474 + OnExecute = UndoActionExecute + end + object RedoAction: TAction + Category = '編集' + Caption = 'やり直し(&R)' + Hint = '「元に戻す」で元に戻した変更を再度適用します' + ImageIndex = 13 + ShortCut = 24666 + OnExecute = RedoActionExecute + end + object DeleteAction: TAction + Category = '編集' + Caption = '削除(&D)' + Hint = '現在選択されているアイテムを削除します' + ImageIndex = 14 + ShortCut = 46 + OnExecute = DeleteActionExecute + end + object NewLinkAction: TAction + Category = '編集' + Caption = '新規リンクを作成(&J)' + Hint = '新しいリンクを作成します' + ImageIndex = 15 + ShortCut = 74 + OnExecute = NewLinkActionExecute + end + object NewLabelAction: TAction + Category = '編集' + Caption = '新規ラベルを作成(&L)' + Hint = '新しいラベルを作成します' + ImageIndex = 16 + ShortCut = 76 + OnExecute = NewLabelActionExecute + end + object EditLinkDetailAction: TAction + Category = '編集' + Caption = 'リンクの編集(&T) ...' + Hint = 'リンクの詳細を編集します' + ImageIndex = 31 + OnExecute = EditLinkDetailActionExecute + end + object EditLabelDetailAction: TAction + Category = '編集' + Caption = 'ラベルを編集(&E) ...' + Hint = 'ラベルを編集します' + ImageIndex = 17 + OnExecute = EditLabelDetailActionExecute + end + object GotoLinkFromAction: TAction + Category = '表示' + Caption = 'リンク元に移動(&B)' + Hint = 'リンク元を表示します' + ImageIndex = 33 + ShortCut = 66 + OnExecute = GotoLinkFromActionExecute + end + object GotoLinkToAction: TAction + Category = '表示' + Caption = 'リンク先に移動(&N)' + Hint = 'リンク先を表示します' + ImageIndex = 34 + ShortCut = 78 + OnExecute = GotoLinkToActionExecute + end + object IgnoreLinksAction: TAction + Category = '再生' + Caption = 'リンクを無視して再生(&G)' + Hint = 'リンクを無視し、ジャンプせずに再生します' + ImageIndex = 36 + ShortCut = 71 + OnExecute = IgnoreLinksActionExecute + end + object CloseAction: TAction + Category = 'ファイル' + Caption = '終了(&X)' + Hint = 'ループチューナを終了します' + OnExecute = CloseActionExecute + end + object ShowHelpAction: TAction + Category = 'ヘルプ' + Caption = 'ヘルプ(&H) ...' + Hint = 'ループチューナのヘルプを表示します' + OnExecute = ShowHelpActionExecute + end + object ShowAboutAction: TAction + Category = 'ヘルプ' + Caption = 'ループチューナについて(&A) ...' + Hint = 'ループチューナの著作権・バージョン情報を表示します' + OnExecute = ShowAboutActionExecute + end + object ClearAllLabelsAction: TAction + Category = '編集' + Caption = '全てのラベルをクリア(&Q)' + Hint = '全てのラベルを削除します' + ImageIndex = 39 + OnExecute = ClearAllLabelsActionExecute + end + object NewLinkOnPlayAction: TAction + Category = '編集' + Caption = '再生位置にラベルを作成(&A)' + Hint = '現在の再生位置に新規ラベルを作成します' + ImageIndex = 40 + OnExecute = NewLinkOnPlayActionExecute + end + end + object ImageList: TImageList + Left = 72 + Top = 64 + Bitmap = { + 494C010129002C00040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3604 + 000000000000360400002800000040000000B00000000100080000000000002C + 0000000000000000000000000000000000000000000000008000008000000080 + 8000800000008000800080800000C0C0C000A19D9D00E3DFE000F0FBFF00A4A0 + A000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFF + FF0000000000000080000080000000808000800000008000800080800000C0C0 + C000A19D9D00E3DFE000F0FBFF00A4A0A000808080000000FF0000FF000000FF + FF00FF000000FF00FF00FFFF0000FFFFFF000000000000008000008000000080 + 8000800000008000800080800000C0C0C000A19D9D00E3DFE000F0FBFF00A4A0 + A000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFF + FF0000000000000080000080000000808000800000008000800080800000C0C0 + C000A19D9D00E3DFE000F0FBFF00A4A0A000808080000000FF0000FF000000FF + FF00FF000000FF00FF00FFFF0000FFFFFF000000000000008000008000000080 + 8000800000008000800080800000C0C0C000A19D9D00E3DFE000F0FBFF00A4A0 + A000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFF + FF0000000000000080000080000000808000800000008000800080800000C0C0 + C000A19D9D00E3DFE000F0FBFF00A4A0A000808080000000FF0000FF000000FF + FF00FF000000FF00FF00FFFF0000FFFFFF000000000000008000008000000080 + 8000800000008000800080800000C0C0C000A19D9D00E3DFE000F0FBFF00A4A0 + A000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFF + FF0000000000000080000080000000808000800000008000800080800000C0C0 + C000A19D9D00E3DFE000F0FBFF00A4A0A000808080000000FF0000FF000000FF + FF00FF000000FF00FF00FFFF0000FFFFFF000000000000008000008000000080 + 8000800000008000800080800000C0C0C000A19D9D00E3DFE000F0FBFF00A4A0 + A000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFF + FF0000000000000080000080000000808000800000008000800080800000C0C0 + C000A19D9D00E3DFE000F0FBFF00A4A0A000808080000000FF0000FF000000FF + FF00FF000000FF00FF00FFFF0000FFFFFF000000000000008000008000000080 + 8000800000008000800080800000C0C0C000A19D9D00E3DFE000F0FBFF00A4A0 + A000808080000000FF0000FF000000FFFF00FF000000FF00FF00FFFF0000FFFF + FF0000000000000080000080000000808000800000008000800080800000C0C0 + C000A19D9D00E3DFE000F0FBFF00A4A0A000808080000000FF0000FF000000FF + FF00FF000000FF00FF00FFFF0000FFFFFF000000000000008000008000000080 + 80008000000080008000F0FBFF00A4A0A000808080000000FF0000FF000000FF + FF00FF000000FF00FF00FFFF0000FFFFFF000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000F000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000F000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000F0F0F0000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000F0F0F0000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000F0F0F0F0F00000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000000000000000000F0F0F0F0F00000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000F0F0F0F0F0F0F000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000010101010101000000000000000000000000000000000000000 + 0000000C0000000000000C13000000000C000000000000000000000000000000 + 0000000000000010101010101000000000000000000000000000000000000000 + 00000006130000000000000C0C000C130C000000000000000000000000000000 + 0000000000000000001010000000000000000000000000000000000000000000 + 0000000006120C000000000C0000000C00000000000000000000000000000000 + 0000000000000000001010000000000000000000000000000000000000000000 + 000000000006000C00000C0F0000000000000000000000000000000000000000 + 0000000000000000001010000000000000000000000000000000000000000000 + 00000000000000000C000F120000000000000000000000000000000000000000 + 0000000000000000001010000000000000000000000000000000000000000000 + 00000000000000130C13000C0000000000000000000000000000000000000000 + 0000000000000000001010000000000000000000000000000000000000000000 + 000000000000000C051213130C00000000000000000000000000000000000000 + 0000000000000010101010101000000000000000000000000000000000000000 + 000000000000001300000F00000C000000000000000000000000000000000000 + 0000000000000010101010101000100000000000000000000000000000000000 + 000000000000000C000E0C0C0000000000000000000000000000000000000000 + 0000000000000000000000000000101000000000000000000000000000000000 + 00000C000000000C120000000000001300000000000000000000000000000000 + 0000000010101010101010101010101010000000000000000000000000000000 + 0000000C00000C0F000C00000000000C00000000000000000000000000000000 + 0000000010101010101010101010101010000000000000000000000000000000 + 0000000000000C00000000000000000000000000000000000000000000000000 + 0000000000000000000000000000101000000000000000000000000000000000 + 00000000000C1300000000000000000000000000000000000000000000000000 + 0000000000000000000000000000100000000000000000000000000000000000 + 00000000000F0000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000606060606060606060600000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000006131313131313131306000000000000060606060606060606060000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000061313130013131306000000000000061313000013131313060000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000061313130013131313060000000000061300000000131313060000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000606060006060606060600000000060000000000001313060000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000131300000013060000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000013131313000000060000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000001313131313130000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000061313131313131300000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000061313131313131313000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000060606060606060606060000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000001010000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000001010100000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000070001010101010000000000000000000000000000000000 + 0000000000000000000000000000000000000000070000000000000000000000 + 0000000000000707070001010101010100000000000000000000000000000000 + 0000000000000000000000000000000000000000070707000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000070707070700000000000000 + 0000001010101010100007070700000000000000000000000000000000000000 + 0000000000000000000000000000000000000000070707070707070000000000 + 0000000010101010100007000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000070707070707070707000000 + 0000000000001010100000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000010100000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000F000000000000 + 0000000606000606060606060606060606000000000000000000000000000000 + 000000000000000000000000000000000000000000000000000F000000000000 + 0000000613001313131313131313131306000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000F0F0F0000000000 + 0000000613001313131313131313131306000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000F0F0F0000000000 + 0000000613001313131313131313131306000000000000000000000000000000 + 00000000000000000000000000000000000000000000000F0F0F0F0F00000000 + 0000000613001313131313131313131306000000000000000000000000000000 + 00000000000000000000000000000000000000000000000F0F0F0F0F00000000 + 0000000613001313131313131313131306000000000000000000000000000000 + 000000000000000000000000000000000000000000000F0F0F0F0F0F0F000000 + 0000000606000606060606060606060606000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000001300000000000000000000 + 1300000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000001131300000000000000000C + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000001010113130000000000000013 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000001010101130000000000000C00 + 00000000000000000000000000000000000000000000000000000000000C0400 + 0000000000040C00000000000000000000000000010101131300000000011300 + 000000000000000000000000000000000000000004040404040000000000040C + 000000000C040000000000040404040400000000000101011313000001010000 + 0000000000000000000000000000000000000000040404040000000000000004 + 0000000004000000000000000404040400000000000001010113130101000000 + 0000000000000000000000000000000000000000040404000000000000000004 + 0000000004000000000000000004040400000000000000010101010100000000 + 0000000000000000000000000000000000000000040400040000000000000004 + 0000000004000000000000000400040400000000000000000101011313000000 + 000000000000000000000000000000000000000004000000040400000000040C + 000000000C040000000004040000000400000000000000010101010113130000 + 0000000000000000000000000000000000000000000000000000040404040C00 + 00000000000C0404040400000000000000000000001301010100000101131300 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000010101010000000001011313 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000001010101000000000000010100 + 1300000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000000101010000000000000000000C + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000030300000000000013130003 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000030303030303030303000000000000030300000000000013130003 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000C000303030303030303030000000000030300000000000013130003 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000F0C0003030303030303030300000000030300000000000000000003 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000C0F0C00030303030303030303000000030303030303030303030303 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000F0C0F0C000000000000000000000000030300000000000000000303 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000C0F0C0F0C0F0C0F0C00000000000000030013131313131313130003 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000F0C0F0C0F0C0F0C0F00000000000000030013131313131313130003 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000C0F0C00000000000000000000000000030013131313131313130003 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000030013131313131313130003 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000030013131313131313130000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000030013131313131313130013 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 0000000000000000000000000000000000000000000000000000000000000000 + 000000000000000000000000000000000000424D3E000000000000003E000000 + 2800000040000000B00000000100010000000000800500000000000000000000 + 000000000000000000000000FFFFFF00FFFF000000000000FEFF000000000000 + FEFF000000000000FC7F000000000000FC7F000000000000F83F000000000000 + F83F000000000000F01F000000000000F01F000000000000E00F000000000000 + E00F000000000000FFF7000000000000FFF3000000000000C001000000000000 + FFF3000000000000FFF7000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF + FFFFF81FFFFF9F19FFBFF81FFFFF8F91FF9FFE7FFFFFC7ABD20FFE7FFFFFE137 + D207FE7FFFFFFD2FD203FE7FFFFFF0BFD207FE7FFFFFF81FD20FF81FFFFFD16F + FF9FF817FFFFBA2BFFBFFFF3FFFF79F1FFFFC001FFFFB2FBFFFFC001FFFFF5FF + FFFFFFF3FFFFE3FFFFFFFFF7FFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF801F + FFFFE00FE00FC00FC00FFFEFFFEFE00FC00FFFEFFFEFE007C00FFFEFFFEFF003 + C00FECEFECEFFEFFC00FF5EFF5EFFEFF800FF5EFF583FEFF800FE0EFE083FE3F + C007FFEFDBC7FE0FC003E0EFE0C7FE03C001FFEFEBEFFE0FFFF9FFEFFFEFFE3F + FFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFF9FFFFFFFFFFF + 87FF87FFFFFFFEFF81FF81FF8001FEFF807F807FE001FE3F801F801FF801FE1F + 800780079E01FC07801F801F8781F003807F807F81E1000181FF81FF8079801F + 87E787C7801FC07F9FDB9FFB8007F0FFFFF7FFE78001F8FFFFDBFFDFFFFFFEFF + FFE7FFC3FFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9FFF9FFF9FFF + FFFF87FF87FF87FFCFFF81FF81FF81FFC3FF807F807F807FC0FF801F801F801F + C03F800780078007C00F801F801F801FC003807F807F807FC00F81FF81FF81FF + C03F875387DF87C3C0FF9EBD9FDF9FEFC3FFFEB9FFDFFFF7CFFFFEB7FFDFFFDB + FFFFFF71FFDFFFE7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFFFF3FFF3FFF3F + FD3FFCBFFCBFFCBFFDCFF3BFF3BFF3BFFDF3CFBFCFBFCFBFFDCFF3BFF3BFF3BF + FD3FFCBFFCBFFCBFFCFFFF3FFF3FFF3FFFFFFFFFFFFFFFFFFFFFFFFFFE7FFFFF + C33FFFF7FFBFF867EEDFFFF7FFDFFDDBF6DFFFF7FC03FEDBDADFFFF7FFDFFB5B + E73FFFF7FFEFFCE7FFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFFFCFF + FFFFFFFFFD3FFD3FFEFFC7FFFDCFFDCFFEFFEFFFFDF3FDF3FC7F8001FDCFFDCF + FC7F8001FD3FFD3FF83F8001FCFFFCFFF83F8001FFFFFFFFF01F8001FFFFFE7F + F01F8001EFFFFDFFE00F8001EFFFFBFFE00FEFFFEFFFC03FFFFFC7FFEFFFFBFF + FFFFFFFFEFFFF7FFFFFFFFFFFFFFCFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFDFFFF + FFFFFFFFC7FB803FFFFFFFFF83FBFFBFFFFFFFFF83F7FFBFFFE7E7FFC1E7FFBF + C1F3CF83E0CFFC07C3FBDFC3F01FFC07C7FBDFE3F83FFE0FCBFBDFD3FC1FFE0F + DCF3CF3BF80FFF1FFF07E0FFE187FF1FFFFFFFFFC3C3FFBFFFFFFFFF87E5FFBF + FFFFFFFF8FFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBFFFBFFFF + FFE7FFF1FFF1F83FFFE7FFE3FFE3FEFFFDE7F847F847FEFFFCE7F78FF78FFEFF + FC67ECDFEFDFFEFF8027DCEFDFEFFEFF8027D02FD02FFEFFFC67D02FD02FFEFF + FCE7DCEFDFEFF83FFDE7ECDFEFDFFFF7FFE7F7BFF7BFFFF3FFE7F87FF87FC001 + FFFFFFFFFFFFFFF3FFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFC001FFFF + FFFF800F8001E7FFFFFF80078001E7FFF00F80038001E7BFF00F80018001E73F + F00F80008001E63FF00F80008001E401F00F800F8001E401F00F800F8001E63F + F00F800F8001E73FF00FC7F88001E7BFFFFFFFFC8001E7FFFFFFFFBA8001E7FF + FFFFFFC78001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7FFFFDFFFDF + FFFFEFFFFF9FFF9FCBFFEBFFFF0FFF0FC8FFE8FF9797EF97C83FE83F91DBE3DB + C80FE80F907DE0FDC803E803901DE03DC80FE80F9005E00DC83FE83F901DE03D + C8FFE8FF907DE0FDCBFFEBFF91FBE3FBFFFFEFFF97F7EFF7FFFFC7FFFC0FFC0F + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000 + 000000000000} + end + object OpenDialog: TOpenDialog + Left = 104 + Top = 64 + end + object ForLabelPopupMenu: TPopupMenu + Images = ImageList + Left = 8 + Top = 96 + object ForLAbel_EditLabelDetailMenuItem: TMenuItem + Action = EditLabelDetailAction + Default = True + end + object ForLabel_NewLabelMenuItem: TMenuItem + Action = NewLabelAction + end + object ForLink_DeleteMenuItem: TMenuItem + Action = DeleteAction + end + end + object ForLinkPopupMenu: TPopupMenu + Images = ImageList + Left = 40 + Top = 96 + object ForLink_EditLinkDetailMenuItem: TMenuItem + Action = EditLinkDetailAction + Default = True + end + object ForLink_GotoLinkFromMenuItem: TMenuItem + Action = GotoLinkFromAction + end + object ForLink_GotoLinkToAction: TMenuItem + Action = GotoLinkToAction + end + object ForLink_NewLinkMenuItem: TMenuItem + Action = NewLinkAction + end + object ForLink_DeleteItemMenuItem: TMenuItem + Action = DeleteAction + end + end + object ForWavePopupMenu: TPopupMenu + Images = ImageList + Left = 72 + Top = 96 + object ForWave_PlayFromCursorMenuItem: TMenuItem + Action = PlayFromCaretAction + Default = True + end + object ForWave_ZoomInMenuItem: TMenuItem + Action = ZoomInAction + end + object ForWave_ZoomOutMenuItem: TMenuItem + Action = ZoomOutAction + end + object ForWave_NewLinkMenuItem: TMenuItem + Action = NewLinkAction + end + object ForWave_NewLabelMenuItem: TMenuItem + Action = NewLabelAction + end + end + object ApplicationEvents: TApplicationEvents + OnIdle = ApplicationEventsIdle + OnHint = ApplicationEventsHint + Left = 104 + Top = 96 + end + object FlagsEditPopupMenu: TPopupMenu + Left = 152 + Top = 64 + object FlagsEditToggleMenuItem: TMenuItem + Caption = 'トグル(&T)' + Default = True + Hint = '値が0以外ならば0に、0ならば1にします' + OnClick = FlagsEditToggleMenuItemClick + end + object FlagsEditZeroMenuItem: TMenuItem + Caption = '&0にする' + Hint = '値を0にします' + OnClick = FlagsEditZeroMenuItemClick + end + object FlasgEditOneMenuItem: TMenuItem + Caption = '&1にする' + Hint = '値を1にします' + OnClick = FlasgEditOneMenuItemClick + end + end + object BlinkTimer: TTimer + Interval = 500 + OnTimer = BlinkTimerTimer + Left = 152 + Top = 96 + end +end diff --git a/tools/win32/krdevui/looptuner2/LoopTunerMainUnit.h b/tools/win32/krdevui/looptuner2/LoopTunerMainUnit.h new file mode 100644 index 0000000..c0a9933 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/LoopTunerMainUnit.h @@ -0,0 +1,258 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef MainUnitH +#define MainUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +#include "WaveReader.h" +#include "WaveViewControl.h" +#include "WaveLoopManager.h" +#include "TotalView.h" +#include +#include "EditLabelAttribUnit.h" +#include "EditLinkAttribUnit.h" +#include +#include +#include +//--------------------------------------------------------------------------- +#define WM_SHOWFRONT (WM_USER+201) +#define WM_DOOPEN (WM_USER+202) +//--------------------------------------------------------------------------- +class TTSSLoopTuner2MainForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TMainMenu *MainMenu; + TActionList *ActionList; + TMenuItem *FileMenu; + TAction *OpenAction; + TImageList *ImageList; + TMenuItem *OpenMenuItem; + TStatusBar *StatusBar; + TOpenDialog *OpenDialog; + TToolBar *ToolBar; + TToolButton *OpenToolButton; + TToolButton *ToolButton2; + TAction *ZoomInAction; + TAction *ZoomOutAction; + TMenuItem *ViewMenu; + TMenuItem *ZoomInMenuItem; + TMenuItem *ZoomOutMenuItem; + TToolButton *ZoomInToolButton; + TToolButton *ZoomOutToolButton; + TToolButton *ToolButton1; + TToolButton *PlayToolButton; + TAction *PlayFromStartAction; + TToolButton *StopToolButton; + TAction *StopPlayAction; + TToolButton *PlayFromCursorToolButton; + TAction *PlayFromCaretAction; + TAction *SaveAction; + TToolButton *SaveToolButton; + TAction *DeleteAction; + TMenuItem *EditMenu; + TMenuItem *DeleteMenuItem; + TAction *UndoAction; + TAction *RedoAction; + TMenuItem *UndoMenuItem; + TMenuItem *RedoMenuItem; + TToolButton *UndoToolButton; + TToolButton *RedoToolButton; + TToolButton *ToolButton3; + TToolButton *DeleteToolButton; + TToolButton *ToolButton5; + TAction *NewLinkAction; + TAction *NewLabelAction; + TMenuItem *NewLinkMenuItem; + TMenuItem *NewLabelMenuItem; + TToolButton *NewLinkToolButton; + TToolButton *NewLabelToolButton; + TToolButton *ToolButton4; + TPopupMenu *ForLabelPopupMenu; + TMenuItem *ForLink_DeleteMenuItem; + TPopupMenu *ForLinkPopupMenu; + TMenuItem *ForLink_DeleteItemMenuItem; + TPopupMenu *ForWavePopupMenu; + TMenuItem *ForWave_PlayFromCursorMenuItem; + TMenuItem *ForWave_NewLinkMenuItem; + TMenuItem *ForWave_NewLabelMenuItem; + TMenuItem *ForWave_ZoomInMenuItem; + TMenuItem *ForWave_ZoomOutMenuItem; + TToolButton *ToolButton7; + TApplicationEvents *ApplicationEvents; + TToolButton *ToolButton6; + TToolButton *FollowMarkerToolButton; + TAction *FollowMarkerAction; + TMenuItem *SaveMenuItem; + TMenuItem *FollowMarkerMenuItem; + TMenuItem *PlayMenu; + TMenuItem *StopPlayMenuItem; + TMenuItem *PlayFromCaretMenuItem; + TMenuItem *PlayFromStartMenuItem; + TAction *EditLinkDetailAction; + TMenuItem *ForLink_EditLinkDetailMenuItem; + TMenuItem *EditLinkDetailMenuItem; + TMenuItem *ForLAbel_EditLabelDetailMenuItem; + TAction *EditLabelDetailAction; + TMenuItem *ForLabel_NewLabelMenuItem; + TMenuItem *ForLink_NewLinkMenuItem; + TAction *GotoLinkFromAction; + TAction *GotoLinkToAction; + TMenuItem *ForLink_GotoLinkFromMenuItem; + TMenuItem *ForLink_GotoLinkToAction; + TPanel *FlagsPanel; + TBevel *Bevel1; + TLabel *FlagLabel0; + TEdit *FlagEdit0; + TPopupMenu *FlagsEditPopupMenu; + TMenuItem *FlagsEditZeroMenuItem; + TMenuItem *FlasgEditOneMenuItem; + TMenuItem *FlagsEditToggleMenuItem; + TAction *ShowEditFlagsAction; + TToolButton *ShowEditFlagToolButton; + TSpeedButton *FlagsClearSpeedButton; + TToolButton *IgnoreLinksToolButton; + TMenuItem *IgnoreLinksMenuItem; + TAction *IgnoreLinksAction; + TMenuItem *ShowEditFlagMenuItem; + TAction *CloseAction; + TMenuItem *N1; + TMenuItem *CloseMenuItem; + TAction *ShowHelpAction; + TAction *ShowAboutAction; + TMenuItem *HelpMenu; + TMenuItem *ShowHelpMenuItem; + TMenuItem *ShowAboutMenuItem; + TTimer *BlinkTimer; + TAction *ShowToolBarAction; + TAction *ShowTotalViewAction; + TAction *ShowStatusBarAction; + TAction *NewLinkOnPlayAction; + TAction *ClearAllLabelsAction; + TMenuItem *ShowToolBarMenuItem; + TMenuItem *ShowTotalViewMenuItem; + TMenuItem *ShowStatusBarMenuItem; + TMenuItem *NewLinkOnPlayMenuItem; + TMenuItem *NewLinkOnPlay_A_MenuItem; + TMenuItem *NewLinkOnPlay_S_MenuItem; + void __fastcall OpenActionExecute(TObject *Sender); + void __fastcall ZoomInActionExecute(TObject *Sender); + void __fastcall ZoomOutActionExecute(TObject *Sender); + void __fastcall PlayFromStartActionExecute(TObject *Sender); + void __fastcall StopPlayActionExecute(TObject *Sender); + void __fastcall PlayFromCaretActionExecute(TObject *Sender); + void __fastcall SaveActionExecute(TObject *Sender); + void __fastcall UndoActionExecute(TObject *Sender); + void __fastcall RedoActionExecute(TObject *Sender); + void __fastcall DeleteActionExecute(TObject *Sender); + void __fastcall NewLabelActionExecute(TObject *Sender); + void __fastcall NewLinkActionExecute(TObject *Sender); + void __fastcall ApplicationEventsIdle(TObject *Sender, bool &Done); + void __fastcall FollowMarkerActionExecute(TObject *Sender); + void __fastcall EditLinkDetailActionExecute(TObject *Sender); + void __fastcall EditLabelDetailActionExecute(TObject *Sender); + void __fastcall GotoLinkFromActionExecute(TObject *Sender); + void __fastcall GotoLinkToActionExecute(TObject *Sender); + void __fastcall FlagsEditZeroMenuItemClick(TObject *Sender); + void __fastcall FlasgEditOneMenuItemClick(TObject *Sender); + void __fastcall FlagEdit0MouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall FlagsEditToggleMenuItemClick(TObject *Sender); + void __fastcall FlagEdit0Change(TObject *Sender); + void __fastcall FlagEdit0KeyPress(TObject *Sender, char &Key); + void __fastcall ShowEditFlagsActionExecute(TObject *Sender); + void __fastcall FlagEdit0DblClick(TObject *Sender); + void __fastcall FlagsClearSpeedButtonClick(TObject *Sender); + void __fastcall IgnoreLinksActionExecute(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall ApplicationEventsHint(TObject *Sender); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall FormShow(TObject *Sender); + void __fastcall CloseActionExecute(TObject *Sender); + void __fastcall ShowAboutActionExecute(TObject *Sender); + void __fastcall ShowHelpActionExecute(TObject *Sender); + void __fastcall FlagEdit15Enter(TObject *Sender); + void __fastcall BlinkTimerTimer(TObject *Sender); + void __fastcall ShowStatusBarActionExecute(TObject *Sender); + void __fastcall ShowTotalViewActionExecute(TObject *Sender); + void __fastcall ShowToolBarActionExecute(TObject *Sender); + void __fastcall ClearAllLabelsActionExecute(TObject *Sender); + void __fastcall NewLinkOnPlayActionExecute(TObject *Sender); +private: // ユーザー宣言 + TWaveReader * Reader; + TWaveView *WaveView; + TTotalView *TotalView; + tTVPWaveLoopManager *Manager; + AnsiString FileName; // current filename + + bool ResettingFlags; + +public: // ユーザー宣言 + __fastcall TTSSLoopTuner2MainForm(TComponent* Owner); + __fastcall ~TTSSLoopTuner2MainForm(); + + void __fastcall ReadFromIni(); + void __fastcall WriteToIni(); + + TWaveView * GetWaveView() { return WaveView; } + + +protected: + void __fastcall WMShowFront(TMessage &msg); + void __fastcall WMDoOpen(TMessage &msg); + void __fastcall WMCopyData(TWMCopyData &msg); + void __fastcall WMDropFiles(TMessage &msg); + + +BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER(WM_SHOWFRONT , TMessage , WMShowFront); + VCL_MESSAGE_HANDLER(WM_DOOPEN, TMessage, WMDoOpen); + VCL_MESSAGE_HANDLER(WM_DROPFILES,TMessage,WMDropFiles); + VCL_MESSAGE_HANDLER(WM_COPYDATA,TWMCopyData,WMCopyData); +END_MESSAGE_MAP(TForm) + + +private: + bool __fastcall GetCanClose(); + void __fastcall CreateWaveView(); + void __fastcall OnReaderProgress(TObject *sender); + void __fastcall Open(); + void __fastcall PlayFrom(int pos); + void __fastcall WaveViewStopFollowingMarker(TObject *Sender); + void __fastcall WaveViewRangeChanged(TObject *Sender, int start, int length); + void __fastcall WaveViewCaretStateChanged(TObject *Sender, int pos, bool visible); + void __fastcall WaveViewMarkerStateChanged(TObject *Sender, int pos, bool visible); + void __fastcall WaveViewWaveDoubleClick(TObject *Sender, int pos); + void __fastcall WaveViewLinkDoubleClick(TObject *Sender, int num, tTVPWaveLoopLink &link); + void __fastcall WaveViewLabelDoubleClick(TObject *Sender, int num, tTVPWaveLabel &label); + void __fastcall WaveViewNotifyPopup(TObject *Sender, AnsiString type, const TPoint &point); + void __fastcall WaveViewShowCaret(TObject *Sender, int pos); + void __fastcall WaveViewLinkSelected(TObject *Sender, int num, tTVPWaveLoopLink &link); + void __fastcall WaveViewLabelSelected(TObject *Sender, int num, tTVPWaveLabel &label); + void __fastcall WaveViewSelectionLost(TObject *Sender); + void __fastcall WaveViewLinkModified(TObject *Sender); + void __fastcall WaveViewLabelModified(TObject *Sender); + void __fastcall TotalViewPoint(TObject *Sender, int pos); + void __fastcall TotalViewDoubleClick(TObject *Sender, int pos); + + void __fastcall ResetFlagsEditFromLoopManager(); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TTSSLoopTuner2MainForm *TSSLoopTuner2MainForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/looptuner2/RIFFWaveContext.cpp b/tools/win32/krdevui/looptuner2/RIFFWaveContext.cpp new file mode 100644 index 0000000..c969894 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/RIFFWaveContext.cpp @@ -0,0 +1,268 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "RIFFWaveContext.h" + +//--------------------------------------------------------------------------- +const GUID __KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = + { 0x00000003 , 0x0000, 0x0010, { 0x80,0x00,0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }}; +const GUID __KSDATAFORMAT_SUBTYPE_PCM = + { 0x00000001 , 0x0000, 0x0010, { 0x80,0x00,0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 }}; +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +static void ConvertFloatTo16bits(short int *output, const float *input, int channels, int count) +{ + // 現時点では 32bit float のみを変換する + + // float PCM は +1.0 〜 0 〜 -1.0 の範囲にある + // 範囲外のデータはクリップする + int total = channels * count; + while(total--) + { + float t = *(input ++) * 32768.0; + if(t > 0) + { + int i = (int)(t + 0.5); + if(i > 32767) i = 32767; + *(output++) = (short int)i; + } + else + { + int i = (int)(t - 0.5); + if(i < -32768) i = -32768; + *(output++) = (short int)i; + } + } + +} +//--------------------------------------------------------------------------- +static void ConvertIntTo16bits(short int *output, const void *input, int bytespersample, + int validbits, int channels, int count) +{ + // 本当は int16 などのサイズの決まった型をつかうべき + + // 整数表現の PCM を 16bit に変換する + int total = channels * count; + + if(bytespersample == 1) + { + // 読み込み時のチェックですでに 8bit 入力のデータは 有効ビット数が 8 ビット + // であることが保証されているので単に 16bit に拡張するだけにする + const char *p = (const char *)input; + while(total--) *(output++) = (short int)( ((int)*(p++)-0x80) * 0x100); + } + else if(bytespersample == 2) + { + // 有効ビット数以下の数値は マスクして取り去る + short int mask = ~( (1 << (16 - validbits)) - 1); + const short int *p = (const short int *)input; + while(total--) *(output++) = (short int)(*(p++) & mask); + } + else if(bytespersample == 3) + { + long int mask = ~( (1 << (24 - validbits)) - 1); + const unsigned char *p = (const unsigned char *)input; + while(total--) + { + int t = p[0] + (p[1] << 8) + (p[2] << 16); + p += 3; + t |= -(t&0x800000); // 符号拡張 + t &= mask; // マスク + t >>= 8; + *(output++) = (short int)t; + } + } + else if(bytespersample == 4) + { + long int mask = ~( (1 << (32 - validbits)) - 1); + const unsigned __int32 *p = (const unsigned __int32 *)input; + while(total--) + { + *(output++) = (short int)((*(p++) & mask) >> 16); + } + } + +} +//--------------------------------------------------------------------------- +static void ConvertTo16bits(short int *output, const void *input, int bytespersample, + bool isfloat, int validbits, int channels, int count) +{ + // 指定されたフォーマットを 16bit フォーマットに変換する + // channels が -6 の場合は特別に + // FL FC FR BL BR LF と並んでいるデータ (AC3と同じ順序) を + // FL FR FC LF BL BR (WAVEFORMATEXTENSIBLE の期待する順序) に並び替える + int cns = channels; + if(cns<0) cns = -cns; + + if(isfloat) + ConvertFloatTo16bits(output, (const float *)input, cns, count); + else + ConvertIntTo16bits(output, input, bytespersample, validbits, cns, count); + + if(channels == -6) + { + // チャンネルの入れ替え + short int *op = output; + for(int i = 0; i < count; i++) + { + short int fc = op[1]; + short int bl = op[3]; + short int br = op[4]; + op[1] = op[2]; + op[2] = fc; + op[3] = op[5]; + op[4] = bl; + op[5] = br; + op += 6; + } + } +} +//--------------------------------------------------------------------------- + + + + + + +//--------------------------------------------------------------------------- +__fastcall TRIFFWaveContext::TRIFFWaveContext() +{ + FInputStream = NULL; +} +//--------------------------------------------------------------------------- +__fastcall TRIFFWaveContext::~TRIFFWaveContext() +{ + if(FInputStream) delete FInputStream; +} +//--------------------------------------------------------------------------- +bool __fastcall TRIFFWaveContext::Start(AnsiString filename) +{ + try + { + FInputStream = new TFileStream(filename, fmOpenRead | fmShareDenyWrite); + } + catch(...) + { + return false; + } + + // ヘッダを読む + BYTE buf[8]; + FInputStream->Position=0; + FInputStream->ReadBuffer(buf, 8); + if(memcmp(buf, "RIFF", 4)) return false; // RIFF がない + FInputStream->ReadBuffer(buf, 8); + if(memcmp(buf, "WAVEfmt ", 4)) return false; // WAVE でないか fmt チャンクがすぐこない + + DWORD fmtlen; + FInputStream->ReadBuffer(&fmtlen,4); + + FInputStream->ReadBuffer(&Format, sizeof(WAVEFORMATEX)); + if(Format.Format.wFormatTag != WAVE_FORMAT_EXTENSIBLE && + Format.Format.wFormatTag != WAVE_FORMAT_PCM && + Format.Format.wFormatTag != WAVE_FORMAT_IEEE_FLOAT) return false; // 対応できないフォーマット + + if(Format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) + { + FInputStream->ReadBuffer( + (char*)&Format + sizeof(Format.Format), + sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX)); + } + else if(Format.Format.wFormatTag == WAVE_FORMAT_PCM) + { + Format.Samples.wValidBitsPerSample = Format.Format.wBitsPerSample; + Format.SubFormat = __KSDATAFORMAT_SUBTYPE_PCM; + Format.dwChannelMask = 0; + } + else if(Format.Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT) + { + Format.Samples.wValidBitsPerSample = Format.Format.wBitsPerSample; + Format.SubFormat = __KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; + Format.dwChannelMask = 0; + } + + // 各種チェック + if(Format.Format.wBitsPerSample & 0x07) return false; // 8 の倍数ではない + if(Format.Format.wBitsPerSample > 32) return false; // 32bit より大きいサイズは扱えない + if(Format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE && + Format.Samples.wValidBitsPerSample < 8) return false; // 有効ビットが 8 未満は扱えない + if(Format.Format.wBitsPerSample < Format.Samples.wValidBitsPerSample) + return false; // 有効ビット数が実際のビット数より大きい + if(!memcmp(&Format.SubFormat, &__KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 16)) + IsFloat = true; + else if(!memcmp(&Format.SubFormat, &__KSDATAFORMAT_SUBTYPE_PCM, 16)) + IsFloat = false; + else + return false; // 未知のサブフォーマット + + if(IsFloat && Format.Format.wBitsPerSample != Format.Samples.wValidBitsPerSample) + return false; // float の有効ビット数が格納ビット数と等しくない + if(IsFloat && Format.Format.wBitsPerSample != 32) + return false; // float のビット数が 32 でない + + + FGranuleSize = Format.Format.wBitsPerSample / 8 * Format.Format.nChannels; + + // data チャンクを探す + FInputStream->Position= fmtlen + 0x14; + + while(1) + { + FInputStream->ReadBuffer(buf,4); // data ? + FInputStream->ReadBuffer(&FDataSize,4); // データサイズ + if(memcmp(buf,"data",4)==0) break; + FInputStream->Position=FInputStream->Position+FDataSize; + + if(FInputStream->Position >= FInputStream->Size) return false; + } + + FDataStart=FInputStream->Position; + + return true; +} +//--------------------------------------------------------------------------- +int __fastcall TRIFFWaveContext::Read(__int16 * dest, int destgranules) +{ + int samplesize = FGranuleSize; + destgranules *= samplesize; // data (in bytes) to read + int bytestowrite; + int remain = FDataStart + FDataSize - FInputStream->Position; + int readsamples; + + char *buf = new char[destgranules]; + + try + { + bytestowrite = (destgranules>remain) ? remain : destgranules; + bytestowrite = FInputStream->Read(buf, bytestowrite); + + readsamples = bytestowrite / samplesize; + + // convert to the destination format + ConvertTo16bits(dest, buf, Format.Format.wBitsPerSample / 8, IsFloat, + Format.Samples.wValidBitsPerSample, Format.Format.nChannels, readsamples); + } + catch(...) + { + delete [] buf; + throw; + } + delete [] buf; + + return readsamples; +} +//--------------------------------------------------------------------------- diff --git a/tools/win32/krdevui/looptuner2/RIFFWaveContext.h b/tools/win32/krdevui/looptuner2/RIFFWaveContext.h new file mode 100644 index 0000000..afa9dcd --- /dev/null +++ b/tools/win32/krdevui/looptuner2/RIFFWaveContext.h @@ -0,0 +1,49 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef RIFFWaveContextH +#define RIFFWaveContextH + +#include +#include +#include +#include +#include "WaveContext.h" + + +//--------------------------------------------------------------------------- +extern const GUID __KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; +extern const GUID __KSDATAFORMAT_SUBTYPE_PCM; +//--------------------------------------------------------------------------- +class TRIFFWaveContext : public TCustomWaveContext +{ + int FGranuleSize; + int FDataSize; + int FDataStart; + + WAVEFORMATEXTENSIBLE Format; + bool IsFloat; + + TStream *FInputStream; + +protected: + int __fastcall GetTotalSamples() { return FDataSize / FGranuleSize; } + int __fastcall GetChannels() { return Format.Format.nChannels; } + int __fastcall GetFrequency() { return Format.Format.nSamplesPerSec; } + DWORD __fastcall GetSpeakerConfig() { return Format.dwChannelMask; } + +public: + __fastcall TRIFFWaveContext(); + __fastcall ~TRIFFWaveContext(); + + bool __fastcall Start(AnsiString filename); + int __fastcall Read(__int16 * dest, int destgranules); +}; +//--------------------------------------------------------------------------- +#endif + diff --git a/tools/win32/krdevui/looptuner2/TSSWaveContext.cpp b/tools/win32/krdevui/looptuner2/TSSWaveContext.cpp new file mode 100644 index 0000000..d390b69 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/TSSWaveContext.cpp @@ -0,0 +1,154 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "tvpsnd.h" +#include "TSSWaveContext.h" + +//--------------------------------------------------------------------------- +TStorageProviderImpl StorageProvider; +//--------------------------------------------------------------------------- +HRESULT _stdcall TStorageProviderImpl::GetStreamForRead(LPWSTR url, IUnknown ** stream ) +{ + TStream *tvpstream; + + try + { + tvpstream = new TFileStream(AnsiString(url), fmOpenRead|fmShareDenyWrite); + } + catch(...) + { + return E_FAIL; + } + + TStreamAdapter * adapter; + adapter = new TStreamAdapter(tvpstream, soOwned); + + IUnknown *istream = (IUnknown*)(IStream*)(*adapter); + *stream = istream; + istream->AddRef(); + + return S_OK; +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +__fastcall TTSSWaveContext::TTSSWaveContext(AnsiString dllname) +{ + FModule = NULL; + FHandle = NULL; + FDecoder = NULL; + + FHandle = LoadLibrary(dllname.c_str()); + if(FHandle == NULL) + { + throw Exception(dllname + "を読み込むことができません"); + } + + FGetModuleInstance =(GetModuleInstanceProc) + GetProcAddress(FHandle, "GetModuleInstance"); + FGetModuleThreadModel =(GetModuleThreadModelProc) + GetProcAddress(FHandle, "GetModuleThreadModel"); + FShowConfigWindow =(ShowConfigWindowProc) + GetProcAddress(FHandle, "ShowConfigWindow"); + FCanUnloadNow = (CanUnloadNowProc) + GetProcAddress(FHandle, "CanUnloadNow"); + + if(!FGetModuleInstance || FAILED(FGetModuleInstance(&FModule, &StorageProvider, + NULL, Application->Handle)) ) + { + FreeLibrary(FHandle); + FHandle = NULL; + throw Exception("外部 DLL "+dllname+" は使用できません"); + } +} +//--------------------------------------------------------------------------- +__fastcall TTSSWaveContext::~TTSSWaveContext() +{ + if(FDecoder) FDecoder->Release(); + if(FModule) FModule->Release(); + if(FHandle) FreeLibrary(FHandle); +} +//--------------------------------------------------------------------------- +bool __fastcall TTSSWaveContext::Start(AnsiString filename) +{ + if(FDecoder) FDecoder->Release(), FDecoder = NULL; + + + HRESULT hr; + IUnknown * decoder; + + hr = FModule->GetMediaInstance(WideString(filename).c_bstr(), &decoder); + if(FAILED(hr)) + { + throw Exception(filename + " は開くことができません"); + } + + hr = decoder->QueryInterface(IID_ITSSWaveDecoder, (void**)&FDecoder); + if(FAILED(hr)) + { + decoder->Release(); + FDecoder = NULL; + throw Exception(filename + " のメディア・タイプは扱うことができません"); + } + + decoder->Release(); + + TSSWaveFormat format; + FDecoder->GetFormat(&format); + if(format.dwBitsPerSample != 16) + { + throw Exception(filename + " は 16bit PCM に変換できないため扱うことができません"); + } + if(format.dwChannels > 8) + { + throw Exception(filename + " は 9チャネル以上あるため扱うことができません"); + } + if(format.ui64TotalSamples == 0) + { + throw Exception(filename + " は 総サンプル数が不明か、ゼロのため扱うことができません"); + } + if(format.ui64TotalSamples >= 0x10000000ui64) + { + throw Exception(filename + " は 大きすぎるため、扱うことができません"); + } + FChannels = format.dwChannels; + FFrequency = format.dwSamplesPerSec; + FBitsPerSample = 16; + FSpeakerConfig = 0; // 現時点では常に 0 (なにか規格をつくるかも) + FTotalSamples = (int)format.ui64TotalSamples; + + FGranuleSize = FChannels * sizeof(__int16); + +// FDecoder->SetPosition(0); /// test + + return true; +} +//--------------------------------------------------------------------------- +int __fastcall TTSSWaveContext::Read(__int16 * dest, int destgranules) +{ + unsigned long written; + unsigned long status ; + + int pos = 0; + int remain = destgranules; + do + { + FDecoder->Render(dest + FChannels * pos, remain, &written, &status); + remain -= written; + pos += written; + } while(remain >0 && status == 1); + + return pos; +} +//--------------------------------------------------------------------------- diff --git a/tools/win32/krdevui/looptuner2/TSSWaveContext.h b/tools/win32/krdevui/looptuner2/TSSWaveContext.h new file mode 100644 index 0000000..676cf8d --- /dev/null +++ b/tools/win32/krdevui/looptuner2/TSSWaveContext.h @@ -0,0 +1,98 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef TSSWaveContextH +#define TSSWaveContextH + +#include +#include +#include +#include +#include "WaveContext.h" +#include "tvpsnd.h" + + +//--------------------------------------------------------------------------- +class ITSSModule; +class ITSSStorageProvider; +class ITSSWaveDecoder; +class TTSSWaveContext : public TCustomWaveContext +{ + typedef HRESULT _stdcall (*GetModuleInstanceProc)(ITSSModule **out, + ITSSStorageProvider *provider, IStream * config, HWND mainwin); + typedef ULONG _stdcall (*GetModuleThreadModelProc)(void); + typedef HRESULT _stdcall (*ShowConfigWindowProc)(HWND parentwin, IStream * storage ); + typedef ULONG _stdcall (*CanUnloadNowProc)(void); + + GetModuleInstanceProc FGetModuleInstance; + GetModuleThreadModelProc FGetModuleThreadModel; + ShowConfigWindowProc FShowConfigWindow; + CanUnloadNowProc FCanUnloadNow; + + ITSSModule *FModule; + HMODULE FHandle; + ITSSWaveDecoder *FDecoder; + + + int FGranuleSize; + int FChannels; + int FFrequency; + int FBitsPerSample; + int FTotalSamples; + DWORD FSpeakerConfig; + +protected: + int __fastcall GetChannels() { return FChannels; } + int __fastcall GetFrequency() { return FFrequency; } + int __fastcall GetBitsPerSample() { return FBitsPerSample; } + int __fastcall GetTotalSamples() { return FTotalSamples; } + DWORD __fastcall GetSpeakerConfig() { return FSpeakerConfig; } + +public: + __fastcall TTSSWaveContext(AnsiString dllname); + __fastcall ~TTSSWaveContext(); + + bool __fastcall Start(AnsiString filename); + int __fastcall Read(__int16 * dest, int destgranules); +}; +//--------------------------------------------------------------------------- +class TStorageProviderImpl : public ITSSStorageProvider +{ + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid,void **ppvObjOut) + { + if(!ppvObjOut) return E_INVALIDARG; + + *ppvObjOut=NULL; + if(!memcmp(&iid,&IID_IUnknown,16)) + *ppvObjOut=(IUnknown*)this; + else if(!memcmp(&iid,&IID_ITSSStorageProvider,16)) + *ppvObjOut=(ITSSStorageProvider*)this; + + if(*ppvObjOut) + { + AddRef(); + return S_OK; + } + return E_NOINTERFACE; + } + + ULONG STDMETHODCALLTYPE AddRef(void) { return 1; } + ULONG STDMETHODCALLTYPE Release(void) { return 1; } + + HRESULT _stdcall GetStreamForRead(LPWSTR url, IUnknown ** stream ); + HRESULT _stdcall GetStreamForWrite(LPWSTR url, IUnknown ** stream ) + { return E_NOTIMPL; } + HRESULT _stdcall GetStreamForUpdate(LPWSTR url, IUnknown ** stream ) + { return E_NOTIMPL; } +}; +//--------------------------------------------------------------------------- +extern TStorageProviderImpl StorageProvider; +//--------------------------------------------------------------------------- + +#endif + diff --git a/tools/win32/krdevui/looptuner2/TotalView.cpp b/tools/win32/krdevui/looptuner2/TotalView.cpp new file mode 100644 index 0000000..bad176c --- /dev/null +++ b/tools/win32/krdevui/looptuner2/TotalView.cpp @@ -0,0 +1,479 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include +#include +#include "TotalView.h" +#include "WaveReader.h" +#include "ColorScheme.h" + +//--------------------------------------------------------------------------- +// constants +//--------------------------------------------------------------------------- +const int CONTROL_HEIGHT = 17; +const int CONTROL_WAVE_HEIGHT = 11; +const int CONTROL_WAVE_CENTER = 7; +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// MakeGradationPalette +//--------------------------------------------------------------------------- +#define G_COLOR_BLEND_8(x, y, ratio) (((x) * (ratio) + (y) * (255-(ratio))) / 255) +#define G_BLEND_RGB(x, y, ratio) (\ + (G_COLOR_BLEND_8(BYTEOF(x, 0), BYTEOF(y, 0), (ratio)) )+ \ + (G_COLOR_BLEND_8(BYTEOF(x, 1), BYTEOF(y, 1), (ratio))<<8 )+ \ + (G_COLOR_BLEND_8(BYTEOF(x, 2), BYTEOF(y, 2), (ratio))<<16) ) +static void MakeGradationPalette(Graphics::TBitmap *bmp, TColor fromcolor, TColor tocolor) +{ + int i; + +#pragma pack(push,1) + struct tagpal + { + WORD palversion; + WORD numentries; + PALETTEENTRY entry[256]; + } pal; +#pragma pack(pop) + pal.palversion = 0x300; + pal.numentries = 256; + + for(i=0;i<256;i++) + { + TColor c = (TColor)G_BLEND_RGB((int)tocolor, (int)fromcolor, i); + pal.entry[i].peRed = c & 0xff; + pal.entry[i].peGreen = (c & 0xff00) >> 8; + pal.entry[i].peBlue = (c & 0xff0000) >> 16; + pal.entry[i].peFlags = 0; + } + bmp->Palette = CreatePalette((LOGPALETTE*)&pal); +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// TThumbnailThread +// thread to create thumbnailed waveform graph +//--------------------------------------------------------------------------- +class TThumbnailThread : public TThread +{ + TWaveReader * Reader; + Graphics::TBitmap *Bitmap; + TWinControl *Owner; + +public: + __fastcall TThumbnailThread(TWinControl *owner, TWaveReader * reader, + Graphics::TBitmap *bmp) : TThread(true) + { + Owner = owner; + Reader = reader; + Bitmap = bmp; + Priority = tpIdle; + Suspended = false; + } + + __fastcall ~TThumbnailThread(void) + { + Priority = tpNormal; + Suspended = false; + Terminate(); + WaitFor(); + } + + +protected: + + void __fastcall SyncFunc() + { + Owner->Invalidate(); + } + + + void __fastcall Execute(void) + { + int x = 0; + int w = Bitmap->Width; + double ratio = (double)Reader->NumSamples / w; + + DWORD tick = GetTickCount(); + + while(!Terminated && x < w) + { + // calculate range + int start = ratio * x; + int end = ratio * (x+1); + if(end > Reader->NumSamples) end = Reader->NumSamples; + if(end - start < 1) end ++; + if(end > Reader->NumSamples) break; + + // calculate histgram + int hist[CONTROL_HEIGHT]; + for(int i = 0; i < CONTROL_HEIGHT; i++) hist[i] = 0; + + for(int p = start; p < end; p++) + { + for(int ch = 0; ch < Reader->Channels; ch++) + { + int smp = Reader->GetSampleAt(p, ch); + int n = smp * -CONTROL_WAVE_HEIGHT / 65536 + CONTROL_WAVE_CENTER; + int z = CONTROL_WAVE_CENTER; + if(n < z) + for(int i = n; i <= z; i++) hist[i]++; + else + for(int i = z; i <= n; i++) hist[i]++; + } + } + + // draw histgram graph as pixel + float idiv = 1.0 / ((end - start) * Reader->Channels); + for(int y = 0; y < CONTROL_HEIGHT; y++) + { + float p = 1.0 - (float) hist[y] * idiv; + p = 1.0 - p * p; + int ip = (int)(p * 1024); + if(ip > 255) ip = 255; + ((unsigned char *)Bitmap->ScanLine[y])[x] = ip; + } + + x++; + + DWORD now = GetTickCount(); + if(now - tick > 250) + { + Synchronize(SyncFunc); + tick = now; + } + + } + Synchronize(SyncFunc); + } +}; +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// TTotalView +//--------------------------------------------------------------------------- +__fastcall TTotalView::TTotalView(Classes::TComponent* AOwner) : + TCustomControl(AOwner) +{ + FThumbnailer = NULL; + FReader = NULL; + WaveCache = NULL; + Height = CONTROL_HEIGHT; + FMouseDowned = false; + FOnPoint = NULL; + FOnDoubleClick = NULL; + DoubleBuffered = true; + ResetAll(); +} +//--------------------------------------------------------------------------- +__fastcall TTotalView::~TTotalView() +{ + if(FThumbnailer) delete FThumbnailer; + if(WaveCache) delete WaveCache; +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::ResetAll() +{ + if(FThumbnailer) delete FThumbnailer, FThumbnailer = NULL; + FViewStart = 0; + Reader = NULL; + FMagnify = 1.0; + FViewLength = 0; + FCaretPos = -1; + FShowCaret = false; + FMarkerPos = -1; + FShowMarker = false; + Labels.clear(); + Links.clear(); + FShowCaret = false; + if(WaveCache) RecreateWaveCacheBitmap(); +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::Paint(void) +{ + if(!FReader) return; + + if(WaveCache) Canvas->Draw(0, 0, WaveCache); + + DrawViewRange(); // draw current view range + DrawLinksAndLabels(); // draw links and labels + DrawCaret(); // draw caret + DrawMarker(); // draw caret + + // draw bottom line + Canvas->Pen->Color = clBtnShadow; + Canvas->MoveTo(-1, ClientHeight - 1); + Canvas->LineTo(ClientWidth, ClientHeight - 1); +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::SetReader(TWaveReader * reader) +{ + // set wave reader + if(FThumbnailer) delete FThumbnailer, FThumbnailer = NULL; + FReader = reader; + RecreateWaveCache(); + Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::Resize() +{ + if(!WaveCache) return; + if(WaveCache->Width != ClientWidth) RecreateWaveCache(); +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::RecreateWaveCache() +{ + if(!FReader) return; + + // delete current thumbnailer + if(FThumbnailer) delete FThumbnailer, FThumbnailer = NULL; + + // caluclate magnification level + FMagnify = (double)FReader->NumSamples / (ClientWidth ? ClientWidth : 0); + + // recreate bitmap + RecreateWaveCacheBitmap(); + + // begin thumbnailing + FThumbnailer = new TThumbnailThread(this, FReader, WaveCache); + +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::RecreateWaveCacheBitmap() +{ + // recreate bitmap + if(WaveCache) delete WaveCache, WaveCache = NULL; + WaveCache = new Graphics::TBitmap(); + WaveCache->Width = ClientWidth; + WaveCache->Height = ClientHeight; + WaveCache->PixelFormat = pf8bit; + MakeGradationPalette(WaveCache, C_CLIENT, C_WAVE); +} +//--------------------------------------------------------------------------- +void TTotalView::DrawViewRange() +{ + int start = FViewStart / FMagnify; + int length = FViewLength / FMagnify; + + RECT r; + r.top = 0; + r.bottom = 3; + r.left = start; + r.right = start + length; + InvertRect(Canvas->Handle, &r); + + r.top = ClientHeight - 5; + r.bottom = ClientHeight - 2; + r.left = start; + r.right = start + length; + InvertRect(Canvas->Handle, &r); + + r.top = 1; + r.bottom = 3; + r.left = start + 1; + r.right = start + length - 1; + InvertRect(Canvas->Handle, &r); + + r.top = ClientHeight - 5; + r.bottom = ClientHeight - 3; + r.left = start + 1; + r.right = start + length - 1; + InvertRect(Canvas->Handle, &r); +} +//--------------------------------------------------------------------------- +void TTotalView::InvalidateViewRange() +{ + int start = FViewStart / FMagnify; + int length = FViewLength / FMagnify; + RECT r; + r.top = 0; + r.bottom = ClientHeight - 1; + r.left = start; + r.right = start + length; + ::InvalidateRect(Handle, &r, FALSE); +} +//--------------------------------------------------------------------------- +void TTotalView::SetViewRange(int start, int length) +{ + if(FViewStart != start || FViewLength != length) + { + InvalidateViewRange(); + + FViewStart = start; + FViewLength = length; + + InvalidateViewRange(); + } +} +//--------------------------------------------------------------------------- +void TTotalView::DrawCaret() +{ + if(FShowCaret) + { + int pos = FCaretPos / FMagnify; + RECT r; + r.top = 0; + r.bottom = ClientHeight - 2; + r.left = pos; + r.right = pos + 1; + InvertRect(Canvas->Handle, &r); + } +} +//--------------------------------------------------------------------------- +void TTotalView::InvalidateCaret() +{ + if(FShowCaret) + { + int pos = FCaretPos / FMagnify; + RECT r; + r.top = 0; + r.bottom = ClientHeight - 2; + r.left = pos; + r.right = pos + 1; + ::InvalidateRect(Handle, &r, FALSE); + } +} +//--------------------------------------------------------------------------- +void TTotalView::SetCaretState(int caretpos, bool showcaret) +{ + if(FCaretPos != caretpos || FShowCaret != showcaret) + { + InvalidateCaret(); + + FCaretPos = caretpos; + FShowCaret = showcaret; + + InvalidateCaret(); + } +} +//--------------------------------------------------------------------------- +void TTotalView::DrawMarker() +{ + if(FShowMarker) + { + int pos = FMarkerPos / FMagnify; + RECT r; + r.top = 0; + r.bottom = ClientHeight - 2; + r.left = pos; + r.right = pos + 1; + InvertRect(Canvas->Handle, &r); + } +} +//--------------------------------------------------------------------------- +void TTotalView::InvalidateMarker() +{ + if(FShowMarker) + { + int pos = FMarkerPos / FMagnify; + RECT r; + r.top = 0; + r.bottom = ClientHeight - 2; + r.left = pos; + r.right = pos + 1; + ::InvalidateRect(Handle, &r, FALSE); + } +} +//--------------------------------------------------------------------------- +void TTotalView::SetMarkerState(int markerpos, bool showmarker) +{ + if(FMarkerPos != markerpos || FShowMarker != showmarker) + { + InvalidateMarker(); + + FMarkerPos = markerpos; + FShowMarker = showmarker; + + InvalidateMarker(); + } +} +//--------------------------------------------------------------------------- +void TTotalView::DrawLinksAndLabels() +{ + // draw links and labels + + // draw labels + Canvas->Pen->Color = C_WAVETHUMB_LABELS; + for(unsigned int i = 0; i < Labels.size(); i++) + { + int pos = Labels[i].Position / FMagnify; + Canvas->MoveTo(pos, 0); + Canvas->LineTo(pos, ClientHeight - 2); + } + + // draw links + Canvas->Pen->Color = C_WAVETHUMB_LINKS; + for(unsigned int i = 0; i < Links.size(); i++) + { + int from = Links[i].From / FMagnify; + int to = Links[i].To / FMagnify; + Canvas->MoveTo(from, CONTROL_WAVE_CENTER); + Canvas->LineTo(to , CONTROL_WAVE_CENTER); + Canvas->MoveTo(from, CONTROL_WAVE_CENTER - 2); + Canvas->LineTo(from, CONTROL_WAVE_CENTER + 3); + Canvas->MoveTo(to, CONTROL_WAVE_CENTER - 2); + Canvas->LineTo(to, CONTROL_WAVE_CENTER + 3); + } + +} +//--------------------------------------------------------------------------- +void TTotalView::SetLinks(const std::vector & links) +{ + Links = links; + Invalidate(); +} +//--------------------------------------------------------------------------- +void TTotalView::SetLabels(const std::vector & labels) +{ + Labels = labels; + Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::MouseDown(TMouseButton button, TShiftState shift, int x, int y) +{ + if(!FReader) return; + if(!FMouseDowned) + { + FMouseDowned = true; + LastClickedPos = x * FMagnify; + if(FOnPoint) FOnPoint(this, x * FMagnify); + } +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::MouseMove(TShiftState shift, int x, int y) +{ + if(!FReader) return; + if(FMouseDowned) if(FOnPoint) FOnPoint(this, x * FMagnify); +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::MouseUp(TMouseButton button, TShiftState shift, int x, int y) +{ + if(!FReader) return; + FMouseDowned = false; +} +//--------------------------------------------------------------------------- +void __fastcall TTotalView::DblClick(void) +{ + if(!FReader) return; + FMouseDowned = true; + if(FOnDoubleClick) FOnDoubleClick(this, LastClickedPos); +} +//--------------------------------------------------------------------------- + + diff --git a/tools/win32/krdevui/looptuner2/TotalView.h b/tools/win32/krdevui/looptuner2/TotalView.h new file mode 100644 index 0000000..af048fd --- /dev/null +++ b/tools/win32/krdevui/looptuner2/TotalView.h @@ -0,0 +1,121 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef TotalViewH +#define TotalViewH + +#include "WaveLoopManager.h" + +#include +#include + + +//--------------------------------------------------------------------------- +class TWaveReader; +//--------------------------------------------------------------------------- +typedef void __fastcall (__closure *TTotalViewPointEvent)(TObject *Sender, int pos); +//--------------------------------------------------------------------------- +class TThumbnailThread; +class TTotalView : public TCustomControl +{ + typedef TCustomControl inherited; + +//-- constructor and destructor +public: + __fastcall TTotalView(Classes::TComponent* AOwner); + __fastcall ~TTotalView(); + +private: + double FMagnify; + + TWaveReader * FReader; + void __fastcall SetReader(TWaveReader * reader); + + TThumbnailThread *FThumbnailer; + Graphics::TBitmap * WaveCache; + +public: + void __fastcall ResetAll(); + __property TWaveReader * Reader = { read = FReader, write = SetReader }; + +protected: + void __fastcall Paint(void); + DYNAMIC void __fastcall Resize(); + void __fastcall RecreateWaveCache(); + void __fastcall RecreateWaveCacheBitmap(); + + +//-- view range + int FViewStart; + int FViewLength; + +protected: + void DrawViewRange(); + void InvalidateViewRange(); + +public: + void SetViewRange(int start, int length); + + +//-- caret + int FCaretPos; + bool FShowCaret; + +protected: + void DrawCaret(); + void InvalidateCaret(); + +public: + void SetCaretState(int caretpos, bool showcaret); + +//-- marker + int FMarkerPos; + bool FShowMarker; + +protected: + void DrawMarker(); + void InvalidateMarker(); + +public: + void SetMarkerState(int markerpos, bool showmarker); + + +//-- links and labels + std::vector Links; + std::vector Labels; + +protected: + void DrawLinksAndLabels(); + +public: + void SetLinks(const std::vector & links); + void SetLabels(const std::vector & labels); + +//-- input events +private: + TTotalViewPointEvent FOnPoint; + TTotalViewPointEvent FOnDoubleClick; + + bool FMouseDowned; + int LastClickedPos; + +protected: + DYNAMIC void __fastcall MouseDown(TMouseButton button, TShiftState shift, int x, int y); + DYNAMIC void __fastcall MouseMove(TShiftState shift, int x, int y); + DYNAMIC void __fastcall MouseUp(TMouseButton button, TShiftState shift, int x, int y); + DYNAMIC void __fastcall DblClick(void); + +public: + __property TTotalViewPointEvent OnPoint = { read = FOnPoint, write = FOnPoint }; + __property TTotalViewPointEvent OnDoubleClick = { read = FOnDoubleClick, write = FOnDoubleClick }; + + +}; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/looptuner2/WaveContext.h b/tools/win32/krdevui/looptuner2/WaveContext.h new file mode 100644 index 0000000..55aa93d --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveContext.h @@ -0,0 +1,38 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef WaveContextH +#define WaveContextH + +#include + +//--------------------------------------------------------------------------- +class TCustomWaveContext +{ +protected: + virtual int __fastcall GetChannels() = 0; + virtual int __fastcall GetFrequency() = 0; + virtual int __fastcall GetTotalSamples() = 0; + virtual DWORD __fastcall GetSpeakerConfig() = 0; + +public: + __fastcall TCustomWaveContext() { }; + virtual __fastcall ~TCustomWaveContext() { }; + + virtual bool __fastcall Start(AnsiString filename) = 0; + virtual int __fastcall Read(__int16 * dest, int destsize) = 0; + + __property int Channels = {read = GetChannels}; + __property int Frequency = {read = GetFrequency}; + __property DWORD SpeakerConfig = {read = GetSpeakerConfig}; + __property int TotalSamples = {read = GetTotalSamples}; +}; +//--------------------------------------------------------------------------- + + +#endif diff --git a/tools/win32/krdevui/looptuner2/WaveLoopManager.cpp b/tools/win32/krdevui/looptuner2/WaveLoopManager.cpp new file mode 100644 index 0000000..bdfc6ca --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveLoopManager.cpp @@ -0,0 +1,1436 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +// Wave Loop Manager +//--------------------------------------------------------------------------- +/* + This module will be shared between TVP2 and + Loop Tuner 2 (a GUI loop-point editor) +*/ + +#include "tjsCommHead.h" + +#include +#include "tjsTypes.h" +#include "WaveLoopManager.h" +#include "CharacterSet.h" + +#ifdef TVP_IN_LOOP_TUNER + #include "WaveReader.h" +#else + #include "WaveIntf.h" +#endif + + +#ifdef __BORLANDC__ + #define strcasecmp strcmpi + #define strncasecmp strncmpi +#endif + +//--------------------------------------------------------------------------- +const int TVPWaveLoopLinkGiveUpCount = 10; + // This is for preventing infinite loop caused by recursive links. + // If the decoding point does not change when the loop manager follows the + // links, after 'TVPWaveLoopLinkGiveUpCount' times the loop manager + // will give up the decoding. +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// Wave Sample Types +//--------------------------------------------------------------------------- +#ifndef TJS_HOST_IS_BIG_ENDIAN + #define TJS_HOST_IS_BIG_ENDIAN 0 +#endif + +#ifdef __WIN32__ + // for assembler compatibility + #pragma pack(push,1) +#endif +struct tTVPPCM8 +{ + tjs_uint8 value; + tTVPPCM8(tjs_int v) { value = (tjs_uint8)(v + 0x80); } + void operator = (tjs_int v) { value = (tjs_uint8)(v + 0x80); } + operator tjs_int () const { return (tjs_int)value - 0x80; } +}; +struct tTVPPCM24 +{ + tjs_uint8 value[3]; + tTVPPCM24(tjs_int v) + { + operator = (v); + } + void operator =(tjs_int v) + { +#if TJS_HOST_IS_BIG_ENDIAN + value[0] = (v & 0xff0000) >> 16; + value[1] = (v & 0x00ff00) >> 8; + value[2] = (v & 0x0000ff); +#else + value[0] = (v & 0x0000ff); + value[1] = (v & 0x00ff00) >> 8; + value[2] = (v & 0xff0000) >> 16; +#endif + } + operator tjs_int () const + { + tjs_int t; +#if TJS_HOST_IS_BIG_ENDIAN + t = ((tjs_int)value[0] << 16) + ((tjs_int)value[1] << 8) + ((tjs_int)value[2]); +#else + t = ((tjs_int)value[2] << 16) + ((tjs_int)value[1] << 8) + ((tjs_int)value[0]); +#endif + t |= -(t&0x800000); // extend sign + return t; + } +}; +#ifdef __WIN32__ + #pragma pack(pop) +#endif +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// Crossfade Template function +//--------------------------------------------------------------------------- +template +static void TVPCrossFadeIntegerBlend(void *dest, void *src1, void *src2, + tjs_int ratiostart, tjs_int ratioend, + tjs_int samples, tjs_int channels) +{ + tjs_uint blend_step = (tjs_int)( + ( + (ratioend - ratiostart) * ((tjs_int64)1<<32) / 100 + ) / samples); + const T *s1 = (const T *)src1; + const T *s2 = (const T *)src2; + T *out = (T *)dest; + tjs_uint ratio = (tjs_int)(ratiostart * ((tjs_int64)1<<32) / 100); + for(tjs_int i = 0; i < samples; i++) + { + for(tjs_int j = channels - 1; j >= 0; j--) + { + tjs_int si1 = (tjs_int)*s1; + tjs_int si2 = (tjs_int)*s2; + tjs_int o = (tjs_int) ( + (((tjs_int64)si2 * (tjs_uint64)ratio) >> 32) + + (((tjs_int64)si1 * (0x100000000ui64 - (tjs_uint64)ratio) ) >> 32) ); + *out = o; + s1 ++; + s2 ++; + out ++; + } + ratio += blend_step; + } +} +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +// tTVPWaveLoopManager +//--------------------------------------------------------------------------- +tTVPWaveLoopManager::tTVPWaveLoopManager() +{ + Position = 0; + IsLinksSorted = false; + IsLabelsSorted = false; + CrossFadeSamples = NULL; + CrossFadeLen = 0; + CrossFadePosition = 0; + Decoder = NULL; + IgnoreLinks = false; + Looping = false; + Format = new tTVPWaveFormat; + memset(Format, 0, sizeof(*Format)); + + ClearFlags(); + FlagsModifiedByLabelExpression = false; +} +//--------------------------------------------------------------------------- +tTVPWaveLoopManager::~tTVPWaveLoopManager() +{ + ClearCrossFadeInformation(); + delete Format; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::SetDecoder(tTVPWaveDecoder * decoder) +{ + // set decoder and compute ShortCrossFadeHalfSamples + Decoder = decoder; + if(decoder) + decoder->GetFormat(*Format); + else + memset(Format, 0, sizeof(*Format)); + ShortCrossFadeHalfSamples = + Format->SamplesPerSec * TVP_WL_SMOOTH_TIME_HALF / 1000; +} +//--------------------------------------------------------------------------- +int tTVPWaveLoopManager::GetFlag(tjs_int index) +{ + volatile tTJSCriticalSectionHolder CS(FlagsCS); + return Flags[index]; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::CopyFlags(tjs_int *dest) +{ + volatile tTJSCriticalSectionHolder CS(FlagsCS); + // copy flags into dest, and clear FlagsModifiedByLabelExpression + memcpy(dest, Flags, sizeof(Flags)); + FlagsModifiedByLabelExpression = false; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetFlagsModifiedByLabelExpression() +{ + volatile tTJSCriticalSectionHolder CS(FlagsCS); + return FlagsModifiedByLabelExpression; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::SetFlag(tjs_int index, tjs_int f) +{ + volatile tTJSCriticalSectionHolder CS(FlagsCS); + if(f < 0) f = 0; + if(f > TVP_WL_MAX_FLAG_VALUE) f = TVP_WL_MAX_FLAG_VALUE; + Flags[index] = f; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::ClearFlags() +{ + volatile tTJSCriticalSectionHolder CS(FlagsCS); + for(tjs_int i = 0; i < TVP_WL_MAX_FLAGS; i++) Flags[i] = 0; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::ClearLinksAndLabels() +{ + // clear links and labels + volatile tTJSCriticalSectionHolder CS(FlagsCS); + Labels.clear(); + Links.clear(); + IsLinksSorted = false; + IsLabelsSorted = false; +} +//--------------------------------------------------------------------------- +const std::vector & tTVPWaveLoopManager::GetLinks() const +{ + volatile tTJSCriticalSectionHolder + CS(const_cast(this)->FlagsCS); + return Links; +} +//--------------------------------------------------------------------------- +const std::vector & tTVPWaveLoopManager::GetLabels() const +{ + volatile tTJSCriticalSectionHolder + CS(const_cast(this)->FlagsCS); + return Labels; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::SetLinks(const std::vector & links) +{ + volatile tTJSCriticalSectionHolder CS(FlagsCS); + Links = links; + IsLinksSorted = false; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::SetLabels(const std::vector & labels) +{ + volatile tTJSCriticalSectionHolder CS(FlagsCS); + Labels = labels; + IsLabelsSorted = false; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetIgnoreLinks() const +{ + volatile tTJSCriticalSectionHolder + CS(const_cast(this)->DataCS); + return IgnoreLinks; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::SetIgnoreLinks(bool b) +{ + volatile tTJSCriticalSectionHolder CS(DataCS); + IgnoreLinks = b; +} +//--------------------------------------------------------------------------- +tjs_int64 tTVPWaveLoopManager::GetPosition() const +{ + // we cannot assume that the 64bit data access is truely atomic on 32bit machines. + volatile tTJSCriticalSectionHolder + CS(const_cast(this)->FlagsCS); + return Position; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::SetPosition(tjs_int64 pos) +{ + volatile tTJSCriticalSectionHolder CS(DataCS); + Position = pos; + ClearCrossFadeInformation(); + Decoder->SetPosition(pos); +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::Decode(void *dest, tjs_uint samples, tjs_uint &written, + std::vector &segments, + std::vector &labels) +{ + // decode from current position + volatile tTJSCriticalSectionHolder CS(DataCS); + + segments.clear(); + labels.clear(); + written = 0; + tjs_uint8 *d = (tjs_uint8*)dest; + + tjs_int give_up_count = 0; + + while(written != samples/* && Position < Format->TotalSamples*/) + { + // decide next operation + tjs_int64 next_event_pos; + bool next_not_found = false; + tjs_int before_count; + + // check nearest link + tTVPWaveLoopLink link; + if(!IgnoreLinks && GetNearestEvent(Position, link, false)) + { + // nearest event found ... + if(link.From == Position) + { + // do jump + give_up_count ++; + if(give_up_count >= TVPWaveLoopLinkGiveUpCount) + break; // give up decoding + + Position = link.To; + if(!CrossFadeSamples) + Decoder->SetPosition(Position); + continue; + } + + if(link.Smooth) + { + // the nearest event is a smooth link + // bofore_count is sample count before 50%-50% blend + // after_count is sample count after 50%-50% blend + before_count = ShortCrossFadeHalfSamples; + // adjust before count + if(link.From - before_count < 0) + before_count = (tjs_int)link.From; + if(link.To - before_count < 0) + before_count = (tjs_int)link.To; + if(link.From - before_count > Position) + { + // Starting crossfade is the nearest next event, + // but some samples must be decoded before the event comes. + next_event_pos = link.From - before_count; + } + else if(!CrossFadeSamples) + { + // just position to start crossfade + // or crossfade must already start + next_event_pos = link.From; + // adjust before_count + before_count = link.From - Position; + // adjust after count + tjs_int after_count = ShortCrossFadeHalfSamples; + if(Format->TotalSamples - link.From < after_count) + after_count = + (tjs_int)(Format->TotalSamples - link.From); + if(Format->TotalSamples - link.To < after_count) + after_count = + (tjs_int)(Format->TotalSamples - link.To); + tTVPWaveLoopLink over_to_link; + if(GetNearestEvent(link.To, over_to_link, true)) + { + if(over_to_link.From - link.To < after_count) + after_count = + (tjs_int)(over_to_link.From - link.To); + } + // prepare crossfade + // allocate memory + tjs_uint8 *src1 = NULL; + tjs_uint8 *src2 = NULL; + try + { + tjs_int alloc_size = + (before_count + after_count) * + Format->BytesPerSample * Format->Channels; + CrossFadeSamples = new tjs_uint8[alloc_size]; + src1 = new tjs_uint8[alloc_size]; + src2 = new tjs_uint8[alloc_size]; + } + catch(...) + { + // memory allocation failed. perform normal link. + if(CrossFadeSamples) + delete [] CrossFadeSamples, + CrossFadeSamples = NULL; + if(src1) delete [] src1; + if(src2) delete [] src2; + next_event_pos = link.From; + } + if(CrossFadeSamples) + { + // decode samples + tjs_uint decoded1 = 0, decoded2 = 0; + + Decoder->Render((void*)src1, + before_count + after_count, decoded1); + + Decoder->SetPosition( + link.To - before_count); + + Decoder->Render((void*)src2, + before_count + after_count, decoded2); + + // perform crossfade + tjs_int after_offset = + before_count * Format->BytesPerSample * Format->Channels; + DoCrossFade(CrossFadeSamples, + src1, src2, before_count, 0, 50); + DoCrossFade(CrossFadeSamples + after_offset, + src1 + after_offset, src2 + after_offset, + after_count, 50, 100); + delete [] src1; + delete [] src2; + // reset CrossFadePosition and CrossFadeLen + CrossFadePosition = 0; + CrossFadeLen = before_count + after_count; + } + } + else + { + next_event_pos = link.From; + } + } + else + { + // normal jump + next_event_pos = link.From; + } + } + else + { + // event not found + next_not_found = true; + } + + tjs_int one_unit; + + if(next_not_found || next_event_pos - Position > (samples - written)) + one_unit = samples - written; + else + one_unit = (tjs_int) (next_event_pos - Position); + + if(CrossFadeSamples) + { + if(one_unit > CrossFadeLen - CrossFadePosition) + one_unit = CrossFadeLen - CrossFadePosition; + } + segments.push_back(tTVPWaveLoopSegment(Position, one_unit)); + + if(one_unit > 0) give_up_count = 0; // reset give up count + + // evaluate each label + tjs_uint label_base = labels.size(); + GetLabelAt(Position, Position + one_unit, labels); + for(std::vector::iterator i = labels.begin() + label_base; + i != labels.end(); i++) + { + if(i->Name.c_str()[0] == ':') + { + // for each label + EvalLabelExpression(i->Name); + } + } + + // calculate each label offset + for(std::vector::iterator i = labels.begin() + label_base; + i != labels.end(); i++) + i->Offset = (tjs_int)(i->Position - Position) + written; + + // decode or copy + if(!CrossFadeSamples) + { + // not crossfade + // decode direct into destination buffer + tjs_uint decoded; + Decoder->Render((void *)d, one_unit, decoded); + Position += decoded; + written += decoded; + if(decoded != (tjs_uint)one_unit) + { + // must be the end of the decode + if(!Looping) break; // end decoding + // rewind and continue + if(Position == 0) + { + // already rewinded; must be an error + break; + } + Position = 0; + Decoder->SetPosition(0); + } + d += decoded * Format->BytesPerSample * Format->Channels; + } + else + { + // in cross fade + // copy prepared samples + memcpy((void *)d, + CrossFadeSamples + + CrossFadePosition * Format->BytesPerSample * Format->Channels, + one_unit * Format->BytesPerSample * Format->Channels); + CrossFadePosition += one_unit; + Position += one_unit; + written += one_unit; + d += one_unit * Format->BytesPerSample * Format->Channels; + if(CrossFadePosition == CrossFadeLen) + { + // crossfade has finished + ClearCrossFadeInformation(); + } + } + } // while +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetNearestEvent(tjs_int64 current, + tTVPWaveLoopLink & link, bool ignore_conditions) +{ + // search nearest event in future, from current. + // this checks conditions unless ignore_conditions is true. + volatile tTJSCriticalSectionHolder CS(FlagsCS); + + if(Links.size() == 0) return false; // there are no event + + if(!IsLinksSorted) + { + std::sort(Links.begin(), Links.end()); + IsLinksSorted = true; + } + + // search nearest next event using binary search + tjs_int s = 0, e = Links.size(); + while(e - s > 1) + { + tjs_int m = (s+e)/2; + if(Links[m].From <= current) + s = m; + else + e = m; + } + + if(s < (int)Links.size()-1 && Links[s].From < current) s++; + + if((tjs_uint)s >= Links.size() || Links[s].From < current) + { + // no links available + return false; + } + + // rewind while the link 'from' is the same + tjs_int64 from = Links[s].From; + while(true) + { + if(s >= 1 && Links[s-1].From == from) + s--; + else + break; + } + + // check conditions + if(!ignore_conditions) + { + do + { + // check condition + if(Links[s].CondVar != -1) + { + bool match = false; + switch(Links[s].Condition) + { + case llcNone: + match = true; break; + case llcEqual: + if(Links[s].RefValue == Flags[Links[s].CondVar]) match = true; + break; + case llcNotEqual: + if(Links[s].RefValue != Flags[Links[s].CondVar]) match = true; + break; + case llcGreater: + if(Links[s].RefValue < Flags[Links[s].CondVar]) match = true; + break; + case llcGreaterOrEqual: + if(Links[s].RefValue <= Flags[Links[s].CondVar]) match = true; + break; + case llcLesser: + if(Links[s].RefValue > Flags[Links[s].CondVar]) match = true; + break; + case llcLesserOrEqual: + if(Links[s].RefValue >= Flags[Links[s].CondVar]) match = true; + break; + default: + match = false; + } + if(match) break; // condition matched + } + else + { + break; + } + s++; + } while((tjs_uint)s < Links.size()); + + if((tjs_uint)s >= Links.size() || Links[s].From < current) + { + // no links available + return false; + } + } + + link = Links[s]; + + return true; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::GetLabelAt(tjs_int64 from, tjs_int64 to, + std::vector & labels) +{ + volatile tTJSCriticalSectionHolder CS(FlagsCS); + + if(Labels.size() == 0) return; // no labels found + if(!IsLabelsSorted) + { + std::sort(Labels.begin(), Labels.end()); + IsLabelsSorted = true; + } + + // search nearest label using binary search + tjs_int s = 0, e = Labels.size(); + while(e - s > 1) + { + tjs_int m = (s+e)/2; + if(Labels[m].Position <= from) + s = m; + else + e = m; + } + + if(s < (int)Labels.size()-1 && Labels[s].Position < from) s++; + + if((tjs_uint)s >= Labels.size() || Labels[s].Position < from) + { + // no labels available + return; + } + + // rewind while the label position is the same + tjs_int64 pos = Labels[s].Position; + while(true) + { + if(s >= 1 && Labels[s-1].Position == pos) + s--; + else + break; + } + + // search labels + for(; s < (int)Labels.size(); s++) + { + if(Labels[s].Position >= from && Labels[s].Position < to) + labels.push_back(Labels[s]); + else + break; + } +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::DoCrossFade(void *dest, void *src1, + void *src2, tjs_int samples, tjs_int ratiostart, tjs_int ratioend) +{ + // do on-memory wave crossfade + // using src1 (fading out) and src2 (fading in). + if(samples == 0) return; // nothing to do + + if(Format->IsFloat) + { + float blend_step = + (float)((ratioend - ratiostart) / 100.0 / samples); + const float *s1 = (const float *)src1; + const float *s2 = (const float *)src2; + float *out = (float *)dest; + float ratio = ratiostart / 100.0; + for(tjs_int i = 0; i < samples; i++) + { + for(tjs_int j = Format->Channels - 1; j >= 0; j--) + { + *out = *s1 + (*s2 - *s1) * ratio; + s1 ++; + s2 ++; + out ++; + } + ratio += blend_step; + } + } + else + { + if(Format->BytesPerSample == 1) + { + TVPCrossFadeIntegerBlend(dest, src1, src2, + ratiostart, ratioend, samples, Format->Channels); + } + else if(Format->BytesPerSample == 2) + { + TVPCrossFadeIntegerBlend(dest, src1, src2, + ratiostart, ratioend, samples, Format->Channels); + } + else if(Format->BytesPerSample == 3) + { + TVPCrossFadeIntegerBlend(dest, src1, src2, + ratiostart, ratioend, samples, Format->Channels); + } + else if(Format->BytesPerSample == 4) + { + TVPCrossFadeIntegerBlend(dest, src1, src2, + ratiostart, ratioend, samples, Format->Channels); + } + } +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::ClearCrossFadeInformation() +{ + if(CrossFadeSamples) delete [] CrossFadeSamples, CrossFadeSamples = NULL; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetLabelExpression(const tTVPLabelStringType &label, + tTVPWaveLoopManager::tExpressionToken * ope, + tjs_int *lv, + tjs_int *rv, bool *is_rv_indirect) +{ + const tTVPLabelCharType * p = label.c_str(); + tExpressionToken token; + tExpressionToken operation; + tjs_int value = 0; + tjs_int lvalue = 0; + tjs_int rvalue = 0; + bool rv_indirect = false; + + if(*p != ':') return false; // not expression + p++; + + token = GetExpressionToken(p, &value); + if(token != etLBracket) return false; // lvalue must form of '[' integer ']' + token = GetExpressionToken(p, &value); + if(token != etInteger) return false; // lvalue must form of '[' integer ']' + lvalue = value; + if(lvalue < 0 || lvalue >= TVP_WL_MAX_FLAGS) return false; // out of the range + token = GetExpressionToken(p, &value); + if(token != etRBracket) return false; // lvalue must form of '[' integer ']' + + token = GetExpressionToken(p, &value); + switch(token) + { + case etEqual: + case etPlusEqual: case etIncrement: + case etMinusEqual: case etDecrement: + break; + default: + return false; // unknown operation + } + operation = token; + + token = GetExpressionToken(p, &value); + if(token == etLBracket) + { + // indirect value + token = GetExpressionToken(p, &value); + if(token != etInteger) return false; // rvalue does not have form of '[' integer ']' + rvalue = value; + if(rvalue < 0 || rvalue >= TVP_WL_MAX_FLAGS) return false; // out of the range + token = GetExpressionToken(p, &value); + if(token != etRBracket) return false; // rvalue does not have form of '[' integer ']' + rv_indirect = true; + } + else if(token == etInteger) + { + // direct value + rv_indirect = false; + rvalue = value; + } + else if(token == etEOE) + { + if(!(operation == etIncrement || operation == etDecrement)) + return false; // increment or decrement cannot have operand + } + else + { + return false; // syntax error + } + + token = GetExpressionToken(p, &value); + if(token != etEOE) return false; // excess characters + + if(ope) *ope = operation; + if(lv) *lv = lvalue; + if(rv) *rv = rvalue; + if(is_rv_indirect) * is_rv_indirect = rv_indirect; + + return true; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::EvalLabelExpression(const tTVPLabelStringType &label) +{ + // eval expression specified by 'label' + // commit the result when 'commit' is true. + // returns whether the label syntax is correct. + volatile tTJSCriticalSectionHolder CS(FlagsCS); + + tExpressionToken operation; + tjs_int lvalue; + tjs_int rvalue; + bool is_rv_indirect; + + if(!GetLabelExpression(label, &operation, &lvalue, &rvalue, &is_rv_indirect)) return false; + + if(is_rv_indirect) rvalue = Flags[rvalue]; + + switch(operation) + { + case etEqual: + FlagsModifiedByLabelExpression = true; + Flags[lvalue] = rvalue; + break; + case etPlusEqual: + FlagsModifiedByLabelExpression = true; + Flags[lvalue] += rvalue; + break; + case etMinusEqual: + FlagsModifiedByLabelExpression = true; + Flags[lvalue] -= rvalue; + break; + case etIncrement: + FlagsModifiedByLabelExpression = true; + Flags[lvalue] ++; + break; + case etDecrement: + FlagsModifiedByLabelExpression = true; + Flags[lvalue] --; + break; + } + + if(Flags[lvalue] < 0) Flags[lvalue] = 0; + if(Flags[lvalue] > TVP_WL_MAX_FLAG_VALUE) Flags[lvalue] = TVP_WL_MAX_FLAG_VALUE; + + return true; +} +//--------------------------------------------------------------------------- +tTVPWaveLoopManager::tExpressionToken + tTVPWaveLoopManager::GetExpressionToken(const tTVPLabelCharType * & p, tjs_int * value) +{ + // get token at pointer 'p' + + while(*p && *p <= 0x20) p++; // skip spaces + if(!*p) return etEOE; + + switch(*p) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + // numbers + if(value) GetLabelCharInt(p, *value); + while(*p && *p >= '0' && *p <= '9') p++; + return etInteger; + + case '[': + p++; + return etLBracket; + case ']': + p++; + return etRBracket; + + case '=': + p++; + return etEqual; + + case '+': + p++; + if(*p == '=') { p++; return etPlusEqual; } + if(*p == '+') { p++; return etIncrement; } + return etPlus; + case '-': + p++; + if(*p == '=') { p++; return etMinusEqual; } + if(*p == '-') { p++; return etDecrement; } + return etPlus; + + default: + ; + } + + p++; + return etUnknown; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetLabelCharInt(const tTVPLabelCharType *s, tjs_int &v) +{ + // convert string to integer + tjs_int r = 0; + bool sign = false; + while(*s && *s <= 0x20) s++; // skip spaces + if(!*s) return false; + if(*s == '-') + { + sign = true; + s++; + while(*s && *s <= 0x20) s++; // skip spaces + if(!*s) return false; + } + + while(*s >= '0' && *s <= '9') + { + r *= 10; + r += *s - '0'; + s++; + } + if(sign) r = -r; + v = r; + return true; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetInt(char *s, tjs_int &v) +{ + // convert string to integer + tjs_int r = 0; + bool sign = false; + while(*s && *s <= 0x20) s++; // skip spaces + if(!*s) return false; + if(*s == '-') + { + sign = true; + s++; + while(*s && *s <= 0x20) s++; // skip spaces + if(!*s) return false; + } + + while(*s >= '0' && *s <= '9') + { + r *= 10; + r += *s - '0'; + s++; + } + if(sign) r = -r; + v = r; + return true; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetInt64(char *s, tjs_int64 &v) +{ + // convert string to integer + tjs_int64 r = 0; + bool sign = false; + while(*s && *s <= 0x20) s++; // skip spaces + if(!*s) return false; + if(*s == '-') + { + sign = true; + s++; + while(*s && *s <= 0x20) s++; // skip spaces + if(!*s) return false; + } + + while(*s >= '0' && *s <= '9') + { + r *= 10; + r += *s - '0'; + s++; + } + if(sign) r = -r; + v = r; + return true; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetBool(char *s, bool &v) +{ + // convert string to boolean + if(!strcasecmp(s, "True")) { v = true; return true; } + if(!strcasecmp(s, "False")) { v = false; return true; } + if(!strcasecmp(s, "Yes")) { v = true; return true; } + if(!strcasecmp(s, "No")) { v = false; return true; } + return false; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetCondition(char *s, tTVPWaveLoopLinkCondition &v) +{ + // get condition value + if(!strcasecmp(s, "no")) { v = llcNone; return true; } + if(!strcasecmp(s, "eq")) { v = llcEqual; return true; } + if(!strcasecmp(s, "ne")) { v = llcNotEqual; return true; } + if(!strcasecmp(s, "gt")) { v = llcGreater; return true; } + if(!strcasecmp(s, "ge")) { v = llcGreaterOrEqual; return true; } + if(!strcasecmp(s, "lt")) { v = llcLesser; return true; } + if(!strcasecmp(s, "le")) { v = llcLesserOrEqual; return true; } + return false; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetString(char *s, tTVPLabelStringType &v) +{ + // convert utf-8 string s to v + + // compute output (unicode) size + tjs_int size = TVPUtf8ToWideCharString(s, NULL); + if(size == -1) return false; // not able to convert the string + + // allocate output buffer + tjs_char *us = new tjs_char[size + 1]; + try + { + TVPUtf8ToWideCharString(s, us); + us[size] = TJS_W('\0'); + +#ifdef TVP_IN_LOOP_TUNER + // convert us (an array of wchar_t) to AnsiString + v = AnsiString(us); +#else + // convert us (an array of wchar_t) to ttstr + v = ttstr(us); +#endif + + } + catch(...) + { + delete [] us; + throw; + } + delete [] us; + return true; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::GetEntityToken(char * & p, char **name, char **value) +{ + // get name=value string at 'p'. + // returns whether the token can be got or not. + // on success, *id will point start of the name, and value will point + // start of the value. the buffer given by 'start' will be destroied. + + char * namelast; + char * valuelast; + char delimiter = '\0'; + + // skip preceeding white spaces + while(isspace(*p)) p++; + if(!*p) return false; + + // p will now be a name + *name = p; + + // find white space or '=' + while(!isspace(*p) && *p != '=' && *p) p++; + if(!*p) return false; + + namelast = p; + + // skip white space + while(isspace(*p)) p++; + if(!*p) return false; + + // is current pointer pointing '=' ? + if(*p != '=') return false; + + // step pointer + p ++; + if(!*p) return false; + + // skip white space + while(isspace(*p)) p++; + if(!*p) return false; + + // find delimiter + if(*p == '\'') delimiter = *p, p++; + if(!*p) return false; + + // now p will be start of value + *value = p; + + // find delimiter or white space or ';' + if(delimiter == '\0') + { + while((!isspace(*p) && *p != ';') && *p) p++; + } + else + { + while((*p != delimiter) && *p) p++; + } + + // remember value last point + valuelast = p; + + // skip last delimiter + if(*p == delimiter) p++; + + // put null terminator + *namelast = '\0'; + *valuelast = '\0'; + + // finish + return true; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::ReadLinkInformation(char * & p, tTVPWaveLoopLink &link) +{ + // read link information from 'p'. + // p must point '{' , which indicates start of the block. + if(*p != '{') return false; + + p++; + if(!*p) return false; + + do + { + // get one token from 'p' + char * name; + char * value; + if(!GetEntityToken(p, &name, &value)) + return false; + + if(!strcasecmp(name, "From")) + { if(!GetInt64(value, link.From)) return false;} + else if(!strcasecmp(name, "To")) + { if(!GetInt64(value, link.To)) return false;} + else if(!strcasecmp(name, "Smooth")) + { if(!GetBool(value, link.Smooth)) return false;} + else if(!strcasecmp(name, "Condition")) + { if(!GetCondition(value, link.Condition)) return false;} + else if(!strcasecmp(name, "RefValue")) + { if(!GetInt(value, link.RefValue)) return false;} + else if(!strcasecmp(name, "CondVar")) + { if(!GetInt(value, link.CondVar)) return false;} + else + { return false;} + + // skip space + while(isspace(*p)) p++; + + // check ';'. note that this will also be a null, if no delimiters are used + if(*p != ';' && *p != '\0') return false; + p++; + if(!*p) return false; + + // skip space + while(isspace(*p)) p++; + if(!*p) return false; + + // check '}' + if(*p == '}') break; + } while(true); + + p++; + + return true; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::ReadLabelInformation(char * & p, tTVPWaveLabel &label) +{ + // read label information from 'p'. + // p must point '{' , which indicates start of the block. + if(*p != '{') return false; + + p++; + if(!*p) return false; + + do + { + // get one token from 'p' + char * name; + char * value; + if(!GetEntityToken(p, &name, &value)) + return false; + + if(!strcasecmp(name, "Position")) + { if(!GetInt64(value, label.Position)) return false;} + else if(!strcasecmp(name, "Name")) + { if(!GetString(value, label.Name)) return false;} + else + { return false;} + + // skip space + while(isspace(*p)) p++; + + // check ';'. note that this will also be a null, if no delimiters are used + if(*p != ';' && *p != '\0') return false; + p++; + if(!*p) return false; + + // skip space + while(isspace(*p)) p++; + if(!*p) return false; + + // check '}' + if(*p == '}') break; + } while(true); + + p++; + + return true; +} +//--------------------------------------------------------------------------- +bool tTVPWaveLoopManager::ReadInformation(char * p) +{ + // read information from 'p' + volatile tTJSCriticalSectionHolder CS(FlagsCS); + + char *p_org = p; + Links.clear(); + Labels.clear(); + + // check version + if(*p != '#') + { + // old sli format + char *p_length = strstr(p, "LoopLength="); + char *p_start = strstr(p, "LoopStart="); + if(!p_length || !p_start) return false; // read error + tTVPWaveLoopLink link; + link.Smooth = false; + link.Condition = llcNone; + link.RefValue = 0; + link.CondVar = 0; + tjs_int64 start; + tjs_int64 length; + if(!GetInt64(p_length + 11, length)) return false; + if(!GetInt64(p_start + 10, start )) return false; + link.From = start + length; + link.To = start; + Links.push_back(link); + } + else + { + // sli v2.0+ + if(strncmp(p, "#2.00", 5) > 0) + return false; // version mismatch + + while(true) + { + if((p == p_org || p[-1] == '\n') && *p == '#') + { + // line starts with '#' is a comment + // skip the comment + while(*p != '\n' && *p) p++; + if(!*p) break; + + p ++; + continue; + } + + // skip white space + while(isspace(*p)) p++; + if(!*p) break; + + // read id (Link or Label) + if(!strncasecmp(p, "Link", 4) && !isalpha(p[4])) + { + p += 4; + while(isspace(*p)) p++; + if(!*p) return false; + tTVPWaveLoopLink link; + if(!ReadLinkInformation(p, link)) return false; + Links.push_back(link); + } + else if(!strncasecmp(p, "Label", 5) && !isalpha(p[5])) + { + p += 5; + while(isspace(*p)) p++; + if(!*p) return false; + tTVPWaveLabel label; + if(!ReadLabelInformation(p, label)) return false; + Labels.push_back(label); + } + else + { + return false; // read error + } + + // skip white space + while(isspace(*p)) p++; + if(!*p) break; + } + } + + return true; // done +} +//--------------------------------------------------------------------------- +#ifdef TVP_IN_LOOP_TUNER +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::PutInt(AnsiString &s, tjs_int v) +{ + s += AnsiString((int)v); +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::PutInt64(AnsiString &s, tjs_int64 v) +{ + s += AnsiString((__int64)v); +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::PutBool(AnsiString &s, bool v) +{ + s += v ? "True" : "False"; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::PutCondition(AnsiString &s, tTVPWaveLoopLinkCondition v) +{ + switch(v) + { + case llcNone: s += "no" ; break; + case llcEqual: s += "eq" ; break; + case llcNotEqual: s += "ne" ; break; + case llcGreater: s += "gt" ; break; + case llcGreaterOrEqual: s += "ge" ; break; + case llcLesser: s += "lt" ; break; + case llcLesserOrEqual: s += "le" ; break; + } +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::PutString(AnsiString &s, tTVPLabelStringType v) +{ + // convert v to a utf-8 string + const tjs_char *pi; + +#ifdef TVP_IN_LOOP_TUNER + WideString wstr = v; + pi = wstr.c_bstr(); +#else + pi = v.c_str(); +#endif + + // count output bytes + int size = TVPWideCharToUtf8String(pi, NULL); + + char * out = new char [size + 1]; + try + { + // convert the string + TVPWideCharToUtf8String(pi, out); + out[size] = '\0'; + + // append the string with quotation + s += "\'" + AnsiString(out) + "\'"; + } + catch(...) + { + delete [] out; + throw; + } + delete [] out; +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::DoSpacing(AnsiString &l, int col) +{ + // fill space until the string becomes specified length + static const char * spaces16 = " "; + int length = l.Length(); + if(length < col) + { + int remain = col - length; + while(remain) + { + int one_size = remain > 16 ? 16 : remain; + l += ((16 - one_size) + spaces16); + remain -= one_size; + } + } +} +//--------------------------------------------------------------------------- +void tTVPWaveLoopManager::WriteInformation(AnsiString &s) +{ + // write current link/label information into s + volatile tTJSCriticalSectionHolder CS(FlagsCS); + + // write banner + s = "#2.00\n# Sound Loop Information (utf-8)\n" + "# Generated by WaveLoopManager.cpp\n"; + + // write links +/* +Link { From=0000000000000000; To=0000000000000000; Smooth=False; Condition=ne; RefValue=444444444; CondVar=99; } +*/ + for(std::vector::iterator i = Links.begin(); + i != Links.end(); i++) + { + AnsiString l; + l = "Link { "; + + l += "From="; + PutInt64(l, i->From); + l += ";"; + DoSpacing(l, 30); + + l += "To="; + PutInt64(l, i->To); + l += ";"; + DoSpacing(l, 51); + + l += "Smooth="; + PutBool(l, i->Smooth); + l += ";"; + DoSpacing(l, 65); + + l += "Condition="; + PutCondition(l, i->Condition); + l += ";"; + DoSpacing(l, 79); + + l += "RefValue="; + PutInt(l, i->RefValue); + l += ";"; + DoSpacing(l, 100); + + l += "CondVar="; + PutInt(l, i->CondVar); + l += ";"; + DoSpacing(l, 112); + + l += "}\n"; + s += l; + } + + + // write labels +/* +Label { Position=0000000000000000; name=" "; } +*/ + for(std::vector::iterator i = Labels.begin(); + i != Labels.end(); i++) + { + AnsiString l; + l = "Label { "; + + l += "Position="; + PutInt64(l, i->Position); + l += ";"; + DoSpacing(l, 35); + + l += "Name="; + PutString(l, i->Name); + l += "; "; + DoSpacing(l, 85); + + l += "}\n"; + s += l; + } + +} +//--------------------------------------------------------------------------- +#endif +//--------------------------------------------------------------------------- + + + + + diff --git a/tools/win32/krdevui/looptuner2/WaveLoopManager.h b/tools/win32/krdevui/looptuner2/WaveLoopManager.h new file mode 100644 index 0000000..43472b7 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveLoopManager.h @@ -0,0 +1,384 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +// Wave Loop Manager +//--------------------------------------------------------------------------- + +#ifndef WaveLoopManagerH +#define WaveLoopManagerH +//--------------------------------------------------------------------------- + +#include "tjsTypes.h" +#include +#include + +#define TVP_WL_MAX_FLAGS 16 + +#define TVP_WL_MAX_FLAG_VALUE 9999 + +#define TVP_WL_SMOOTH_TIME 50 +#define TVP_WL_SMOOTH_TIME_HALF (TVP_WL_SMOOTH_TIME/2) + +#define TVP_WL_MAX_ID_LEN 16 + +#ifdef TVP_IN_LOOP_TUNER + #include "WaveReader.h" +#endif + +//--------------------------------------------------------------------------- +#ifdef TVP_IN_LOOP_TUNER + typedef AnsiString tTVPLabelStringType; + typedef char tTVPLabelCharType; +#else + typedef ttstr tTVPLabelStringType; + typedef tjs_char tTVPLabelCharType; +#endif +//--------------------------------------------------------------------------- + + +#ifdef TVP_IN_LOOP_TUNER + //--------------------------------------------------------------------------- + // tTJSCriticalSection ( taken from tjsUtils.h ) + //--------------------------------------------------------------------------- + class tTJSCriticalSection + { + CRITICAL_SECTION CS; + public: + tTJSCriticalSection() { InitializeCriticalSection(&CS); } + ~tTJSCriticalSection() { DeleteCriticalSection(&CS); } + + void Enter() { EnterCriticalSection(&CS); } + void Leave() { LeaveCriticalSection(&CS); } + }; + //--------------------------------------------------------------------------- + // tTJSCriticalSectionHolder ( taken from tjsUtils.h ) + //--------------------------------------------------------------------------- + class tTJSCriticalSectionHolder + { + tTJSCriticalSection *Section; + public: + tTJSCriticalSectionHolder(tTJSCriticalSection &cs) + { + Section = &cs; + Section->Enter(); + } + + ~tTJSCriticalSectionHolder() + { + Section->Leave(); + } + }; +#else + #include "tjsUtils.h" +#endif +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +// tTVPWaveLoopLink : link structure +//--------------------------------------------------------------------------- +enum tTVPWaveLoopLinkCondition +{ + llcNone, + llcEqual, + llcNotEqual, + llcGreater, + llcGreaterOrEqual, + llcLesser, + llcLesserOrEqual +}; +//--------------------------------------------------------------------------- +struct tTVPWaveLoopLink +{ + tjs_int64 From; // 'From' in sample position + tjs_int64 To; // 'To' in sample position + bool Smooth; // Smooth transition (uses short 50ms crossfade) + tTVPWaveLoopLinkCondition Condition; // Condition + tjs_int RefValue; + tjs_int CondVar; // Condition variable index +#ifdef TVP_IN_LOOP_TUNER + // these are only used by the loop tuner + tjs_int FromTier; // display tier of vertical 'from' line + tjs_int LinkTier; // display tier of horizontal link + tjs_int ToTier; // display tier of vertical 'to' allow line + tjs_int Index; // link index + + struct tSortByDistanceFuncObj + { + bool operator()( + const tTVPWaveLoopLink &lhs, + const tTVPWaveLoopLink &rhs) const + { + tjs_int64 lhs_dist = lhs.From - lhs.To; + if(lhs_dist < 0) lhs_dist = -lhs_dist; + tjs_int64 rhs_dist = rhs.From - rhs.To; + if(rhs_dist < 0) rhs_dist = -rhs_dist; + return lhs_dist < rhs_dist; + } + }; + + struct tSortByIndexFuncObj + { + bool operator()( + const tTVPWaveLoopLink &lhs, + const tTVPWaveLoopLink &rhs) const + { + return lhs.Index < rhs.Index; + } + }; +#endif + + tTVPWaveLoopLink() + { + From = To = 0; + Smooth = false; + Condition = llcNone; + RefValue = CondVar = 0; + +#ifdef TVP_IN_LOOP_TUNER + FromTier = LinkTier = ToTier = 0; + Index = 0; +#endif + } +}; +//--------------------------------------------------------------------------- +bool inline operator < (const tTVPWaveLoopLink & lhs, const tTVPWaveLoopLink & rhs) +{ + if(lhs.From < rhs.From) return true; + if(lhs.From == rhs.From) + { + // give priority to conditional link + if(lhs.Condition != rhs.Condition) + return lhs.Condition > rhs.Condition; + // give priority to conditional expression + return lhs.CondVar > rhs.CondVar; + } + return false; +} +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +// tTVPWaveLabel : label structure +//--------------------------------------------------------------------------- +struct tTVPWaveLabel +{ + tjs_int64 Position; // label position + tTVPLabelStringType Name; // label name + tjs_int Offset; + /* + This member will be set in tTVPWaveLoopManager::Decode, + and will contain the sample granule offset from first decoding + point at call of tTVPWaveLoopManager::Decode(). + */ +#ifdef TVP_IN_LOOP_TUNER + // these are only used by the loop tuner + tjs_int NameWidth; // display name width + tjs_int Index; // index +#endif + + struct tSortByPositionFuncObj + { + bool operator()( + const tTVPWaveLabel &lhs, + const tTVPWaveLabel &rhs) const + { + return lhs.Position < rhs.Position; + } + }; + + struct tSortByOffsetFuncObj + { + bool operator()( + const tTVPWaveLabel &lhs, + const tTVPWaveLabel &rhs) const + { + return lhs.Offset < rhs.Offset; + } + }; + +#ifdef TVP_IN_LOOP_TUNER + struct tSortByIndexFuncObj + { + bool operator()( + const tTVPWaveLabel &lhs, + const tTVPWaveLabel &rhs) const + { + return lhs.Index < rhs.Index; + } + }; +#endif + + tTVPWaveLabel() + { + Position = 0; + Offset = 0; +#ifdef TVP_IN_LOOP_TUNER + NameWidth = 0; + Index = 0; +#endif + } +}; +//--------------------------------------------------------------------------- +bool inline operator < (const tTVPWaveLabel & lhs, const tTVPWaveLabel & rhs) +{ + return lhs.Position < rhs.Position; +} + +//--------------------------------------------------------------------------- +struct tTVPWaveLoopSegment +{ + tTVPWaveLoopSegment(tjs_int64 start, tjs_int64 length) + { Start = start; Length = length; } + tjs_int64 Start; + tjs_int64 Length; +}; +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// tTVPWaveLoopManager : wave loop manager +//--------------------------------------------------------------------------- +class tTVPWaveDecoder; +class tTVPWaveFormat; +class tTVPWaveLoopManager +{ + tTJSCriticalSection FlagsCS; // CS to protect flags/links/labels + int Flags[TVP_WL_MAX_FLAGS]; + bool FlagsModifiedByLabelExpression; // true if the flags are modified by EvalLabelExpression + std::vector Links; + std::vector Labels; + tTJSCriticalSection DataCS; // CS to protect other members + tTVPWaveFormat * Format; + tTVPWaveDecoder * Decoder; + + tjs_int ShortCrossFadeHalfSamples; + // TVP_WL_SMOOTH_TIME_HALF in sample unit + + bool Looping; + + tjs_int64 Position; // decoding position + + tjs_uint8 *CrossFadeSamples; // sample buffer for crossfading + tjs_int CrossFadeLen; + tjs_int CrossFadePosition; + + bool IsLinksSorted; // false if links are not yet sorted + bool IsLabelsSorted; // false if labels are not yet sorted + + bool IgnoreLinks; // decode the samples with ignoring links + +public: + tTVPWaveLoopManager(); + virtual ~tTVPWaveLoopManager(); + + void SetDecoder(tTVPWaveDecoder * decoder); + + int GetFlag(tjs_int index); + void CopyFlags(tjs_int *dest); + bool GetFlagsModifiedByLabelExpression(); + void SetFlag(tjs_int index, tjs_int f); + void ClearFlags(); + void ClearLinksAndLabels(); + + const std::vector & GetLinks() const; + const std::vector & GetLabels() const; + + void SetLinks(const std::vector & links); + void SetLabels(const std::vector & labels); + + bool GetIgnoreLinks() const; + void SetIgnoreLinks(bool b); + + tjs_int64 GetPosition() const; + void SetPosition(tjs_int64 pos); + + bool GetLooping() const { return Looping; } + void SetLooping(bool b) { Looping = b; } + + void Decode(void *dest, tjs_uint samples, tjs_uint &written, + std::vector &segments, + std::vector &labels); + + const tTVPWaveFormat & GetFormat() const { return *Format; } + +private: + bool GetNearestEvent(tjs_int64 current, + tTVPWaveLoopLink & link, bool ignore_conditions); + + void GetLabelAt(tjs_int64 from, tjs_int64 to, + std::vector & labels); + + void DoCrossFade(void *dest, void *src1, void *src2, tjs_int samples, + tjs_int ratiostart, tjs_int ratioend); + + void ClearCrossFadeInformation(); + +//--- flag manupulation by label expression + enum tExpressionToken { + etUnknown, + etEOE, // End of the expression + etLBracket, // '[' + etRBracket, // ']' + etInteger, // integer number + etEqual, // '=' + etPlus, // '+' + etMinus, // '-' + etPlusEqual, // '+=' + etMinusEqual, // '-=' + etIncrement, // '++' + etDecrement // '--' + }; +public: + static bool GetLabelExpression(const tTVPLabelStringType &label, + tExpressionToken * ope = NULL, + tjs_int *lv = NULL, + tjs_int *rv = NULL, bool *is_rv_indirect = NULL); +private: + bool EvalLabelExpression(const tTVPLabelStringType &label); + + static tExpressionToken GetExpressionToken(const tTVPLabelCharType * & p , tjs_int * value); + static bool GetLabelCharInt(const tTVPLabelCharType *s, tjs_int &v); + + +//--- loop information input/output stuff +private: + static bool GetInt(char *s, tjs_int &v); + static bool GetInt64(char *s, tjs_int64 &v); + static bool GetBool(char *s, bool &v); + static bool GetCondition(char *s, tTVPWaveLoopLinkCondition &v); + static bool GetString(char *s, tTVPLabelStringType &v); + + static bool GetEntityToken(char * & p, char **name, char **value); + + static bool ReadLinkInformation(char * & p, tTVPWaveLoopLink &link); + static bool ReadLabelInformation(char * & p, tTVPWaveLabel &label); +public: + bool ReadInformation(char * p); + +#ifdef TVP_IN_LOOP_TUNER + // output facility (currently only available with VCL interface) +private: + static void PutInt(AnsiString &s, tjs_int v); + static void PutInt64(AnsiString &s, tjs_int64 v); + static void PutBool(AnsiString &s, bool v); + static void PutCondition(AnsiString &s, tTVPWaveLoopLinkCondition v); + static void PutString(AnsiString &s, tTVPLabelStringType v); + static void DoSpacing(AnsiString &l, int col); +public: + void WriteInformation(AnsiString &s); +#endif + + +public: +}; +//--------------------------------------------------------------------------- +#endif + + diff --git a/tools/win32/krdevui/looptuner2/WaveReader.cpp b/tools/win32/krdevui/looptuner2/WaveReader.cpp new file mode 100644 index 0000000..fbe5fb5 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveReader.cpp @@ -0,0 +1,637 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include +#include "WaveReader.h" +#include "TSSWaveContext.h" +#include "RIFFWaveContext.h" + +#include "tvpsnd.h" + +//--------------------------------------------------------------------------- +class TWaveReaderThread : public TThread +{ + TWaveReader * FOwner; +public: + __fastcall TWaveReaderThread(TWaveReader *owner) : TThread(true) + { + FOwner = owner; + Suspended = false; + } + + __fastcall ~TWaveReaderThread(void) + { + Suspended = false; + Terminate(); + WaitFor(); + } + + void __fastcall SyncMethod(void) + { + if(FOwner->FOnReadProgress) + { + FOwner->FOnReadProgress(NULL); + } + } + + void __fastcall Execute(void) + { + Sleep(100); // sleep a while; this will arrow other threads to do unprocessed events. + DWORD tickstart = GetTickCount(); + while(!Terminated) + { + if(!FOwner->ReadBlock()) + { + Synchronize(SyncMethod); + Terminate(); + } + else if(GetTickCount() - tickstart >= 100) + { + Synchronize(SyncMethod); + tickstart = GetTickCount(); + } + } + Synchronize(SyncMethod); + } +} ; +//--------------------------------------------------------------------------- +static void FindPlugins(AnsiString path, AnsiString ext, TStringList *dest) +{ + TSearchRec sr; + int done; + done = FindFirst(path + "*." + ext, + faReadOnly | faHidden | faSysFile | faArchive, sr); + if(!done) + { + do + { + // 試しに DLL をロードしてみる + AnsiString filename = path + sr.FindData.cFileName; + HMODULE dll = LoadLibrary(filename.c_str()); + if(dll) + { + // 必要な関数を持っているか + if(GetProcAddress(dll, "GetModuleInstance")) + { + dest->Add(filename); + } + FreeLibrary(dll); + } + + done = FindNext(sr); + } while(!done); + FindClose(sr); + } +} +//--------------------------------------------------------------------------- +TWaveReader::TWaveReader() +{ + FReadDone = false; + FPrevRange = 0; + FNumSamples = 0; + FSamplesRead = 0; + + ZeroMemory(&Format, sizeof(Format)); + + FPeaks = NULL; + FTmpStream = NULL; + FInputContext = NULL; + FReaderThread = NULL; + FOnReadProgress = NULL; + FMappingFile = NULL; + FData = NULL; + FMapping = NULL; + + FPlugins = NULL; + FFilterString = NULL; + + FDecodePoint = NULL; + + FTmpFileName = ExtractFileDir(ParamStr(0)) + "\\temp.dat"; + FPlugins = new TStringList(); + + // 使用可能なプラグインを検索する + AnsiString exepath = ExtractFilePath(ParamStr(0)); + FindPlugins(exepath + "plugin\\", "dll", FPlugins); + FindPlugins(exepath+ "plugin\\", "tpm", FPlugins); + FindPlugins(exepath + "..\\plugin\\", "dll", FPlugins); + FindPlugins(exepath + "..\\plugin\\", "tpm", FPlugins); + + + // 使用可能な拡張子とそのファイルタイプを取得する + + TStringList *exts = new TStringList; + TStringList *descs = new TStringList; + typedef HRESULT _stdcall (*GetModuleInstanceProc)(ITSSModule **out, + ITSSStorageProvider *provider, IStream * config, HWND mainwin); + + try + { + exts->Add(".wav"); + descs->Add("Wave ファイル"); + + for(int i = 0; i < FPlugins->Count; i++) + { + HMODULE lib = LoadLibrary(FPlugins->Strings[i].c_str()); + if(lib) + { + ITSSModule * mod; + GetModuleInstanceProc proc = (GetModuleInstanceProc) + GetProcAddress(lib, "GetModuleInstance"); + if(proc) + { + HRESULT hr = + proc(&mod, &StorageProvider, NULL, + Application->Handle); + if(SUCCEEDED(hr)) + { + int idx = 0; + for(;;) + { + wchar_t shortname[33]; + wchar_t ext[256]; + hr = mod->GetSupportExts(idx, shortname, + ext, 256); + if(hr != S_OK) break; + if(wcslen(ext) >= 1) + { + exts->Add(ext); + descs->Add(shortname); + } + idx++; + } + mod->Release(); + } + } + else + { + MessageDlg(AnsiString("このプラグインは扱えません : ") + + FPlugins->Strings[i].c_str(), mtWarning, TMsgDlgButtons() << mbOK , 0); + } + FreeLibrary(lib); + } + } + } + catch(Exception &e) + { + delete exts; + delete descs; + throw Exception(e); + } + + AnsiString ret; + ret = "すべての形式 ("; + int i; + for(i=0; iCount; i++) + { + if(i) ret+=";"; + ret+= "*" + exts->Strings[i]; + } + ret += ")|"; + for(i=0; iCount; i++) + { + if(i) ret+=";"; + ret+= "*" + exts->Strings[i]; + } + + for(i=0; iCount; i++) + { + ret+="|"; + ret+= descs->Strings[i]; + ret+= " (*"+ exts->Strings[i] +")|"; + ret+= "*" + exts->Strings[i]; + } + + ret+="|すべてのファイル (*.*)|*.*"; + + FFilterString = ret; +} +//--------------------------------------------------------------------------- +TWaveReader::~TWaveReader() +{ + Clear(); + DeleteFile(FTmpFileName); + delete FPlugins; +} +//--------------------------------------------------------------------------- +void TWaveReader::Clear() +{ + if(FReaderThread) delete FReaderThread, FReaderThread = NULL; + if(FPeaks) SysFreeMem(FPeaks), FPeaks = NULL; + if(FData) UnmapViewOfFile(FData), FData = NULL; + if(FMapping) CloseHandle(FMapping), FMapping = NULL; + if(FMappingFile) CloseHandle(FMappingFile), FMappingFile = NULL; + if(FTmpStream) delete FTmpStream, FTmpStream = NULL; + if(FInputContext) delete FInputContext, FInputContext = NULL; + FReadDone = false; + FNumSamples = 0; + FSamplesRead = 0; + FPrevRange = 0; +} +//--------------------------------------------------------------------------- +bool TWaveReader::ReadBlock() +{ + if(FReadDone) return false; + __int16 *buf = new __int16[32768 * Format.Format.nChannels]; + int written = FInputContext->Read(buf, 32768); + FSamplesRead += written; + FTmpStream->Write(buf, written * Format.Format.nChannels * sizeof(__int16)); + delete [] buf; + if(written==0) + { + // 読み込み終わり + Map(); + FReadDone = true; + } + + return written!=0; +} +//--------------------------------------------------------------------------- +void TWaveReader::Map() +{ + if(!FData) + { + if(FTmpStream) delete FTmpStream , FTmpStream = NULL; + + FNumSamples = FSamplesRead; + + FMappingFile = + CreateFile(FTmpFileName.c_str(), + GENERIC_READ, + FILE_SHARE_READ, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if(!FMappingFile) + { + return; + } + + FNumSamples = GetFileSize(FMappingFile, NULL) / (Format.Format.nChannels*2); + + FMapping = + CreateFileMapping(FMappingFile, + NULL, + PAGE_READONLY, + 0, + 0, + ("WaveReadMapping"+AnsiString(GetTickCount())).c_str()); + + if(!FMapping) + { + CloseHandle(FMappingFile), FMappingFile = NULL; + return; + } + + FData = (__int16 *)MapViewOfFile(FMapping, FILE_MAP_READ, 0, 0, 0); + + // ピークを探す + #define PEAK_RANGE 128 + + if(FPeaks) SysFreeMem(FPeaks); // ピークキャッシュ + + int alloc; + alloc = (FNumSamples / PEAK_RANGE + 2) * sizeof(__int16)*2 * Format.Format.nChannels; + FPeaks = (__int16*) + SysGetMem(alloc); + + alloc /=2; + + int pos; + int idx = 0; + for(pos=0; pos= FNumSamples) i = FNumSamples-1; + if(lim >= FNumSamples) lim = FNumSamples; + high = low = FData[i*Format.Format.nChannels + channel]; + i++; + while(i n) low = n; + if(high < n) high = n; + i++; + } + FPeaks[idx++] = low; + FPeaks[idx++] = high; + if(idx > alloc) + { + return; + } + } + } + } +} +//--------------------------------------------------------------------------- +void TWaveReader::LoadWave(AnsiString filename) +{ + Clear(); + + FTmpStream = new TFileStream(FTmpFileName, fmCreate|fmShareDenyWrite); + + // 使用可能なのを探す + + // 標準 RIFF wave reader で試す + bool res; + FInputContext = new TRIFFWaveContext(); + try + { + res = FInputContext->Start(filename); + } + catch(...) + { + res = false; + } + + if(!res) + { + delete FInputContext; + FInputContext = NULL; + + // プラグインから読み込み可能なモノを探す + for(int i = 0; i < FPlugins->Count; i++) + { + FInputContext = new TTSSWaveContext(FPlugins->Strings[i]); + + try + { + res = FInputContext->Start(filename); + } + catch(...) + { + res = false; + } + if(res) break; + delete FInputContext, FInputContext = NULL; + } + } + + if(!FInputContext) + { + delete FTmpStream; + FTmpStream = NULL; + throw Exception(filename + " : この形式のファイルは読み込めないか、ファイルが異常です"); + } + + FNumSamples = FInputContext->TotalSamples; + if(FNumSamples >= (0x80000000ul/8)) + { + throw Exception(filename + " は 大きすぎるため、扱うことができません"); + } + + // Format に格納 + // 16bit への変換はinputcontextが行うため、Format には 16bit を指定する + DWORD speakerconfig = FInputContext->SpeakerConfig; + int channels = FInputContext->Channels; + int frequency = FInputContext->Frequency; + + Format.Format.nChannels = channels; + Format.Format.nSamplesPerSec = frequency; + Format.Format.wBitsPerSample = 16; + Format.SubFormat = __KSDATAFORMAT_SUBTYPE_PCM; + Format.Samples.wValidBitsPerSample = 16; + + if(speakerconfig == 0 && channels <= 2) + { + // 普通の WAVE_FORMAT_PCM + Format.Format.wFormatTag = WAVE_FORMAT_PCM; + Format.Format.cbSize = 0; + } + else if(speakerconfig == 0) + { + // channels が 4 あるいは 6 の場合 + if(channels == 4) + { + // 左前、右前、左後、右後であると仮定する + Format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + Format.dwChannelMask = + SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_BACK_LEFT | + SPEAKER_BACK_RIGHT; + Format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + } + else if(channels == 6) + { + // 5.1 チャンネル用データであると仮定する + Format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + Format.dwChannelMask = KSAUDIO_SPEAKER_5POINT1; + Format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + } + else + { + throw Exception(filename + " : 対応できないチャンネル数です"); + } + } + else + { + // speakerconfig がある + Format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + Format.dwChannelMask = speakerconfig; + Format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); + } + + Format.Format.nBlockAlign = + Format.Format.wBitsPerSample * Format.Format.nChannels / 8; + Format.Format.nAvgBytesPerSec = + Format.Format.nSamplesPerSec * Format.Format.nBlockAlign; + + FReaderThread = new TWaveReaderThread(this); + + // この関数は読み込みの終了を待たずに戻ります +} +//--------------------------------------------------------------------------- +void TWaveReader::GetPeak(int &high, int &low, int pos, int channel, int range) +{ + if(!FReadDone) return; + + if(range < PEAK_RANGE) + { + int i; + i = pos; + int lim = i + range; + if(lim >= FNumSamples) lim = FNumSamples; + high = low = FData[i * Format.Format.nChannels + channel]; + i++; + while(i n) low = n; + if(high < n) high = n; + i++; + } + } + else + { + + int i; + i = pos / PEAK_RANGE; + int lim = i + range / PEAK_RANGE; + if(i >= FNumSamples / PEAK_RANGE) i = FNumSamples / PEAK_RANGE -1; + if(lim >= FNumSamples / PEAK_RANGE) lim = FNumSamples / PEAK_RANGE -1; + low = FPeaks[i*Format.Format.nChannels*2 + channel*2]; + high = FPeaks[i*Format.Format.nChannels*2 + channel*2 + 1]; + i++; + while(i nlow) low = nlow; + if(high < nhigh) high = nhigh; + i++; + } + } +} +//--------------------------------------------------------------------------- +int TWaveReader::GetSampleAt(int pos, int channel) +{ + if(pos < 0) return 0; + if(pos >= FNumSamples) return 0; // out of the range + if(channel < 0) return 0; + if(channel >= Format.Format.nChannels) return 0; + return FData[pos * Format.Format.nChannels + channel]; +} +//--------------------------------------------------------------------------- +int TWaveReader::GetData(__int16 *buf, int ofs, int num) +{ + if(!FReadDone) return 0; + + if(ofs >= FNumSamples) return 0; + if(ofs + num >= FNumSamples) num = FNumSamples - ofs; + if(num <=0 ) return 0; + + memcpy(buf, FData + ofs * Format.Format.nChannels, num * Format.Format.nChannels * sizeof(__int16)); + + return num; +} +//--------------------------------------------------------------------------- +int TWaveReader::SamplePosToTime(DWORD samplepos) +{ + if(!FReadDone) return -1; + + return (int)((__int64)samplepos*1000L / (__int64)Format.Format.nSamplesPerSec); +} +//--------------------------------------------------------------------------- +AnsiString TWaveReader::GetChannelLabel(int ch) +{ + static AnsiString chlabels[] = + {"FL", "FR", "FC", "LF", "BL", "BR", "FLC", "FRC", "BC", "SL", "SR", "TC", + "TFL", "TFC", "TFR", "TBL", "TBC", "TBR"}; + + if(Format.Format.wFormatTag == WAVE_FORMAT_PCM) + { + if(Format.Format.nChannels == 1) + { + if(ch == 0) return "Mono"; + } + else if(Format.Format.nChannels == 2) + { + if(ch == 0) return "L"; + else if(ch == 1) return "R"; + } + } + else if(Format.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) + { + DWORD mask = Format.dwChannelMask; + DWORD m = 1; + int index = 0; + int nmasks = 0; + int count = ch; + if(!(mask & 0x80000000)) + { + while(m) + { + if(mask & m) + { + if(count == 0) + { + if(index >= sizeof(chlabels) / sizeof(chlabels[0])) break; + return chlabels[index]; + } + count --; + nmasks ++; + } + m <<= 1; + index ++; + } + } + return AnsiString(ch - count); + } + + return "-"; +} +//--------------------------------------------------------------------------- +void TWaveReader::GetFormat(tTVPWaveFormat & format) +{ + format.SamplesPerSec = Format.Format.nSamplesPerSec; + format.Channels = Format.Format.nChannels; + format.BitsPerSample = Format.Samples.wValidBitsPerSample; + format.BytesPerSample = Format.Format.wBitsPerSample / 8; + format.TotalSamples = FNumSamples; + format.TotalTime = SamplePosToTime(FNumSamples); + format.SpeakerConfig = Format.dwChannelMask; + format.IsFloat = false; // always 16bit integer + format.Seekable = true; +} +//--------------------------------------------------------------------------- +bool TWaveReader::Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered) +{ + // write bufsamplelen samples to buf from current FDecodePoint + if(FDecodePoint >= FNumSamples) + { + // already finished + rendered = 0; + return false; + } + + tjs_uint remain = FNumSamples - FDecodePoint; + rendered = bufsamplelen < remain ? bufsamplelen : remain; + memcpy(buf, FData + FDecodePoint * Format.Format.nChannels, + sizeof(FData[0]) * Format.Format.nChannels * rendered); + FDecodePoint += rendered; + return FDecodePoint < FNumSamples; +} +//--------------------------------------------------------------------------- +bool TWaveReader::SetPosition(tjs_uint64 samplepos) +{ + // set FDecodePoint + if(samplepos >= 0x80000000ui64) return false; + if(samplepos >= FNumSamples) return false; + FDecodePoint = (int) samplepos; + return true; +} +//--------------------------------------------------------------------------- +AnsiString TWaveReader::SamplePosToTimeString(int pos) +{ + // returns HH:MM:SS.nnn string + int t = SamplePosToTime(pos); + + AnsiString ret; + + ret.sprintf("%02d:%02d:%02d.%03d", + t / (1000 * 60 * 60), + t / (1000 * 60) % 60, + t / 1000 % 60, + t % 1000); + + return ret; +} +//--------------------------------------------------------------------------- + +#pragma package(smart_init) diff --git a/tools/win32/krdevui/looptuner2/WaveReader.h b/tools/win32/krdevui/looptuner2/WaveReader.h new file mode 100644 index 0000000..6770ff2 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveReader.h @@ -0,0 +1,155 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef WaveReaderUnitH +#define WaveReaderUnitH + +#include "tjsTypes.h" +#include "WaveContext.h" +#include +#include +#include +#include + + +//--------------------------------------------------------------------------- +// PCM data format (internal use) +//--------------------------------------------------------------------------- +struct tTVPWaveFormat +{ + tjs_uint SamplesPerSec; // sample granule per sec + tjs_uint Channels; + tjs_uint BitsPerSample; // per one sample + tjs_uint BytesPerSample; // per one sample + tjs_uint64 TotalSamples; // in sample granule; unknown for zero + tjs_uint64 TotalTime; // in ms; unknown for zero + tjs_uint32 SpeakerConfig; // bitwise OR of SPEAKER_* constants + bool IsFloat; // true if the data is IEEE floating point + bool Seekable; +}; +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// tTVPWaveDecoder interface +//--------------------------------------------------------------------------- +class tTVPWaveDecoder +{ +public: + virtual ~tTVPWaveDecoder() {}; + + virtual void GetFormat(tTVPWaveFormat & format) = 0; + /* Retrieve PCM format, etc. */ + + virtual bool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered) = 0; + /* + Render PCM from current position. + where "buf" is a destination buffer, "bufsamplelen" is the buffer's + length in sample granule, "rendered" is to be an actual number of + written sample granule. + returns whether the decoding is to be continued. + because "redered" can be lesser than "bufsamplelen", the player + should not end until the returned value becomes false. + */ + + virtual bool SetPosition(tjs_uint64 samplepos) = 0; + /* + Seek to "samplepos". "samplepos" must be given in unit of sample granule. + returns whether the seeking is succeeded. + */ +}; +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +class TWaveReader : public tTVPWaveDecoder +{ + friend class TWaveReaderThread; + +public: + TWaveReader(); + ~TWaveReader(); + +private: + bool FReadDone; + int FPrevRange; + + int FNumSamples; + int FSamplesRead; + + WAVEFORMATEXTENSIBLE Format; + + int GetChannels() { return Format.Format.nChannels; } + int GetNumSamples(void) {return FNumSamples;} + int GetFrequency(void) {return Format.Format.nSamplesPerSec; } + int GetBitsPerSample(void) {return Format.Format.wBitsPerSample; } + + __int16 *FPeaks; + TStream *FTmpStream; + AnsiString FTmpFileName; + TCustomWaveContext *FInputContext; + TWaveReaderThread * FReaderThread; + TNotifyEvent FOnReadProgress; + HANDLE FMappingFile; + __int16 *FData; + HANDLE FMapping; + + TStringList *FPlugins; + AnsiString FFilterString; + + bool ReadBlock(); + + void Map(); + +protected: + +public: + void Clear(); + void LoadWave(AnsiString filename); + + void GetPeak(int &high, int &low, int pos, int channel, int range); + + int GetSampleAt(int pos, int channel); + + int GetData(__int16 *buf, int ofs, int num); + + int SamplePosToTime(DWORD samplepos); + + __property TNotifyEvent OnReadProgress={read=FOnReadProgress, write=FOnReadProgress}; + + const WAVEFORMATEXTENSIBLE * GetWindowsFormat() const { return &Format; } + + AnsiString GetChannelLabel(int ch); + + __property bool ReadDone = {read=FReadDone}; + __property int NumSamples = {read=FNumSamples}; + __property int SamplesRead = {read=FSamplesRead}; + __property int Channels = {read=GetChannels}; + __property int Frequency = {read=GetFrequency}; + __property int BitsPerSample = {read=GetBitsPerSample}; + + __property AnsiString FilterString = {read=FFilterString}; + +public: + // tTVPWaveDecoder stuff + int FDecodePoint; + void GetFormat(tTVPWaveFormat & format); + bool Render(void *buf, tjs_uint bufsamplelen, tjs_uint& rendered); + bool SetPosition(tjs_uint64 samplepos); + + AnsiString SamplePosToTimeString(int pos); // returns HH:MM:SS.nnn string +}; +//--------------------------------------------------------------------------- + + +#endif diff --git a/tools/win32/krdevui/looptuner2/WaveView.cpp b/tools/win32/krdevui/looptuner2/WaveView.cpp new file mode 100644 index 0000000..ec97d26 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveView.cpp @@ -0,0 +1,3183 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include +#include +#include "WaveView.h" +#include "WaveReader.h" +#include "ColorScheme.h" + +//--------------------------------------------------------------------------- +// constants +//--------------------------------------------------------------------------- +const AnsiString C_NEW_LABEL_BASE_NAME = "ラベル"; +const AnsiString C_LINK_HINT = + "リンク元: %s\n" // link from + "リンク先: %s\n" // link to + "距離 : %s\n" // distance + "条件 : %s" // condition + ; +const AnsiString C_LINK_COND_CODES[] = { + "条件無し", + "%d 番のフラグが %d と同じとき", + "%d 番のフラグが %d でないとき", + "%d 番のフラグが %d より大きいとき", + "%d 番のフラグが %d 以上のとき", + "%d 番のフラグが %d より小さいとき", + "%d 番のフラグが %d 以下のとき" +}; +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- +const int LinkArrowSize = 4; +const int LinkDirectionArrowWidth = 10; +const int LinkDirectionInterval = 200; +//--------------------------------------------------------------------------- +const int MaxUndoLevel = 20; +const int MaxMagnify = 3; +const int MinMagnify = -16; +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// TWaveView +//--------------------------------------------------------------------------- +__fastcall TWaveView::TWaveView(Classes::TComponent* AOwner) : + TCustomControl(AOwner) +{ + FBlinkTimer = new TTimer(this); + FBlinkTimer->OnTimer = OnBlinkTimer; + FBlinkTimer->Interval = GetCaretBlinkTime(); + FBlinkTimer->Enabled = true; + + DragScrollTimer = new TTimer(this); + DragScrollTimer->OnTimer = OnDragScrollTimer; + DragScrollTimer->Interval = 100; + DragScrollTimer->Enabled = false; + + ClearAll(); +} +//--------------------------------------------------------------------------- +__fastcall TWaveView::~TWaveView() +{ + delete DragScrollTimer; + delete FBlinkTimer; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::ClearAll() +{ + Color = C_CLIENT; + + FReader = NULL; + FMagnify = -12; + FStart = 0; + + FDoubleBufferEnabled = true; + FFollowingMarker = true; + FWaitingMarker = true; + FSoftCenteringStartTick = 0; + FSoftCenteringPos = 0; + FOnStopFollowingMarker = NULL; + FOnRangeChanged = NULL; + FOnMarkerStateChanged = NULL; + + FCaretPos = 0; + FShowCaret = false; + FCaretVisiblePhase = true; + FOnCaretStateChanged = NULL; + + FMinRulerMajorWidth = 0; + FMinRulerMajorHeight = 0; + FRulerUnit = 0; + FShowRuler = true; + FMarkerPos = -1; + Canvas->Font->Height = -12; + + FOnNotifyPopup = NULL; + FOnShowCaret = NULL; + FOnLinkSelected = NULL; + FOnLabelSelected = NULL; + FOnSelectionLost = NULL; + FOnLinkModified = NULL; + FInOnLinkModified = false; // to prevent re-entrering + FOnLabelModified = NULL; + FInOnLabelModified = false; // to prevent re-entrering + + FUndoStack.clear(); + FUndoLevel = 0; + + Links.clear(); + FShowLinks = true; + FLinkTierCount = 0; + FHoveredLink = -1; // -1 for not hovered + FFocusedLink = -1; // -1 for not focused + NotifyLinkChanged(); + + Labels.clear(); + FShowLabels = true; + FHoveredLabel = -1; // -1 for not hovered + FFocusedLabel = -1; // -1 for not focused + LabelTextHeight = -1; + NotifyLabelChanged(); + + FOnWaveDoubleClick = NULL; + FOnLinkDoubleClick = NULL; + FOnLabelDoubleClick = NULL; + + LastMouseDownX = -1; + LastMouseDownY = -1; + LastMouseDownPosOffset = 0; + LastMouseMoveX = -1; + PopupType = ""; + DraggingState = dsNone; + DisableNextMouseDown = false; + + LastClickedPos[0] = LastClickedPos[1] = 0; + + Cursor = crIBeam; + + ShowHint = true; + + FModified = false; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::Paint(void) +{ + DWORD start = GetTickCount(); + + DrawWave(FStart, true); + DrawLinks(); + DrawLabels(); + DrawCaret(); + + DWORD end = GetTickCount(); + if(FDoubleBufferEnabled && end - start > 100) + { + // too heavy to double buffering + // disable double buffering + FDoubleBufferEnabled = false; + DoubleBuffered = false; + } +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::PixelToSample(int pixel) +{ + if(FMagnify <= 0) + { + // shrink + return pixel << (-FMagnify); + } + else + { + // expand + return pixel >> FMagnify; + } +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::SampleToPixel(int sample) +{ + if(FMagnify <= 0) + { + // shrink + return sample >> (-FMagnify); + } + else + { + // expand + return sample << FMagnify; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetReader(TWaveReader * reader) +{ + // set wave reader + FReader = reader; + Invalidate(); + + SetScrollBarRange(); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::ResetAll() +{ + FReader = NULL; + FUndoStack.clear(); + FMagnify = -12; + FStart = 0; + FHoveredLink = -1; // -1 for not hovered + FFocusedLink = -1; // -1 for not focused + FHoveredLabel = -1; // -1 for not hovered + FFocusedLabel = -1; // -1 for not focused + SetScrollBarRange(); + Invalidate(); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::EraseRedo() +{ + // erase redo data + if(CanRedo()) + { + FUndoStack.erase(FUndoStack.begin() + FUndoLevel + 1, FUndoStack.end()); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::PushUndo() +{ + // erase redo + EraseRedo(); + + // remove old data + if(FUndoStack.size() == (MaxUndoLevel+1)) + { + FUndoStack.pop_front(); + FUndoLevel --; + } + + // append new data + tHistoryInfo info; + info.Links = Links; + info.Labels = Labels; + FUndoStack.push_back(info); + FUndoLevel ++; + + // set modified flag + FModified = true; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::PushFirstUndoState() +{ + FUndoStack.clear(); + PushUndo(); + FUndoLevel = 0; + FModified = false; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::Undo() +{ + // do undo + if(CanUndo()) + { + int linknum = FFocusedLink; + int labelnum = FFocusedLabel; + FocusedLink = -1; + FocusedLabel = -1; + HoveredLink = -1; + HoveredLabel = -1; + + if(CanUndo()) + { + FUndoLevel --; + Links = FUndoStack[FUndoLevel].Links; + Labels = FUndoStack[FUndoLevel].Labels; + } + + if((int)Links.size() <= linknum) linknum = Links.size() - 1; + FocusedLink = linknum; + if((int)Labels.size() <= labelnum) labelnum = Labels.size() - 1; + FocusedLabel = labelnum; + + NotifyLinkChanged(); + NotifyLabelChanged(); + DoubleBuffered = FDoubleBufferEnabled; + Invalidate(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::Redo() +{ + if(CanRedo()) + { + int linknum = FFocusedLink; + int labelnum = FFocusedLabel; + FocusedLink = -1; + FocusedLabel = -1; + HoveredLink = -1; + HoveredLabel = -1; + + if(CanRedo()) + { + FUndoLevel ++; + Links = FUndoStack[FUndoLevel].Links; + Labels = FUndoStack[FUndoLevel].Labels; + } + + if((int)Links.size() <= linknum) linknum = Links.size() - 1; + FocusedLink = linknum; + if((int)Labels.size() <= labelnum) labelnum = Labels.size() - 1; + FocusedLabel = labelnum; + + NotifyLinkChanged(); + NotifyLabelChanged(); + DoubleBuffered = FDoubleBufferEnabled; + Invalidate(); + } +} +//--------------------------------------------------------------------------- +bool __fastcall TWaveView::CanUndo() const +{ + return FUndoLevel != 0; +} +//--------------------------------------------------------------------------- +bool __fastcall TWaveView::CanRedo() const +{ + return FUndoStack.size() - FUndoLevel > 1; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DeleteItem() +{ + // delete current focused item + if(FFocusedLink != -1) + { + int num = FocusedLink; + FocusedLink = -1; + HoveredLink = -1; + Links.erase(Links.begin() + num); + NotifyLinkChanged(); + DoubleBuffered = FDoubleBufferEnabled; + Invalidate(); + PushUndo(); //==== push undo + } + else if(FFocusedLabel != -1) + { + int num = FocusedLabel; + FocusedLabel = -1; + HoveredLabel = -1; +// InvalidateLabel(num); + Labels.erase(Labels.begin() + num); + NotifyLabelChanged(); + DoubleBuffered = false; + Invalidate(); + PushUndo(); //==== push undo + } +} +//--------------------------------------------------------------------------- +bool __fastcall TWaveView::CanDeleteItem() const +{ + return FFocusedLink != -1 || FFocusedLabel != -1; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::ClearAllLabels() +{ + // delete all labels + FocusedLabel = -1; + HoveredLabel = -1; + Labels.clear(); + NotifyLabelChanged(); + DoubleBuffered = false; + Invalidate(); + PushUndo(); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::CreateParams(TCreateParams ¶ms) +{ + TCustomControl::CreateParams(params); + params.Style |= WS_HSCROLL; // create horizontal scroll bar +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::Resize() +{ + SetScrollBarRange(); + TCustomControl::Resize(); + + SCROLLINFO si; + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(Handle, SB_HORZ, &si); + + FDoubleBufferEnabled = true; + DoubleBuffered = FDoubleBufferEnabled; + + SetStart(si.nPos); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetScrollBarRange() +{ + if(!FReader || !FReader->ReadDone) + { + SCROLLINFO si; + si.cbSize = sizeof(si); + si.fMask = SIF_DISABLENOSCROLL; + SetScrollInfo(Handle, SB_HORZ, &si, true); + EnableScrollBar(Handle, SB_HORZ, ESB_DISABLE_BOTH); + return; + } + + SCROLLINFO si; + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE/* | SIF_DISABLENOSCROLL*/; + si.nMin = 0; + si.nMax = FReader->NumSamples; + si.nPage = PixelToSample(ClientWidth); + + SetScrollInfo(Handle, SB_HORZ, &si, true); + + EnableScrollBar(Handle, SB_HORZ, ESB_ENABLE_BOTH); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetView(int n, int r) +{ + // set left edge of the viewport + int clwp = PixelToSample(ClientWidth); + clwp = clwp / 100 * r; + n -= clwp; + if(n < 0) n = 0; + + SCROLLINFO si; + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_POS; + si.nPos = n; + SetScrollInfo(Handle, SB_HORZ, &si, true); + + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(Handle, SB_HORZ, &si); + + SetStart(si.nPos); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::WMHScroll(TWMHScroll &msg) +{ + SCROLLINFO si; + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(Handle, SB_HORZ, &si); + + if(msg.ScrollCode == SB_THUMBTRACK) + { + si.nPos = si.nTrackPos; + } + else if(msg.ScrollCode == SB_LINELEFT) + { + si.nPos = si.nPos - PixelToSample(ClientWidth)/20; + if(si.nPos<0) si.nPos=0; + } + else if(msg.ScrollCode == SB_LINERIGHT) + { + si.nPos = si.nPos + PixelToSample(ClientWidth)/20; + if((int)(si.nPos) >= (int)(si.nMax - si.nPage)) si.nPos=si.nMax- si.nPage; + } + else if(msg.ScrollCode == SB_PAGELEFT) + { + si.nPos = si.nPos - si.nPage; + if(si.nPos<0) si.nPos=0; + } + else if(msg.ScrollCode == SB_PAGERIGHT) + { + si.nPos = si.nPos + si.nPage; + if(si.nPos >=si.nMax) si.nPos=si.nMax-1; + } + + si.fMask = SIF_POS; + SetScrollInfo(Handle, SB_HORZ, &si, true); + + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(Handle, SB_HORZ, &si); + + SetStart(si.nPos); + + if(FOnStopFollowingMarker) FOnStopFollowingMarker(this); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::WMSetFocus(TWMSetFocus &msg) +{ + ::SetFocus(Handle); + ResetCaretFocusState(); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::WMKillFocus(TWMKillFocus &msg) +{ + ResetCaretFocusState(); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::InvalidateCaret(int pos) +{ + DoubleBuffered = false; + RECT r; + r.top = GetHeadSize(); + r.bottom = ClientHeight - GetFootSize(); + int p_pos = SampleToPixel(pos - FStart); + if(p_pos >= 0 && p_pos < ClientWidth) + { + r.left = p_pos; + r.right = p_pos + 1; + InvalidateRect(Handle, &r, false); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetCaretPos(int pos) +{ + // set caret position. + if(pos < 0) pos = 0; + if(pos >= FReader->NumSamples) pos = FReader->NumSamples - 1; + + if(pos != FCaretPos) + { + // invalidate new position and old position + if(FShowCaret) + { + InvalidateCaret(FCaretPos); + InvalidateCaret(pos); + } + + if(pos >= 0) + { + FCaretVisiblePhase = true; + FBlinkTimer->Enabled = false; + FBlinkTimer->Enabled = FShowCaret; + } + FCaretPos = pos; + if(FOnCaretStateChanged) + FOnCaretStateChanged(this, FCaretPos, FShowCaret && FCaretVisiblePhase && Focused()); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetShowCaret(bool b) +{ + if(b != FShowCaret) + { + FShowCaret = b; + + InvalidateCaret(FCaretPos); + if(FCaretPos >= 0) + { + FCaretVisiblePhase = true; + FBlinkTimer->Enabled = b; + } + + if(FShowCaret && FCaretPos >= 0) + { + FocusedLink = -1; + FocusedLabel = -1; // these are exclusive + Hint = ""; + } + else + { + if(FOnSelectionLost) FOnSelectionLost(this); + } + + if(FShowCaret && FOnShowCaret && FCaretPos >= 0) + { + FOnShowCaret(this, FCaretPos); + } + if(FOnCaretStateChanged) + FOnCaretStateChanged(this, FCaretPos, FShowCaret && FCaretVisiblePhase && Focused()); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::OnBlinkTimer(TObject * sender) +{ + FCaretVisiblePhase = !FCaretVisiblePhase; + InvalidateCaret(FCaretPos); + if(FOnCaretStateChanged) + FOnCaretStateChanged(this, FCaretPos, FShowCaret && FCaretVisiblePhase && Focused()); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::ResetCaretFocusState() +{ + InvalidateCaret(FCaretPos); + FBlinkTimer->Enabled = Focused(); + if(FOnCaretStateChanged) + FOnCaretStateChanged(this, FCaretPos, FShowCaret && FCaretVisiblePhase && Focused()); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DrawCaret() +{ + // draw caret + if(!FReader || !FReader->ReadDone) return; + + if(FShowCaret && FCaretVisiblePhase && Focused()) + { + int p_pos = SampleToPixel(FCaretPos - FStart); + if(p_pos >= 0 && p_pos < ClientWidth) + { + RECT r; + r.top = GetHeadSize(); + r.bottom = ClientHeight - GetFootSize(); + r.left = p_pos; + r.right = p_pos + 1; + InvertRect(Canvas->Handle, &r); + } + } + +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::GetAttentionPos() +{ + int center; + int c_pos = SampleToPixel(FCaretPos - FStart); + if(c_pos >= 0 && c_pos < ClientWidth) + center = FCaretPos; + else + center = FStart + PixelToSample(ClientWidth >> 1); + return center; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::FireRangeChanged() +{ + if(FOnRangeChanged && FReader) + { + int length; + length = PixelToSample(ClientWidth); + if(length >= FReader->NumSamples) + length = FReader->NumSamples; + FOnRangeChanged(this, FStart, length); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetStart(int n) +{ + RECT r; + + // set start position + n = PixelToSample(SampleToPixel(n)); // quantize + r.left = 0; + r.top = 0; + r.right = ClientWidth; + r.bottom = ClientHeight; + int d = SampleToPixel(FStart) - SampleToPixel(n); + ScrollWindowEx(Handle, d, 0, + &r, NULL, NULL, NULL, SW_INVALIDATE); + + FStart = n; + FireRangeChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetMagnify(int m) +{ + // set magnification + if(!FReader || !FReader->ReadDone) return; + + if(m > MaxMagnify) m = MaxMagnify; + if(m < MinMagnify) m = MinMagnify; + if(FMagnify != m) + { + int center = GetAttentionPos(); + FMagnify = m; + int left = center - PixelToSample(ClientWidth >> 1); + int view = PixelToSample(ClientWidth); + if(left < 0) left = 0; + if(left > FReader->NumSamples - view) left = FReader->NumSamples - view; + if(left < 0) left = 0; + + FStart = PixelToSample(SampleToPixel(left)); // quantize + FMinRulerMajorWidth = 0; + FMinRulerMajorHeight = 0; + NotifyLinkChanged(); + NotifyLabelChanged(); + FireRangeChanged(); + Invalidate(); + + // set scroll bar range + SetScrollBarRange(); + + SCROLLINFO si; + ZeroMemory(&si, sizeof(si)); + si.cbSize = sizeof(si); + si.fMask = SIF_ALL; + GetScrollInfo(Handle, SB_HORZ, &si); + + si.fMask = SIF_POS; + si.nPos = FStart; + SetScrollInfo(Handle, SB_HORZ, &si, true); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetInitialMagnify() +{ + // set initial view magnify, which fits the current view width + int m; + for(m = MaxMagnify; m >= MinMagnify; m--) + { + int w; + if(m <= 0) + { + // shrink + w = FReader->NumSamples >> (-m); + } + else + { + // expand + w = FReader->NumSamples << m; + } + if(w < ClientWidth) break; + } + + SetMagnify(m); +} +//--------------------------------------------------------------------------- +AnsiString __fastcall TWaveView::GetMagnifyString() +{ + AnsiString ret; + if(FMagnify >= 0) + { + ret.sprintf("x%d", 1 << FMagnify); + return ret; + } + else + { + ret.sprintf("/%d", 1 << (-FMagnify)); + return ret; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::EnsureView(int p, int length) +{ + // scroll the view (if needed) to ensure the point p .. (p+length) is visible + int lim = PixelToSample(ClientWidth-1); + + if(lim * 0.9 < std::abs(length)) + { + // the client width is less than the length + if(length > 0) + SetView(p, 1); + else + SetView(p, 99); + } + else + { + int lofs = p - Start; + int rofs = p + length - Start; + if(rofs < lofs) std::swap(rofs, lofs); + + if(lofs <= 0) + { + SetView(lofs + Start, 5); + } + else if(rofs >= lim) + { + SetView(rofs + Start, 95); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::GetPositionStringAt(int vx, int vy, + AnsiString &pos, AnsiString &channel) +{ + // vx vy are in client coodinates + if(!FReader || !FReader->ReadDone || + vx < 0 || vy < 0 || vx >= ClientWidth || vy >= ClientHeight) + { + pos = "-"; channel = "-"; + return; + } + + int last = SampleToPixel(FReader->NumSamples - FStart); + if(last <= vx) + { + pos = "-"; channel = "-"; + return; + } + + pos = FReader->SamplePosToTimeString(PixelToSample(vx) + FStart); + + int head_size = GetHeadSize(); + int foot_size = GetFootSize(); + + int one_height = ((ClientHeight - head_size - foot_size) / FReader->Channels) & ~1; + + int ch = (vy - head_size) / one_height; + + channel = FReader->GetChannelLabel(ch); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetMarkerPos(int n) +{ + // set marker position. + // p = -1 for hide the marker. + if(!FReader || !FReader->ReadDone) n = -1; + + if(n != FMarkerPos) + { + // invalidate new position and old position + int p_pos; + RECT r; + r.top = GetHeadSize(); + r.bottom = ClientHeight - GetFootSize(); + + if(n != -1) + { + p_pos = SampleToPixel(n - FStart); + if(p_pos >= 0 && p_pos < ClientWidth) + { + r.left = p_pos; + r.right = p_pos + 1; + InvalidateRect(Handle, &r, false); + } + } + + if(FMarkerPos != -1) + { + p_pos = SampleToPixel(FMarkerPos - FStart); + if(p_pos >= 0 && p_pos < ClientWidth) + { + r.left = p_pos; + r.right = p_pos + 1; + InvalidateRect(Handle, &r, false); + } + } + + FMarkerPos = n; + if(FOnMarkerStateChanged) FOnMarkerStateChanged(this, FMarkerPos, FMarkerPos != -1); + } + + // marker following + if(FReader && FReader->ReadDone && FFollowingMarker && n != -1) + { + __int64 viewsamples = PixelToSample(ClientWidth); + if(viewsamples * 1000 / FReader->Frequency < 500) + { + // too fast to track + SetView(n); + FWaitingMarker = false; + DoubleBuffered = FDoubleBufferEnabled; + } + else + { + DoubleBuffered = false; + + int px = SampleToPixel(n - FStart); + if(px < 0 || px >= ClientWidth) + { + SetView(n, 10); + FWaitingMarker = true; + FSoftCenteringStartTick = 0; + } + else + { + if(FWaitingMarker) + { + if(px >= ClientWidth *9 / 10) + { + FWaitingMarker = false; // start following + FSoftCenteringStartTick = GetTickCount(); + FSoftCenteringPos = px - ClientWidth / 2; + } + } + else + { + // soft centering + int elapsed = GetTickCount() - FSoftCenteringStartTick; + int slew = FSoftCenteringPos - elapsed / 20; + if(slew < 0) slew = 0; + int sn = n; + if(px > ClientWidth/2) + { + sn -= PixelToSample((ClientWidth/2) + slew); + } + else + { + sn -= PixelToSample(ClientWidth / 2); + } + SetView(sn, 0); + } + } + } + } + +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetFollowingMarker(bool b) +{ + if(FFollowingMarker != b) + { + FFollowingMarker = b; + if(FFollowingMarker) + { + ResetMarkerFollow(); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::ResetMarkerFollow() +{ + FWaitingMarker = true; +} +//--------------------------------------------------------------------------- +inline static bool PartIntersect(int a, int b, int i, int j) +{ + if(a > b) + { + int t = b; + b = a; + a = t; + } + if(i > j) + { + int t = i; + i = j; + j = t; + } + + return + a >= i && a <= j || + b >= i && b <= j || + i >= a && i <= b || + j >= a && j <= b; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DrawWave(int start, bool clear) +{ + // draw waveform. + // this does not clear the background unless 'clear' is true. + // 'magnify' is magnify level in logarithm based 2; + // 2 = x 4 + // 1 = x 2 + // 0 = x 1 + // -1 = x 1 / 2 + // -2 = x 1 / 4 + if(!FReader || !FReader->ReadDone) + { + TRect r; + r.left = Canvas->ClipRect.left, r.top = 0, r.right = Canvas->ClipRect.right, r.bottom = ClientHeight; + Canvas->Brush->Style = bsSolid; + Canvas->Brush->Color = C_DISABLEED_CLIENT; + Canvas->FillRect(r); + return ; // reader not available + } + + // calc minimum major ruler size + if(FShowRuler && FMinRulerMajorWidth == 0) + { + AnsiString zero("00:00:00.000"); + FMinRulerMajorWidth = Canvas->TextWidth(zero); + FMinRulerMajorWidth += 3; + FMinRulerMajorHeight = Canvas->TextHeight(zero); + FMinRulerMajorHeight += FMinRulerMajorHeight / 3; + + // decice time unit + double sample_per_pixel; + if(FMagnify > 0) + sample_per_pixel = 1.0 / (1<Frequency; + + // crank up to upper reasonable time unit + int n; + int nn; + for(n = 10000000; n >= 1; n /= 10) + { + double unit_size; + nn = n * 1; + unit_size = nn / time_per_pixel; + if(unit_size <= FMinRulerMajorWidth) break; + } + FRulerUnit = nn; + } + + // calc dimentions + int xstep = FMagnify <= 0 ? 1 : (1<Channels) & ~1; + int one_height_half = one_height >> 1; + int one_client_height = one_height - 2; // 2 : padding margin + + // calc start point + int dest_left = Canvas->ClipRect.left; + int dest_right = Canvas->ClipRect.right; + + //- align destination start and end + dest_left = (int)(dest_left / xstep) * xstep; + dest_right = ((int)(dest_right / xstep) + 1) * xstep; + + //- calc pcm start point + int pos = start + (int)(dest_left / xstep) * sstep; + if(pos < 0) + { + // start position is negative + dest_left += (-pos) * xstep; + pos = 0; + if(dest_left > dest_right) dest_left = dest_right; + } + + + //- calc pcm end point + int vr = SampleToPixel(FReader->NumSamples - pos) + 1 + dest_left; + if(vr < dest_right) dest_right = vr; + + // clear the background + #define CONV_Y(v, ch) ((((v) * one_client_height) / -65536) + \ + one_height_half + (ch) * one_height + head_size) + + if(clear) + { + // negative + if(Canvas->ClipRect.left < dest_left) + { + TRect r; + r.left = Canvas->ClipRect.left, r.top = head_size, r.right = dest_left, r.bottom = ClientHeight; + Canvas->Brush->Style = bsSolid; + Canvas->Brush->Color = C_DISABLEED_CLIENT; + Canvas->FillRect(r); + } + + + // main + if(dest_left < dest_right) + { + TRect r; + r.left = dest_left, r.top = head_size, r.right = dest_right, r.bottom = ClientHeight; + Canvas->Brush->Style = bsSolid; + Canvas->Brush->Color = C_CLIENT; + Canvas->FillRect(r); + } + + // draw -Inf line + Canvas->Pen->Color = C_INF_LINE; + for(int ch = 0; ch < FReader->Channels; ch ++) + { + Canvas->MoveTo(dest_left, CONV_Y(0, ch)); + Canvas->LineTo(dest_right, CONV_Y(0, ch)); + } + + + // over + if(Canvas->ClipRect.right > dest_right) + { + TRect r; + r.left = dest_right, r.top = head_size, r.right = Canvas->ClipRect.right, r.bottom = ClientHeight; + Canvas->Brush->Style = bsSolid; + Canvas->Brush->Color = C_DISABLEED_CLIENT; + Canvas->FillRect(r); + } + + // draw time base line + if(FShowRuler) + { + TRect r; + r.left = dest_left, r.top = 0, r.right = dest_right, r.bottom = head_size; + Canvas->Brush->Style = bsSolid; + Canvas->Brush->Color = C_TIME_CLIENT; + Canvas->FillRect(r); + if(dest_right < Canvas->ClipRect.right) + { + r.left = dest_right; + r.right = Canvas->ClipRect.right; + Canvas->Brush->Color = C_DISABLED_TIME_CLIENT; + Canvas->FillRect(r); + } + Canvas->Pen->Color = C_TIME_COLOR; + Canvas->MoveTo(dest_left, head_size - 1); + Canvas->LineTo(Canvas->ClipRect.right, head_size - 1); + } + + + } + + + // main loop + int rpos = pos; + Canvas->Pen->Color = C_WAVE; + Canvas->Brush->Color = C_WAVE; + if(dest_left >= dest_right) return; // no more samples + for(int x = dest_left; x <= dest_right; + x += xstep, pos += sstep) + { + for(int ch = 0; ch < FReader->Channels; ch ++) + { + // draw line to previous sample + if(pos >= FReader->NumSamples) break; + + if(pos > 0) + { + int pv = FReader->GetSampleAt(pos-1, ch); + Canvas->MoveTo(x-xstep, CONV_Y(pv, ch)); + } + else + { + Canvas->MoveTo(x-xstep, CONV_Y(0, ch)); + } + + int cv; + cv = FReader->GetSampleAt(pos, ch); + Canvas->LineTo(x, CONV_Y(cv, ch)); + + if(FMagnify < 0) + { + // shrink view + // draw peaks + int high, low; + FReader->GetPeak(high, low, pos, ch, sstep); + Canvas->MoveTo(x, CONV_Y(high, ch)); + Canvas->LineTo(x, CONV_Y(low , ch)); + } + if(FMagnify >= 3) + { + // draw sample point + RECT r; + r.left = x - 1; + r.right = x + 2; + r.top = CONV_Y(cv, ch) - 1; + r.bottom = r.top + 3; + Canvas->FillRect(r); + } + } + } + + // draw marker + if(FMarkerPos != -1) + { + int p_pos = SampleToPixel(FMarkerPos - FStart); + if(p_pos >= 0 && p_pos < ClientWidth) + { + RECT r; + r.top = head_size; + r.bottom = bottom_limit; + r.left = p_pos; + r.right = p_pos + 1; + InvertRect(Canvas->Handle, &r); + } + } + + + // draw time line + if(FShowRuler && Canvas->ClipRect.top < head_size) + { + // find start ruler unit + Canvas->Brush->Style = bsClear; + Canvas->Pen->Color = C_TIME_COLOR; + Canvas->Font->Color = C_TIME_COLOR; + double sample_per_pixel; + + int time_index; + + if(FMagnify > 0) + sample_per_pixel = 1.0 / (1<Frequency * 10000; + + double start_time = (double)rpos / (double)FReader->Frequency * 10000; + time_index = (int)(start_time / FRulerUnit) - 10; + start_time = (double)time_index * (double)FRulerUnit; + + double x_per_unit = FRulerUnit / time_per_pixel; + + double x = start_time / time_per_pixel - SampleToPixel(rpos); + + for(; x < dest_right; x += x_per_unit, time_index ++) + { + int ix = (int)floor(x + dest_left); + int st; + bool write_time = false; + if(time_index % 10 == 0) + { + st = 0; + write_time = true; + } + else if(time_index % 5 == 0) + { + if(FRulerUnit >= 5 && x_per_unit * 5 > FMinRulerMajorWidth) + { + st = 0; + write_time = true; + } + else + { + st = (head_size >> 3) + (head_size >> 1); + } + } + else + { + if(FRulerUnit >= 1 && x_per_unit > FMinRulerMajorWidth) + { + st = 0; + write_time = true; + } + else + { + st = (head_size >> 2) + (head_size >> 1); + } + } + Canvas->MoveTo(ix, st); + Canvas->LineTo(ix, head_size - 1); + if(write_time) + { + // write time + int t = (int)((__int64)time_index * FRulerUnit / 10); + char buf[100]; + if(FRulerUnit >= 5000) + { + sprintf(buf, "%02d:%02d:%02d", + t / (1000 * 60 * 60), + t / (1000 * 60) % 60, + t / 1000 % 60); + } + else + { + sprintf(buf, "%02d:%02d:%02d.%03d", + t / (1000 * 60 * 60), + t / (1000 * 60) % 60, + t / 1000 % 60, + t % 1000); + } + Canvas->TextOut(ix+2, 0, buf); + } + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::NotifyLinkChanged() +{ + // re-check tier + + // re-check focused or hovered state + if(FFocusedLink >= (int)Links.size()) FFocusedLink = -1; + if(FHoveredLink >= (int)Links.size()) FHoveredLink = -1; + Hint = ""; + + // arrange link lines to ensure visibility and discrimination. + + //- mark indices + for(unsigned int i = 0; i < Links.size(); i++) Links[i].Index = i; + + //- sort by link distance + std::stable_sort(Links.begin(), Links.end(), tTVPWaveLoopLink::tSortByDistanceFuncObj()); + + //- arrange Links by finding line intersections. + int tier_count = 0; + std::vector > > tiers; + for(unsigned int i = 0; i < Links.size(); i++) + { + // search free tier + TTierMinMaxInfo cinfo; + GetLinkMinMaxPixel(Links[i], cinfo); + + int found_link_tier = -1; + int found_from_tier = 0; + int found_to_tier = 0; + + for(unsigned int j = 0; j < i; j++) + { + TTierMinMaxInfo jinfo; + GetLinkMinMaxPixel(Links[j], jinfo); + + // for 'from' + if( PartIntersect(jinfo.ToMin, jinfo.ToMax, cinfo.FromMin, cinfo.FromMax) ) + { + // intersection found + found_from_tier = Links[j].ToTier + 1; + } + if( PartIntersect(jinfo.FromMin, jinfo.FromMax, cinfo.FromMin, cinfo.FromMax)) + { + // intersection found + found_from_tier = Links[j].FromTier + 1; + } + + // for 'to' + if( PartIntersect(jinfo.ToMin, jinfo.ToMax, cinfo.ToMin, cinfo.ToMax)) + { + // intersection found + found_to_tier = Links[j].ToTier + 1; + } + if( PartIntersect(jinfo.FromMin, jinfo.FromMax, cinfo.ToMin, cinfo.ToMax)) + { + // intersection found + found_to_tier = Links[j].FromTier + 1; + } + } + + for(unsigned int i = + found_from_tier > found_to_tier ? + found_from_tier : found_to_tier; i < tiers.size(); i++) + { + // for link + bool conflicted = false; + std::vector > & tier = tiers[i]; + for(std::vector >::iterator j = tier.begin(); + j != tier.end(); j++) + { + if(PartIntersect(j->first, j->second, cinfo.LinkMin, cinfo.LinkMax)) + { + // intersection found + conflicted = true; + break; + } + } + if(!conflicted) + { + // intersection not found + found_link_tier = i; + break; + } + } + + if(found_link_tier == -1) + { + // create new tier + found_link_tier = tiers.size(); + tiers.push_back(std::vector >() ); + } + + Links[i].LinkTier = found_link_tier; + Links[i].FromTier = found_from_tier; + Links[i].ToTier = found_to_tier; + + tiers[found_link_tier].push_back(std::pair(cinfo.LinkMin, cinfo.LinkMax)); + + if(tier_count < found_link_tier + 1) tier_count = found_link_tier + 1; + } + + if(FLinkTierCount != tier_count) + Invalidate(); + FLinkTierCount = tier_count; + + //- sort by Index + std::stable_sort(Links.begin(), Links.end(), tTVPWaveLoopLink::tSortByIndexFuncObj()); + + // call notify handler + if(FOnLinkModified && !FInOnLinkModified) + { + FInOnLinkModified = true; + try + { + FOnLinkModified(this); + } + catch(...) + { + FInOnLinkModified = false; + throw; + } + FInOnLinkModified = false; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetLinks(const std::vector & links) +{ + // set new link information + // note that this will call OnLinkModified + Links = links; + NotifyLinkChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::GetLinkMinMaxPixel(const tTVPWaveLoopLink & link, + TTierMinMaxInfo & info) +{ + int from_px = SampleToPixel(link.From); + int to_px = SampleToPixel(link.To); + + int min; + int max; + + min = from_px - 1; + max = from_px + 1; + + if(min > to_px - (LinkArrowSize+1)) min = to_px - (LinkArrowSize+1); + if(max < to_px + (LinkArrowSize+1)) max = to_px + (LinkArrowSize+1); + + info.LinkMin = min; + info.LinkMax = max; + info.FromMin = from_px - 1; + info.FromMax = from_px + 1; + info.ToMin = to_px - (LinkArrowSize+1); + info.ToMax = to_px + (LinkArrowSize+1); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DrawLinkArrowAt(int tier, int where) +{ + // arrow bitmap: + // <> = 1 pixel + + // <> + // <> + // <><><> + // <><><> + // <><><><><> + // <><><><><> + // <><><><><><><> + // <><><><><><><> + // <> + // <> + + // draw up-arrow at given position + int foot_size = GetFootSize(); + int y_start = ClientHeight - foot_size; + int y = y_start + tier * TVP_LGD_TIER_HEIGHT; + + // draw arrow body + Canvas->Brush->Style = bsSolid; + Canvas->Brush->Color = Canvas->Pen->Color; + TRect r; + + for(int i = 1; i < LinkArrowSize; i++) + { + r.left = where - i; + r.top = y + i*2; + r.right = where + (i+1); + r.bottom = y + (i*2+2); + Canvas->FillRect(r); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DrawDirectionArrowAt(int tier, bool dir, int where) +{ + // arrow bitmap: + // <> = 1 pixel + + // <><> + // <><><><> + // <><><><><><><><><><> + // <><><><> + // <><> + + // <><> + // <><><><> + // <><><><><><><><><><> + // <><><><> + // <><> + + int foot_size = GetFootSize(); + int y_start = ClientHeight - foot_size; + int y = y_start + tier * TVP_LGD_TIER_HEIGHT + TVP_LGD_TIER_HEIGHT - 3; + + Canvas->Brush->Style = bsSolid; + Canvas->Brush->Color = Canvas->Pen->Color; + TRect r; + + r.left = where - 2; + r.top = y; + r.right = where + 6; + r.bottom = y + 1; + Canvas->FillRect(r); + + if(dir) + { + // dir = true: right arrow + r.left = where + 0; + r.top = y - 2; + r.right = where + 2; + r.bottom = y + 3; + Canvas->FillRect(r); + + r.left = where + 2; + r.top = y - 1; + r.right = where + 4; + r.bottom = y + 2; + Canvas->FillRect(r); + } + else + { + // dir = false: left arrow + r.left = where + 0; + r.top = y - 1; + r.right = where + 2; + r.bottom = y + 2; + Canvas->FillRect(r); + + r.left = where + 2; + r.top = y - 2; + r.right = where + 4; + r.bottom = y + 3; + Canvas->FillRect(r); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DrawLinkOf(const tTVPWaveLoopLink & link) +{ + int dest_left = Canvas->ClipRect.left; + int dest_right = Canvas->ClipRect.right; + int foot_size = GetFootSize(); + int y_start = ClientHeight - foot_size; + + int x_from; + int x_to; + int y_link = y_start + link.LinkTier * TVP_LGD_TIER_HEIGHT + TVP_LGD_TIER_HEIGHT - 3; + + int dir_step = PixelToSample(LinkDirectionInterval); + + if(link.Condition != llcNone) + Canvas->Pen->Style = psDot; + else + Canvas->Pen->Style = psSolid; + + // for from line + x_from = SampleToPixel(link.From - Start); + if(x_from >= dest_left || x_from < dest_right) + { + int y0 = y_start + link.FromTier * TVP_LGD_TIER_HEIGHT; + Canvas->Brush->Style = bsClear; + Canvas->MoveTo(x_from, y0); + Canvas->LineTo(x_from, y_link); + } + + // for to arrow + x_to = SampleToPixel(link.To - Start); + int xmin = x_to - (LinkArrowSize+1); + int xmax = x_to + (LinkArrowSize+1); + if(PartIntersect(xmin, xmax, dest_left, dest_right -1)) + { + DrawLinkArrowAt(link.ToTier, x_to); + int y0 = y_start + link.ToTier * TVP_LGD_TIER_HEIGHT; + Canvas->Brush->Style = bsClear; + Canvas->MoveTo(x_to, y0); + Canvas->LineTo(x_to, y_link); + } + + // for horizontal link line + if(PartIntersect(x_from, x_to, dest_left, dest_right-1)) + { + Canvas->Brush->Style = bsClear; + if(x_from < x_to) + { + Canvas->MoveTo(x_from, y_link); + Canvas->LineTo(x_to+1, y_link); + } + else + { + Canvas->MoveTo(x_from, y_link); + Canvas->LineTo(x_to-1, y_link); + } + } + + // for direction mark + int m_start = x_to < x_from ? x_to : x_from; + int m_end = x_to < x_from ? x_from : x_to; + if(m_end - m_start > LinkDirectionArrowWidth * 2) + { + int s = (Start / dir_step) * dir_step; + + for(;;) + { + int x = SampleToPixel(s - Start); + if(x > dest_right) break; + + if(x > m_start + LinkDirectionArrowWidth && x < m_end - LinkDirectionArrowWidth) + DrawDirectionArrowAt(link.LinkTier, x_from < x_to, x); + + s += dir_step; + } + } + + Canvas->Pen->Style = psSolid; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DrawLinks(void) +{ + if(!FReader || !FReader->ReadDone) return; + if(!FShowLinks) return; + + // calc start point + int dest_left = Canvas->ClipRect.left; + int dest_right = Canvas->ClipRect.right; + int head_size = GetHeadSize(); + int foot_size = GetFootSize(); + int y_start = ClientHeight - foot_size; + + // draw separator + Canvas->Pen->Color = C_LINK_SEPARETOR; + Canvas->MoveTo(dest_left, y_start); + Canvas->LineTo(dest_right, y_start); + + if(PartIntersect(Canvas->ClipRect.top, Canvas->ClipRect.bottom -1, + y_start, ClientHeight - 1)) + { + // draw each link (for vertical weak line) + Canvas->Pen->Color = C_LINK_WEAK_LINE; + + for(unsigned int i = 0; i < Links.size(); i++) + { + const tTVPWaveLoopLink & link = Links[i]; + tjs_int x; + + x = SampleToPixel(link.From - Start); + if(x >= dest_left || x < dest_right) + { + int y = y_start + link.FromTier * TVP_LGD_TIER_HEIGHT - 1; + Canvas->MoveTo(x, y_start+1); + Canvas->LineTo(x, y); + } + x = SampleToPixel(link.To - Start); + if(x >= dest_left || x < dest_right) + { + int y = y_start + link.ToTier * TVP_LGD_TIER_HEIGHT - 1; + Canvas->MoveTo(x, y_start+1); + Canvas->LineTo(x, y); + } + } + + // draw each link + for(unsigned int i = 0; i < Links.size(); i++) + { + if((int)i == FFocusedLink) + continue; + else if((int)i == FHoveredLink) + continue; + else + Canvas->Pen->Color = C_LINK_LINE; + + const tTVPWaveLoopLink & link = Links[i]; + + DrawLinkOf(link); + } + if(FHoveredLink != -1) + { + Canvas->Pen->Color = C_LINK_HOVER; + const tTVPWaveLoopLink & link = Links[FHoveredLink]; + DrawLinkOf(link); + } + + if(FFocusedLink != -1) + { + Canvas->Pen->Width = 2; + Canvas->Pen->Color = C_LINK_FOCUS; + const tTVPWaveLoopLink & link = Links[FFocusedLink]; + DrawLinkOf(link); + Canvas->Pen->Width = 1; + } + } + + + if(PartIntersect(Canvas->ClipRect.top, Canvas->ClipRect.bottom -1, + head_size, y_start - 1)) + { + // draw link 'from' and 'to' lines + Canvas->Pen->Color = C_LINK_WAVE_MARK; + Canvas->Pen->Style = psDashDot; + Canvas->Brush->Style = bsClear; + for(unsigned int i = 0; i < Links.size(); i++) + { + const tTVPWaveLoopLink & link = Links[i]; + int x; + + x = SampleToPixel(link.From - Start); + Canvas->MoveTo(x, head_size); + Canvas->LineTo(x, y_start); + + x = SampleToPixel(link.To - Start); + Canvas->MoveTo(x, head_size); + Canvas->LineTo(x, y_start); + } + Canvas->Pen->Style = psSolid; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::InvalidateLink(int linknum) +{ + // invalidate displaying area of link 'linknum'. + // currently not completely implemented. + + if(linknum < 0 || linknum >= (int)Links.size()) return; + + const tTVPWaveLoopLink & link = Links[linknum]; + + int foot_size = GetFootSize(); + int y_start = ClientHeight - foot_size; + RECT r; + r.top = y_start; + r.bottom = ClientHeight; + r.left = 0; + r.right = ClientWidth; + InvalidateRect(Handle, &r, false); + + // also invalidate wave link marks + int x_from = SampleToPixel(link.From - Start); + int x_to = SampleToPixel(link.To - Start); + + r.top = GetHeadSize(); + r.bottom = ClientHeight - GetFootSize(); + + if(x_from >= 0 && x_from < ClientWidth) + { + r.left = x_from; + r.right = x_from + 1; + InvalidateRect(Handle, &r, false); + } + + if(x_to >= 0 && x_to < ClientWidth) + { + r.left = x_to; + r.right = x_to + 1; + InvalidateRect(Handle, &r, false); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetHoveredLink(int l) +{ + if(FHoveredLink != l) + { + DoubleBuffered = FDoubleBufferEnabled; + InvalidateLink(FHoveredLink); + FHoveredLink = l; + InvalidateLink(FHoveredLink); + + // generate link hint + AnsiString hint; + if(FHoveredLink != -1) + { + tTVPWaveLoopLink & link = Links[FHoveredLink]; + AnsiString cond; + if(link.Condition == llcNone) + { + cond = C_LINK_COND_CODES[0]; + } + else + { + cond.sprintf(C_LINK_COND_CODES[(int)link.Condition].c_str(), + link.CondVar, link.RefValue); + } + + hint.sprintf(C_LINK_HINT.c_str(), + FReader->SamplePosToTimeString(link.From), + FReader->SamplePosToTimeString(link.To), + FReader->SamplePosToTimeString(std::abs(link.To - link.From)), + cond.c_str()); + } + Application->CancelHint(); + Hint = hint; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetFocusedLink(int l) +{ + if(FFocusedLink != l) + { + DoubleBuffered = FDoubleBufferEnabled; + InvalidateLink(FFocusedLink); + FFocusedLink = l; + InvalidateLink(FFocusedLink); + if(l != -1) + { + ShowCaret = false; // link, label and caret are exclusive + FocusedLabel = -1; + Hint = ""; + if(FOnLinkSelected) + { + FOnLinkSelected(this, l, Links[l]); + } + } + else + { + if(FOnSelectionLost) FOnSelectionLost(this); + } + } +} +//--------------------------------------------------------------------------- +bool __fastcall TWaveView::IsLinkAt(int linknum, int x, int y) +{ + if(linknum < 0 || linknum >= (int)Links.size()) return false; + + const tTVPWaveLoopLink & link = Links[linknum]; + int foot_size = GetFootSize(); + int y_start = ClientHeight - foot_size; + + int x_from; + int x_to; + int y_link = y_start + link.LinkTier * TVP_LGD_TIER_HEIGHT + + TVP_LGD_TIER_HEIGHT - 3 - TVP_LGD_TIER_HEIGHT / 2; + + x_from = SampleToPixel(link.From - Start); + x_to = SampleToPixel(link.To - Start); + if(x_from > x_to) + std::swap(x_from, x_to); + + return x >= x_from && x <= x_to && + y >= y_link && y < y_link + TVP_LGD_TIER_HEIGHT; +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::GetLinkAt(int x, int y) +{ + int foot_size = GetFootSize(); + int y_start = ClientHeight - foot_size; + if(y < y_start) return -1; + + // give priority to current focuesd link + if(FFocusedLink != -1) + if(IsLinkAt(FFocusedLink, x, y)) return FFocusedLink; + + // walk through + for(unsigned int i = 0; i < Links.size(); i++) + { + if((int)i != FFocusedLink && IsLinkAt(i, x, y)) return i; + } + return -1; +} +//--------------------------------------------------------------------------- +#define MARK_GRIP_MARGIN 2 +int __fastcall TWaveView::IsLinkWaveMarkAt(int x, int linknum, bool &from_or_to) +{ + const tTVPWaveLoopLink & link = Links[linknum]; + + int from_pos = SampleToPixel(link.From - FStart); + int to_pos = SampleToPixel(link.To - FStart); + + bool from_match = false; + bool to_match = false; + if(from_pos - MARK_GRIP_MARGIN <= x && x <= from_pos + MARK_GRIP_MARGIN) + from_match = true; + + if(to_pos - MARK_GRIP_MARGIN <= x && x <= to_pos + MARK_GRIP_MARGIN) + to_match = true; + + if(to_match && from_match) + { + // both from and to are matched + // check which one should be taken + + int center = (from_pos + to_pos) / 2; + if(center <= x) + { + if(link.From > link.To) + to_match = false; + else + from_match = false; + } + else + { + if(link.From > link.To) + from_match = false; + else + to_match = false; + } + } + + if(to_match || from_match) + { + from_or_to = to_match; + return from_or_to ? link.To : link.From; + } + + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::GetLinkWaveMarkAt(int x, int &linknum, bool &from_or_to) +{ + // give priority to focused link + int pos; + if(FFocusedLink != -1) + { + pos = IsLinkWaveMarkAt(x, FFocusedLink, from_or_to); + + if(pos != -1) + { + linknum = FFocusedLink; + return pos; + } + } + + // for each links + for(unsigned int i = 0; i < Links.size(); i++) + { + if((int)i != FFocusedLink) + { + pos = IsLinkWaveMarkAt(x, i, from_or_to); + + if(pos != -1) + { + linknum = i; + return pos; + } + } + } + + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::SelectLink(int tier, int spos, int mode) +{ + // select link at sample position "spos", at tier "tier". + // mode = 0 : nearest link + // mode = 1 : upper link + // mode = 2 : lower link + // mode = 3 : left link + // mode = 4 : right link + + // search the nearest link at spos + int found_link = -1; + int min_dist = -1; + for(unsigned int i = 0; i < Links.size(); i++) + { + if(Links[i].LinkTier != tier) continue; + int dist = std::abs((Links[i].From + Links[i].To)/2 - spos); + if(min_dist == -1 || min_dist > dist) + min_dist = dist, found_link = i; + } + + if(found_link == -1) return -1; // link not found at tier + if(mode == 0) return found_link; // the nearest link found + + // search most nearest left or right siblings + const tTVPWaveLoopLink & reflink = Links[found_link]; + int reflink_num = found_link; + found_link = -1; + min_dist = -1; + for(unsigned int i = 0; i < Links.size(); i++) + { + if((int)i == reflink_num) continue; + + int rx, ry = reflink.LinkTier * TVP_LGD_TIER_HEIGHT; + int cx, cy = Links[i].LinkTier * TVP_LGD_TIER_HEIGHT; + // find link's nearest position + if(Links[i].LinkTier == reflink.LinkTier || + !PartIntersect(Links[i].From, Links[i].To, reflink.From, reflink.To)) + { + // the same link pos or does not have link intersection + if(Links[i].From < reflink.From) + { + rx = SampleToPixel(std::min(reflink.From, reflink.To)); + cx = SampleToPixel(std::max(Links[i].From, Links[i].To)); + } + else + { + rx = SampleToPixel(std::max(reflink.From, reflink.To)); + cx = SampleToPixel(std::min(Links[i].From, Links[i].To)); + } + } + else + { + // different link tier but have intersection + rx = SampleToPixel((reflink.From + reflink.To)/2); + cx = rx; + } + + if(mode == 1 && !(cy <= ry && std::abs(cx - rx) < ry - cy)) continue; + if(mode == 2 && !(cy >= ry && std::abs(cx - rx) < cy - ry)) continue; + if(mode == 3 && !(cx <= rx && std::abs(cy - ry) < rx - cx)) continue; + if(mode == 4 && !(cx >= rx && std::abs(cy - ry) < cx - rx)) continue; + + int dist = (cx-rx)*(cx-rx) + (cy-ry)*(cy-ry); + if(min_dist == -1 || min_dist > dist) + min_dist = dist, found_link = i; + } + + return found_link; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::FocusLinkAt(int tier, int spos, int mode) +{ + // focus the nearest link + int found = SelectLink(tier, spos, mode); + if(found != -1) + { + FocusedLink = found; + EnsureView(Links[found].From, Links[found].To - Links[found].From); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::CreateNewLink() +{ + // create a new link + if(!FReader || !FReader->ReadDone) return; + + int from, to; + if(LastClickedPos[0] == LastClickedPos[1]) + { + // 'from' and the 'to' is the same + from = LastClickedPos[0]; + to = LastClickedPos[0] + 500000; + } + else + { + from = LastClickedPos[0]; + to = LastClickedPos[1]; + } + + if(from < 0) from = 0; + if(from > FReader->NumSamples) from = FReader->NumSamples; + + if(to < 0) to = 0; + if(to > FReader->NumSamples) to = FReader->NumSamples; + + + tTVPWaveLoopLink link; + + link.From = from; + link.To = to; + link.Smooth = false; + link.Condition = llcNone; + link.CondVar = 0; + Links.push_back(link); + + NotifyLinkChanged(); + + FocusedLink = Links.size() - 1; // focus last + + DoubleBuffered = FDoubleBufferEnabled; + Invalidate(); + PushUndo(); //==== push undo +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::CreateNewLabel(int pos) +{ + // create new label at current caret position + if(!FReader || !FReader->ReadDone) return; + + if(pos == -1) pos = GetAttentionPos(); + tTVPWaveLabel label; + label.Position = pos; + + // search free label name + int last = 0; + for(std::vector::iterator i = Labels.begin(); i != Labels.end(); + i++) + { + if(i->Name.AnsiPos(C_NEW_LABEL_BASE_NAME) == 1) + { + int n = atoi(i->Name.c_str() + C_NEW_LABEL_BASE_NAME.Length()); + if(n >= last) last = n + 1; + } + } + + label.Name = C_NEW_LABEL_BASE_NAME + AnsiString(last); + label.NameWidth = -1; + + Labels.push_back(label); + + NotifyLabelChanged(); + + FocusedLabel = Labels.size() - 1; + + DoubleBuffered = FDoubleBufferEnabled; + Invalidate(); + PushUndo(); //==== push undo +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::NotifyLabelChanged() +{ + // notify the label information has changed + if(FFocusedLabel >= (int)Labels.size()) FFocusedLabel = -1; + if(FHoveredLabel >= (int)Labels.size()) FHoveredLabel = -1; + + + for(std::vector::iterator i = Labels.begin(); i != Labels.end(); + i++) + { + // invalidate all cache information + i->NameWidth = -1; + } + + // call notify handler + if(FOnLabelModified && ! FInOnLabelModified) + { + FInOnLabelModified = true; + try + { + FOnLabelModified(this); + } + catch(...) + { + FInOnLabelModified = false; + throw; + } + FInOnLabelModified = false; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetLabels(const std::vector & labels) +{ + // set new label information + // note that this will call OnLabelModified + Labels = labels; + NotifyLabelChanged(); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::GetLabelNameRect(tTVPWaveLabel & label, TRect & rect) +{ + // get text height + if(LabelTextHeight == -1) + LabelTextHeight = Canvas->TextHeight("|"); + + // get label name rectangle + int x = SampleToPixel(label.Position - Start); + int head_size = GetHeadSize(); + Canvas->Font->Style = Canvas->Font->Style << fsBold; + + // decide the label position + int text_width; + + if(label.NameWidth == -1) + label.NameWidth = Canvas->TextWidth(label.Name); + + text_width = label.NameWidth + 10; + + // check right free space + int right_space; + if(PixelToSample(ClientWidth) > FReader->NumSamples) + right_space = ClientWidth - x; + else + right_space = SampleToPixel(FReader->NumSamples - label.Position); + + // check left free space + int left_space; + left_space = SampleToPixel(label.Position); + + // decide position + int text_x; + if(right_space < text_width && left_space >= text_width) + text_x = x - text_width; + else + text_x = x + 10; + + int text_y = head_size - LabelTextHeight - 2; + + // return a rectangle + rect.left = text_x - 2; + rect.top = text_y - 1; + rect.right = text_x + text_width - 10 + 2; + rect.bottom = head_size; + + Canvas->Font->Style = Canvas->Font->Style >> fsBold; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DrawLabelMarkOf(tTVPWaveLabel & label) +{ + int head_size = GetHeadSize(); + int foot_size = GetFootSize(); + int bottom_limit = ClientHeight - foot_size; + + // draw label mark + int x; + x = SampleToPixel(label.Position - Start); + + Canvas->Brush->Color = C_LABEL_MARK; + Canvas->Brush->Style = bsSolid; + TPoint points[3]; + points[0].x = x; + points[0].y = head_size - 2; + points[1].x = x - 4; + points[1].y = head_size - 10; + points[2].x = x + 4; + points[2].y = head_size - 10; + + Canvas->Polygon(points, 2); + + Canvas->Pen->Width = 1; + Canvas->Brush->Style = bsClear; + Canvas->Pen->Color = C_LABEL_WAVE_MARK; + Canvas->Pen->Style = psDashDot; + Canvas->MoveTo(x, head_size); + Canvas->LineTo(x, bottom_limit); + Canvas->Pen->Style = psSolid; + +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DrawLabelNameOf(tTVPWaveLabel & label) +{ + // draw label name + TRect rect; + GetLabelNameRect(label, rect); + + if( + PartIntersect(rect.left, rect.right-1, Canvas->ClipRect.left, Canvas->ClipRect.right-1) && + PartIntersect(rect.top, rect.bottom-1, Canvas->ClipRect.top, Canvas->ClipRect.bottom-1) ) + { + + int text_x = rect.left + 2; + int text_y = rect.top + 1; + + Canvas->Font->Style = Canvas->Font->Style << fsBold; + TColor color_save = Canvas->Font->Color; + Canvas->Font->Color = C_LABEL_TEXT_BG; + Canvas->TextOut(text_x-2 , text_y , label.Name); + Canvas->TextOut(text_x+2 , text_y , label.Name); + Canvas->TextOut(text_x , text_y-1 , label.Name); + Canvas->TextOut(text_x , text_y+1 , label.Name); + Canvas->Font->Color = color_save; + Canvas->TextOut(text_x , text_y , label.Name); + Canvas->Font->Style = Canvas->Font->Style >> fsBold; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DrawLabels() +{ + if(!FReader || !FReader->ReadDone) return; + if(!FShowLabels) return; + + // draw each label mark + for(unsigned int i = 0; i < Labels.size(); i++) + { + if((int)i == FFocusedLabel) + continue; + else if((int)i == FHoveredLabel) + continue; + else + { + Canvas->Pen->Color = C_LABEL_MARK_LINE; + Canvas->Font->Color = C_LABEL_TEXT; + } + + tTVPWaveLabel & label = Labels[i]; + + DrawLabelMarkOf(label); + } + if(FFocusedLabel != -1) + { + Canvas->Pen->Width = 2; + Canvas->Pen->Color = C_LABEL_MARK_FOCUS; + Canvas->Font->Color = C_LABEL_TEXT_FOCUS; + tTVPWaveLabel & label = Labels[FFocusedLabel]; + DrawLabelMarkOf(label); + Canvas->Pen->Width = 1; + } + if(FHoveredLabel != -1 && FHoveredLabel != FFocusedLabel) + { + Canvas->Pen->Color = C_LABEL_MARK_HOVER; + Canvas->Font->Color = C_LABEL_TEXT_HOVER; + tTVPWaveLabel & label = Labels[FHoveredLabel]; + DrawLabelMarkOf(label); + } + + // draw each label name + for(unsigned int i = 0; i < Labels.size(); i++) + { + if((int)i == FFocusedLabel) + continue; + else if((int)i == FHoveredLabel) + continue; + else + { + Canvas->Pen->Color = C_LABEL_MARK_LINE; + Canvas->Font->Color = C_LABEL_TEXT; + } + + tTVPWaveLabel & label = Labels[i]; + + DrawLabelNameOf(label); + } + if(FFocusedLabel != -1) + { + Canvas->Pen->Width = 2; + Canvas->Pen->Color = C_LABEL_MARK_FOCUS; + Canvas->Font->Color = C_LABEL_TEXT_FOCUS; + tTVPWaveLabel & label = Labels[FFocusedLabel]; + DrawLabelNameOf(label); + Canvas->Pen->Width = 1; + } + if(FHoveredLabel != -1 && FHoveredLabel != FFocusedLabel) + { + Canvas->Pen->Color = C_LABEL_MARK_HOVER; + Canvas->Font->Color = C_LABEL_TEXT_HOVER; + tTVPWaveLabel & label = Labels[FHoveredLabel]; + DrawLabelNameOf(label); + } + + +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::InvalidateLabel(int labelnum) +{ + // invalidate label labelnum + if(labelnum < 0 || labelnum >= (int)Labels.size()) return; + + int head_size = GetHeadSize(); + int foot_size = GetFootSize(); + int bottom_limit = ClientHeight - foot_size; + + // invalidate marker triangle + tTVPWaveLabel & label = Labels[labelnum]; + int x = SampleToPixel(label.Position - Start); + + // invalidate marker triangle + RECT r; + r.left = x - 5; + r.top = head_size - 11; + r.right = x + 6; + r.bottom = head_size; + InvalidateRect(Handle, &r, FALSE); + + // invalidate wave mark + r.left = x; + r.top = head_size; + r.right = x + 1; + r.bottom = bottom_limit; + InvalidateRect(Handle, &r, FALSE); + + // invalidate label name + TRect rect; + GetLabelNameRect(label, rect); + InvalidateRect(Handle, (RECT*)&rect, FALSE); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetHoveredLabel(int l) +{ + if(FHoveredLabel != l) + { + DoubleBuffered = FDoubleBufferEnabled; + InvalidateLabel(FHoveredLabel); + FHoveredLabel = l; + InvalidateLabel(FHoveredLabel); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::SetFocusedLabel(int l) +{ + if(FFocusedLabel != l) + { + DoubleBuffered = FDoubleBufferEnabled; + InvalidateLabel(FFocusedLabel); + FFocusedLabel = l; + InvalidateLabel(FFocusedLabel); + if(l != -1) + { + ShowCaret = false; // link, label and caret are exclusive + FocusedLink = -1; // link, label and caret are exclusive + Hint = ""; + if(FOnLabelSelected) + { + FOnLabelSelected(this, l, Labels[l]); + } + } + else + { + if(FOnSelectionLost) FOnSelectionLost(this); + } + } +} +//--------------------------------------------------------------------------- +bool __fastcall TWaveView::IsLabelAt(int labelnum, int x, int y) +{ + if(labelnum < 0 || labelnum >= (int)Labels.size()) return false; + + const tTVPWaveLabel & label = Labels[labelnum]; + int lx = SampleToPixel(label.Position - Start); + + int head_size = GetHeadSize(); + return y >= 0 && y < head_size && x >= lx - 4 && x <= lx + 4; +} +//--------------------------------------------------------------------------- +bool __fastcall TWaveView::IsLabelNameAt(int labelnum, int x, int y) +{ + if(labelnum < 0 || labelnum >= (int)Labels.size()) return false; + + tTVPWaveLabel & label = Labels[labelnum]; + TRect rect; + GetLabelNameRect(label, rect); + + return x >= rect.left && x < rect.right && y >= rect.top && y < rect.bottom; +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::GetLabelAt(int x, int y) +{ + // give priority to focused label + if(FFocusedLabel != -1) + { + if(IsLabelAt(FFocusedLabel, x, y)) + return FFocusedLabel; + } + + // for each labels + for(unsigned int i = 0; i < Labels.size(); i++) + { + if((int)i != FFocusedLabel) + { + if(IsLabelAt(i, x, y)) + { + return i; + } + } + } + + // give priority to focused label + if(FFocusedLabel != -1) + { + if(IsLabelNameAt(FFocusedLabel, x, y)) + return FFocusedLabel; + } + + // for each labels + for(unsigned int i = 0; i < Labels.size(); i++) + { + if((int)i != FFocusedLabel) + { + if(IsLabelNameAt(i, x, y)) + { + return i; + } + } + } + + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::IsLabelWaveMarkAt(int x, int labelnum) +{ + if(labelnum < 0 || labelnum >= (int)Labels.size()) return false; + + const tTVPWaveLabel & label = Labels[labelnum]; + int lx = SampleToPixel(label.Position - FStart); + + return (lx - MARK_GRIP_MARGIN <= x && x <= lx + MARK_GRIP_MARGIN) ? + label.Position : -1; +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::GetLabelWaveMarkAt(int x, int &labelnum) +{ + // give priority to focused label + int pos; + + if(FFocusedLabel != -1) + { + pos = IsLabelWaveMarkAt(x, FFocusedLabel); + + if(pos != -1) + { + labelnum = FFocusedLabel; + return pos; + } + } + + // for each labels + for(unsigned int i = 0; i < Labels.size(); i++) + { + if((int)i != FFocusedLabel) + { + pos = IsLabelWaveMarkAt(x, i); + + if(pos != -1) + { + labelnum = i; + return pos; + } + } + } + + return -1; +} +//--------------------------------------------------------------------------- +int __fastcall TWaveView::SelectLabel(int spos, int mode) +{ + // select one label at sample position "spos". + // mode = -1 : search left label of spos + // mode = 0 : search the nearest label at spos + // mode = +1 : search right label of spos + + // mark label index + for(unsigned int i = 0; i < Labels.size(); i++) Labels[i].Index = i; + + // sort labels by the position + std::sort(Labels.begin(), Labels.end(), tTVPWaveLabel::tSortByPositionFuncObj()); + + // find the nearest label at spos + int found_label = -1; + do // dummy loop + { + int mindist = -1; + int minlabel = -1; + for(unsigned int i = 0; i < Labels.size(); i++) + { + int dist = std::abs(Labels[i].Position - spos); + if(mindist == -1 || dist < mindist) + mindist = dist, minlabel = i; + } + if(minlabel == -1) + { + found_label = -1; // no labels found + break; + } + + if(mode == 0) return minlabel; // nearest label found + + // skip labels which have the same position + minlabel += mode; + if(minlabel < 0 || minlabel >= (int)Labels.size()) + { + found_label = -1; // out of range + break; + } + while(minlabel >= 0 && minlabel < (int)Labels.size() && Labels[minlabel].Position == spos) + minlabel += mode; + if(minlabel < 0 || minlabel >= (int)Labels.size()) + { + found_label = -1; // out of range + break; + } + + found_label = minlabel; // label found + } while(false); + + if(found_label != -1) + { + // retrieve the original label order + found_label = Labels[found_label].Index; + } + + // sort labels by the index + std::sort(Labels.begin(), Labels.end(), tTVPWaveLabel::tSortByIndexFuncObj()); + + return found_label; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::FocusLabelAt(int spos, int mode) +{ + int num = SelectLabel(spos, mode); + if(num != -1) + { + TRect rect; + GetLabelNameRect(Labels[num], rect); + EnsureView(Labels[num].Position, PixelToSample(rect.right - rect.left)); + FocusedLabel = num; + } +} +//--------------------------------------------------------------------------- +void TWaveView::PushLastClickedPos(int pos) +{ + LastClickedPos[0] = LastClickedPos[1]; + LastClickedPos[1] = pos; +} +//--------------------------------------------------------------------------- +bool TWaveView::GetNearestObjectAt(int x, TObjectInfo & info) +{ + int num = 0; + bool from_or_to = false; + int pos; + + // give priority to currently focused object (link or label) + int prio_order[2]; + if(FFocusedLink != -1) + prio_order[0] = 0, prio_order[1] = 1; + else if(FFocusedLabel != -1) + prio_order[0] = 1, prio_order[1] = 0; + else + prio_order[0] = 0, prio_order[1] = 1; + + + for(int p = 0; p < sizeof(prio_order) / sizeof(prio_order[0]); p++) + { + if(prio_order[p] == 0) + { + pos = GetLinkWaveMarkAt(x, num, from_or_to); + + if(pos != -1) + { + info.Kind = okLink; + info.Num = num; + info.FromOrTo = from_or_to; + info.Position = pos; + return true; + } + } + else if(prio_order[p] == 1) + { + pos = GetLabelWaveMarkAt(x, num); + + if(pos != -1) + { + info.Kind = okLabel; + info.Num = num; + info.Position = pos; + HoveredLink = -1; + return true; + } + } + } + + return false; +} +//--------------------------------------------------------------------------- +int TWaveView::MouseXPosToSamplePos(int x) +{ + int least = SampleToPixel(1); + x += least / 2; + return PixelToSample(x) + FStart; +} +//--------------------------------------------------------------------------- +bool __fastcall TWaveView::DoMouseWheel(Classes::TShiftState Shift, int WheelDelta, + const Windows::TPoint &MousePos) +{ + WheelDelta /= 120; // is 120 minimum unit? + + if(Shift.Contains(ssCtrl)) + { + // zoom up/down + if(WheelDelta > 0) Magnify ++; + else Magnify --; + } + else + { + // scroll + // generate fake TWMHScroll structure and call WMHScroll + TWMHScroll msg; + ZeroMemory(&msg, sizeof(msg)); + msg.ScrollCode = WheelDelta > 0 ? SB_LINELEFT : SB_LINERIGHT; + WMHScroll(msg); + } + + return true; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::CMMouseLeave(TMessage &msg) +{ + MouseLeave(); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::MouseDown(TMouseButton button, TShiftState shift, int x, int y) +{ + if(!FReader || !FReader->ReadDone) return; + + // mouse downed + if(DisableNextMouseDown) + { + DisableNextMouseDown = false; + return; + } + + SetFocus(); + PopupType = ""; + int head_size = GetHeadSize(); + int foot_size = GetFootSize(); + int foot_start = ClientHeight - foot_size; + + LastMouseDownY = y; + LastMouseDownX = x; + + if(button == mbLeft) + { + if(y < head_size) + { + int fl = GetLabelAt(x, y); + if(fl != -1) + { + FocusedLabel = fl; + // generate dragging information + tTVPWaveLabel &label = Labels[fl]; + DraggingObjectInfo.Kind = okLabel; + DraggingObjectInfo.Num = fl; + DraggingObjectInfo.Position = label.Position; + DraggingState = dsMouseDown; + LastMouseDownPosOffset = MouseXPosToSamplePos(x) - DraggingObjectInfo.Position; + if(FOnStopFollowingMarker) FOnStopFollowingMarker(this); + } + } + else if(y < foot_start) + { + TObjectInfo info; + if(GetNearestObjectAt(x, info)) + { + DraggingObjectInfo = info; + DraggingState = dsMouseDown; + LastMouseDownPosOffset = MouseXPosToSamplePos(x) - DraggingObjectInfo.Position; + } + else + { + int pos = MouseXPosToSamplePos(x); + CaretPos = pos; + ShowCaret = true; + PushLastClickedPos(pos); + } + + } + else + { + HoveredLabel = -1; + int fl = GetLinkAt(x, y); + if(fl != -1) + { + FocusedLink = fl; + if(FOnStopFollowingMarker) FOnStopFollowingMarker(this); + } + } + } + else if(button == mbRight) + { + if(y < head_size) + { + int fl = GetLabelAt(x, y); + if(fl != -1) + FocusedLabel = fl; + else + CaretPos = MouseXPosToSamplePos(x); + PopupType = "Label"; + } + else if(y < foot_start) + { + int pos; + TObjectInfo info; + if(GetNearestObjectAt(x, info)) + pos = info.Position; + else + pos = MouseXPosToSamplePos(x); + CaretPos = pos; + ShowCaret = true; + PushLastClickedPos(pos); + PopupType = "Wave"; + } + else + { + HoveredLabel = -1; + int fl = GetLinkAt(x, y); + if(fl != -1) + { + FocusedLink = fl; + } + else + { + int pos = MouseXPosToSamplePos(x); + CaretPos = pos; + PushLastClickedPos(pos); + } + PopupType = "Link"; + } + } + +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::MouseMove(TShiftState shift, int x, int y) +{ + if(!FReader || !FReader->ReadDone) + { + Cursor = crDefault; + return; + } + + // mouse moved + if(DraggingState != dsNone) + { + LastMouseMoveX = x; + + // dragging + if(DraggingState == dsMouseDown) + { + if(LastMouseDownX != x) + { + // dragging started + DraggingState = dsDragging; + if(DraggingObjectInfo.Kind == okLink) + FocusedLink = DraggingObjectInfo.Num; + else if(DraggingObjectInfo.Kind == okLabel) + FocusedLabel = DraggingObjectInfo.Num; + } + } + /* no else here */ + if(DraggingState == dsDragging) + { + // enable double buffering + DoubleBuffered = FDoubleBufferEnabled; + + int pos = MouseXPosToSamplePos(x) - LastMouseDownPosOffset; + if(pos < 0) pos = 0; + if(pos > FReader->NumSamples) pos = FReader->NumSamples; + + // dragging + if(DraggingObjectInfo.Kind == okLink) + { + tTVPWaveLoopLink &link = Links[DraggingObjectInfo.Num]; + + InvalidateLink(DraggingObjectInfo.Num); + if(!DraggingObjectInfo.FromOrTo) + { + // 'from' + link.From = pos; + } + else + { + // 'to' + link.To = pos; + } + NotifyLinkChanged(); + InvalidateLink(DraggingObjectInfo.Num); + CaretPos = pos; // also set the caret position + } + else if(DraggingObjectInfo.Kind == okLabel) + { + tTVPWaveLabel &label = Labels[DraggingObjectInfo.Num]; + + InvalidateLabel(DraggingObjectInfo.Num); + label.Position = pos; + NotifyLabelChanged(); + InvalidateLabel(DraggingObjectInfo.Num); + CaretPos = pos; // also set the caret position + } + + // scroll + if(x < 10 || x >= ClientWidth - 10) + DragScrollTimer->Enabled = true; + else + DragScrollTimer->Enabled = false; + } + } + else + { + int head_size = GetHeadSize(); + int foot_size = GetFootSize(); + int foot_start = ClientHeight - foot_size; + + if(y < head_size) + { + HoveredLink = -1; + HoveredLabel = GetLabelAt(x, y); + Cursor = crArrow; + } + else if(y < foot_start) + { + TObjectInfo info; + if(GetNearestObjectAt(x, info)) + { + if(info.Kind == okLink) + { + HoveredLabel = -1; + HoveredLink = info.Num; + Cursor = crSizeWE; + } + else if(info.Kind == okLabel) + { + HoveredLink = -1; + HoveredLabel = info.Num; + Cursor = crSizeWE; + } + } + else + { + HoveredLink = -1; + HoveredLabel = -1; + Cursor = crIBeam; + } + } + else + { + HoveredLabel = -1; + HoveredLink = GetLinkAt(x, y); + Cursor = crArrow; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::MouseUp(TMouseButton button, TShiftState shift, int x, int y) +{ + // mouse up + if(!FReader || !FReader->ReadDone) + { + return; + } + + if(DraggingState != dsNone) + { + if(DraggingState == dsMouseDown) + { + // set caret to current from or to position + if(DraggingObjectInfo.Kind == okLink) + { + CaretPos = DraggingObjectInfo.Position; + ShowCaret = true; + PushLastClickedPos(DraggingObjectInfo.Position); + } + else if(DraggingObjectInfo.Kind == okLabel) + { + if(y >= GetHeadSize()) + { + CaretPos = DraggingObjectInfo.Position; + ShowCaret = true; + PushLastClickedPos(DraggingObjectInfo.Position); + } + } + } + else + { + // commit current state + PushUndo(); //==== push undo + } + DraggingState = dsNone; + DragScrollTimer->Enabled = false; + } + else + { + PopupType = ""; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DblClick(void) +{ + // on double click + if(!FReader || !FReader->ReadDone) + { + return; + } + + int head_size = GetHeadSize(); + int foot_size = GetFootSize(); + int foot_start = ClientHeight - foot_size; + + if(LastMouseDownY < head_size) + { + // label + if(FOnLabelDoubleClick) + { + int labelnum = GetLabelAt(LastMouseDownX, LastMouseDownY); + if(labelnum != -1) + { + // cancel dragging + DraggingState = dsNone; + DragScrollTimer->Enabled = false; + + // call double click handler + FOnLabelDoubleClick(this, labelnum, Labels[labelnum]); + + DisableNextMouseDown = true; // to avoid dragging + } + } + } + else if(LastMouseDownY < foot_start) + { + // wave + if(FOnWaveDoubleClick) + { + int pos = MouseXPosToSamplePos(LastMouseDownX); + if(pos >= 0 && pos < FReader->NumSamples) + { + FOnWaveDoubleClick(this, pos); + } + } + } + else + { + // link + if(FOnLinkDoubleClick) + { + int linknum = GetLinkAt(LastMouseDownX, LastMouseDownY); + if(linknum != -1) + FOnLinkDoubleClick(this, linknum, Links[linknum]); + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::DoContextPopup(const Windows::TPoint & MousePos, bool &Handled) +{ + if(FOnNotifyPopup) + { + TPoint mpos = MousePos; + if(mpos.x == -1 && mpos.y == -1) + { + // point not specified; decide popup point + if(FocusedLabel != -1) + { + mpos.x = SampleToPixel(Labels[FocusedLabel].Position - FStart); + mpos.y = GetHeadSize(); + } + else if(FocusedLink != -1) + { + int f = SampleToPixel(Links[FocusedLink].From - FStart); + int t = SampleToPixel(Links[FocusedLink].To - FStart); + if(f >= 0 && f <= ClientWidth) + mpos.x = f; + else if(t >= 0 && t <= ClientWidth) + mpos.x = t; + else + { + if(f >= ClientWidth) + mpos.x = ClientWidth; + else + mpos.x = 0; + } + int y_start = ClientHeight - GetFootSize(); + int y = y_start + + Links[FocusedLink].LinkTier * TVP_LGD_TIER_HEIGHT + + TVP_LGD_TIER_HEIGHT - 3; + mpos.y = y + 3; + } + else if(ShowCaret) + { + mpos.x = SampleToPixel(CaretPos - FStart); + mpos.y = ClientHeight - GetFootSize(); + } + } + mpos = ClientToScreen(mpos); + + if(PopupType != "") + { + // popup by mouse + FOnNotifyPopup(this, PopupType, mpos); + } + else + { + // popup by the kerboard + // decide popup type by currently focused item + if(FocusedLabel != -1) + PopupType = "Label"; + else if(FocusedLink != -1) + PopupType = "Link"; + else if(ShowCaret) + PopupType = "Wave"; + FOnNotifyPopup(this, PopupType, mpos); + PopupType = ""; + } + } + + Handled = true; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::PerformLinkDoubleClick() +{ + if(FocusedLink != -1) + { + FOnLinkDoubleClick(this, FocusedLink, Links[FocusedLink]); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::PerformLabelDoubleClick() +{ + if(FocusedLabel != -1) + { + FOnLabelDoubleClick(this, FocusedLabel, Labels[FocusedLabel]); + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::MouseLeave() +{ + // mouse leaved + HoveredLink = -1; +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::OnDragScrollTimer(TObject * sender) +{ + TWMHScroll wmscroll; + ZeroMemory(&wmscroll, sizeof(TWMHScroll)); + wmscroll.ScrollCode = LastMouseMoveX > ClientWidth / 2 ? SB_LINERIGHT : SB_LINELEFT; + WMHScroll(wmscroll); +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::CMWantSpecialKey(TCMWantSpecialKey &message) +{ + switch(message.CharCode) + { + case VK_UP: + case VK_DOWN: + case VK_LEFT: + case VK_RIGHT: + if(FOnStopFollowingMarker) FOnStopFollowingMarker(this); + message.Result = 1; + break; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveView::KeyDown(Word &Key, Classes::TShiftState Shift) +{ + if(!FReader || !FReader->ReadDone) + { + return; + } + + // key action is to be changed by which item is currently focused + if(FocusedLabel != -1) + { + // currently the label is focued + if(Key == VK_LEFT) + { + // select left label + FocusLabelAt(Labels[FocusedLabel].Position, -1); + } + else if(Key == VK_RIGHT) + { + // select right label + FocusLabelAt(Labels[FocusedLabel].Position, 1); + } + else if(Key == VK_DOWN) + { + // show caret + CaretPos = Labels[FocusedLabel].Position; + ShowCaret = true; + } + else if(Key == VK_RETURN) + { + // enter key pressed + PerformLabelDoubleClick(); + } + } + else if(FocusedLink != -1) + { + // currently the link is focused + // mode = 0 : nearest link + // mode = 1 : upper link + // mode = 2 : lower link + // mode = 3 : left link + // mode = 4 : right link + if(Key == VK_LEFT) + { + // select left link + FocusLinkAt(Links[FocusedLink].LinkTier, + (Links[FocusedLink].From + Links[FocusedLink].To)/2, 3); + } + else if(Key == VK_RIGHT) + { + // select right link + FocusLinkAt(Links[FocusedLink].LinkTier, + (Links[FocusedLink].From + Links[FocusedLink].To)/2, 4); + } + else if(Key == VK_UP) + { + // select upper tier or wave view + if(Links[FocusedLink].LinkTier == 0) + { + CaretPos = (Links[FocusedLink].From + Links[FocusedLink].To)/2; + EnsureView(CaretPos); + ShowCaret = true; + } + else + { + FocusLinkAt(Links[FocusedLink].LinkTier, + (Links[FocusedLink].From + Links[FocusedLink].To)/2, 1); + } + } + else if(Key == VK_DOWN) + { + // select lower tier + FocusLinkAt(Links[FocusedLink].LinkTier, + (Links[FocusedLink].From + Links[FocusedLink].To)/2, 2); + } + else if(Key == VK_RETURN) + { + // enter key pressed + PerformLinkDoubleClick(); + } + } + else/* if(ShowCaret) */ + { + // no item is selected or currently the caret is showing + ShowCaret = true; + if(Key == VK_LEFT) + { + // move the caret left + int xstep = FMagnify <= 0 ? 1 : (1<= FReader->NumSamples) cp = FReader->NumSamples - 1; + cp = PixelToSample(SampleToPixel(cp)); + EnsureView(cp); + CaretPos = cp; + } + else if(Key == VK_UP) + { + // select label + FocusLabelAt(CaretPos, 0); + } + else if(Key == VK_DOWN) + { + // select link + FocusLinkAt(0, CaretPos, 0); + } + } +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/looptuner2/WaveView.h b/tools/win32/krdevui/looptuner2/WaveView.h new file mode 100644 index 0000000..0f36067 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveView.h @@ -0,0 +1,371 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef WaveViewH +#define WaveViewH + +#include "WaveLoopManager.h" + +#include +#include +//--------------------------------------------------------------------------- +#define TVP_LGD_TIER_HEIGHT 12 +//--------------------------------------------------------------------------- +struct TTierMinMaxInfo +{ + // structure for bring back infomration from GetLinkMinMaxPixel + int FromMin; + int FromMax; + int LinkMin; + int LinkMax; + int ToMin; + int ToMax; +}; +//--------------------------------------------------------------------------- +class TWaveReader; +//--------------------------------------------------------------------------- +typedef void __fastcall (__closure *TCaretStateChanged)(TObject *Sender, int caretpos, bool showcaret); +typedef TCaretStateChanged TMarkerStateChanged; +typedef void __fastcall (__closure *TWaveViewRangeChanged)(TObject *Sender, int viewstart, int viewlength); +typedef void __fastcall (__closure *TNotifyWavePosEvent)(TObject *Sender, int pos); +typedef void __fastcall (__closure *TNotifyPopupEvent)(TObject *Sender, AnsiString where, const TPoint & pos); +typedef void __fastcall (__closure *TShowCaretEvent)(TObject *Sender, int pos); +typedef void __fastcall (__closure *TLinkSelectedEvent)(TObject *Sender, int num, tTVPWaveLoopLink &link); +typedef void __fastcall (__closure *TLabelSelectedEvent)(TObject *Sender, int num, tTVPWaveLabel &label); +//--------------------------------------------------------------------------- +class TWaveView : public TCustomControl +{ + typedef TCustomControl inherited; + +//-- constructor and destructor +public: + __fastcall TWaveView(Classes::TComponent* AOwner); + __fastcall ~TWaveView(); + + void __fastcall ClearAll(); + +//-- common stuff +private: + TWaveReader * FReader; + int GetHeadSize() const { return FShowRuler ? (FMinRulerMajorHeight + 1) : 0; } + int GetFootSize() const { return FShowLinks ? (FLinkTierCount * TVP_LGD_TIER_HEIGHT + TVP_LGD_TIER_HEIGHT / 2) : 0; } + void __fastcall Paint(void); + void __fastcall SetReader(TWaveReader * reader); + +public: + void __fastcall ResetAll(); + + __property TWaveReader * Reader = { read = FReader, write = SetReader }; + + +//-- editing support +private: + TNotifyPopupEvent FOnNotifyPopup; + TShowCaretEvent FOnShowCaret; + TLinkSelectedEvent FOnLinkSelected; + TLabelSelectedEvent FOnLabelSelected; + TNotifyEvent FOnSelectionLost; + TNotifyEvent FOnLinkModified; + bool FInOnLinkModified; // to prevent re-entrering + TNotifyEvent FOnLabelModified; + bool FInOnLabelModified; // to prevent re-entrering + bool FModified; + + struct tHistoryInfo + { + std::vector Links; + std::vector Labels; + }; + std::deque FUndoStack; + unsigned int FUndoLevel; + +public: + void __fastcall EraseRedo(); + void __fastcall PushUndo(); + void __fastcall PushFirstUndoState(); + + void __fastcall Undo(); + void __fastcall Redo(); + bool __fastcall CanUndo() const; + bool __fastcall CanRedo() const; + + void __fastcall DeleteItem(); + bool __fastcall CanDeleteItem() const; + void __fastcall ClearAllLabels(); + + __property TNotifyPopupEvent OnNotifyPopup = + { read = FOnNotifyPopup, write = FOnNotifyPopup }; + + __property TShowCaretEvent OnShowCaret = + { read = FOnShowCaret, write = FOnShowCaret }; + + __property TLinkSelectedEvent OnLinkSelected = + { read = FOnLinkSelected, write = FOnLinkSelected }; + + __property TLabelSelectedEvent OnLabelSelected = + { read = FOnLabelSelected, write = FOnLabelSelected }; + + __property TNotifyEvent OnSelectionLost = + { read = FOnSelectionLost, write = FOnSelectionLost }; + + __property TNotifyEvent OnLinkModified = + { read = FOnLinkModified, write = FOnLinkModified }; + + __property TNotifyEvent OnLabelModified = + { read = FOnLabelModified, write = FOnLabelModified }; + + __property bool Modified = + { read = FModified, write = FModified }; + + +//-- view control +private: + int FMagnify; // magnification level (in logarithm based 2) + int FStart; // start sample position at left edge of the client + bool FDoubleBufferEnabled; + bool FFollowingMarker; + bool FWaitingMarker; + int FMarkerPos; // marker position for current playing position, -1 for invisible + int __fastcall PixelToSample(int pixel); + int __fastcall SampleToPixel(int sample); + TNotifyEvent FOnStopFollowingMarker; + TMarkerStateChanged FOnMarkerStateChanged; + TWaveViewRangeChanged FOnRangeChanged; + + DWORD FSoftCenteringStartTick; + int FSoftCenteringPos; + + void __fastcall CreateParams(TCreateParams ¶ms); + DYNAMIC void __fastcall Resize(); + void __fastcall SetScrollBarRange(); + +public: + void __fastcall SetView(int n, int r = 50); + +private: +BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER(WM_HSCROLL , TWMHScroll , WMHScroll) + VCL_MESSAGE_HANDLER(CM_MOUSELEAVE , TMessage , CMMouseLeave) + VCL_MESSAGE_HANDLER(CM_WANTSPECIALKEY , TCMWantSpecialKey, CMWantSpecialKey) + VCL_MESSAGE_HANDLER(WM_SETFOCUS , TWMSetFocus , WMSetFocus) + VCL_MESSAGE_HANDLER(WM_KILLFOCUS , TWMKillFocus , WMKillFocus) +END_MESSAGE_MAP(TCustomControl) + void __fastcall WMHScroll(TWMHScroll &msg); + void __fastcall WMSetFocus(TWMSetFocus &msg); + void __fastcall WMKillFocus(TWMKillFocus &msg); + void __fastcall SetMarkerPos(int p); + void __fastcall SetFollowingMarker(bool b); +public: + void __fastcall ResetMarkerFollow(); +private: + void __fastcall FireRangeChanged(); + void __fastcall SetStart(int n); + void __fastcall SetMagnify(int m); + +public: + void __fastcall SetInitialMagnify(); + AnsiString __fastcall GetMagnifyString(); + void __fastcall EnsureView(int p, int length = 0); + +public: + void __fastcall GetPositionStringAt(int vx, int vy, AnsiString &pos, AnsiString &channel); + + __property int Start = { read = FStart, write = SetStart }; + __property int Magnify = { read = FMagnify, write = SetMagnify }; + __property bool FollowingMarker = + { read = FFollowingMarker, write = SetFollowingMarker }; + __property TNotifyEvent OnStopFollowingMarker = + { read = FOnStopFollowingMarker, write = FOnStopFollowingMarker }; + __property int MarkerPos = { read = FMarkerPos, write = SetMarkerPos }; + __property TWaveViewRangeChanged OnRangeChanged = + { read = FOnRangeChanged, write = FOnRangeChanged }; + __property TMarkerStateChanged OnMarkerStateChanged = + { read = FOnMarkerStateChanged, write = FOnMarkerStateChanged }; + +//-- caret drawing stuff + int FCaretPos; // caret position + bool FShowCaret; + bool FCaretVisiblePhase; + TTimer * FBlinkTimer; + TCaretStateChanged FOnCaretStateChanged; + + void __fastcall InvalidateCaret(int pos); + + void __fastcall SetCaretPos(int pos); + void __fastcall SetShowCaret(bool b); + + void __fastcall OnBlinkTimer(TObject * sender); + void __fastcall ResetCaretFocusState(); + + void __fastcall DrawCaret(); + + int __fastcall GetAttentionPos(); + +public: + __property int CaretPos = { read = FCaretPos, write = SetCaretPos }; + __property bool ShowCaret = { read = FShowCaret, write = SetShowCaret }; + __property TCaretStateChanged OnCaretStateChanged = + { read = FOnCaretStateChanged, write = FOnCaretStateChanged }; + +//-- wave drawing stuff +private: + int FMinRulerMajorWidth; + int FMinRulerMajorHeight; + int FRulerUnit; // time in msec/10 + bool FShowRuler; // whether to draw time line + +private: + void __fastcall DrawWave(int start, bool clear); + + + + +//-- link drawing stuff +private: + std::vector Links; + bool FShowLinks; + int FLinkTierCount; + int FHoveredLink; // -1 for not hovered + int FFocusedLink; // -1 for not focused + +public: + void __fastcall NotifyLinkChanged(); + void __fastcall SetLinks(const std::vector & links); + const std::vector & GetLinks() const { return Links; } + std::vector & GetLinks() { return Links; } + +private: + void __fastcall DrawLinkArrowAt(int tier, int where); + void __fastcall DrawDirectionArrowAt(int tier, bool dir, int where); + void __fastcall GetLinkMinMaxPixel(const tTVPWaveLoopLink & link, + TTierMinMaxInfo & info); + void __fastcall DrawLinkOf(const tTVPWaveLoopLink & link); + void __fastcall DrawLinks(void); +public: + void __fastcall InvalidateLink(int linknum); +private: + void __fastcall SetHoveredLink(int l); + void __fastcall SetFocusedLink(int l); + bool __fastcall IsLinkAt(int linknum, int x, int y); + int __fastcall GetLinkAt(int x, int y); + int __fastcall IsLinkWaveMarkAt(int x, int linknum, bool &from_or_to); + int __fastcall GetLinkWaveMarkAt(int x, int &linknum, bool &from_or_to); + int __fastcall SelectLink(int tier, int spos, int mode); + void __fastcall FocusLinkAt(int tier, int spos, int mode); + +public: + __property int HoveredLink = { read = FHoveredLink, write = SetHoveredLink }; + __property int FocusedLink = { read = FFocusedLink, write = SetFocusedLink }; + + void __fastcall CreateNewLink(); + +//-- label drawing stuff +private: + std::vector Labels; + bool FShowLabels; + int FHoveredLabel; // -1 for not hovered + int FFocusedLabel; // -1 for not focused + int LabelTextHeight; // label's text height + +public: + void __fastcall NotifyLabelChanged(); + void __fastcall SetLabels(const std::vector & labels); + const std::vector & GetLabels() const { return Labels; } + std::vector & GetLabels() { return Labels; } + +private: + void __fastcall GetLabelNameRect(tTVPWaveLabel & label, TRect & rect); + void __fastcall DrawLabelMarkOf(tTVPWaveLabel & label); + void __fastcall DrawLabelNameOf(tTVPWaveLabel & label); + void __fastcall DrawLabels(); +public: + void __fastcall InvalidateLabel(int labelnum); +private: + void __fastcall SetHoveredLabel(int l); + void __fastcall SetFocusedLabel(int l); + bool __fastcall IsLabelAt(int labelnum, int x, int y); + bool __fastcall IsLabelNameAt(int labelnum, int x, int y); + int __fastcall GetLabelAt(int x, int y); + int __fastcall IsLabelWaveMarkAt(int x, int labelnum); + int __fastcall GetLabelWaveMarkAt(int x, int &labelnum); + int __fastcall SelectLabel(int spos, int mode); + void __fastcall FocusLabelAt(int spos, int mode); + +public: + __property int HoveredLabel = { read = FHoveredLabel, write = SetHoveredLabel }; + __property int FocusedLabel = { read = FFocusedLabel, write = SetFocusedLabel }; + + void __fastcall CreateNewLabel(int pos = -1); + +//-- mouse input +private: + TNotifyWavePosEvent FOnWaveDoubleClick; + TLinkSelectedEvent FOnLinkDoubleClick; + TLabelSelectedEvent FOnLabelDoubleClick; + + enum TObjectKind { okLink, okLabel }; + enum TDraggingState { dsNone, dsMouseDown, dsDragging }; + + struct TObjectInfo + { + TObjectKind Kind; // object kind + int Num; // object number + bool FromOrTo; // 'from' or 'to' (for link only) + int Position; // object position + }; + + TTimer * DragScrollTimer; + int LastMouseDownX; + int LastMouseDownY; + int LastMouseDownPosOffset; + int LastMouseMoveX; + AnsiString PopupType; + + bool DisableNextMouseDown; + + int LastClickedPos[2]; // last clicked two positions; only used for new link creation + + TObjectInfo DraggingObjectInfo; + TDraggingState DraggingState; + + void PushLastClickedPos(int pos); + + bool GetNearestObjectAt(int x, TObjectInfo & info); + int MouseXPosToSamplePos(int x); + + DYNAMIC bool __fastcall DoMouseWheel(Classes::TShiftState Shift, int WheelDelta, + const Windows::TPoint &MousePos); + void __fastcall CMMouseLeave(TMessage &msg); + DYNAMIC void __fastcall MouseDown(TMouseButton button, TShiftState shift, int x, int y); + DYNAMIC void __fastcall MouseMove(TShiftState shift, int x, int y); + DYNAMIC void __fastcall MouseUp(TMouseButton button, TShiftState shift, int x, int y); + DYNAMIC void __fastcall DblClick(void); + DYNAMIC void __fastcall DoContextPopup(const Windows::TPoint & MousePos, bool &Handled); + +public: + void __fastcall PerformLinkDoubleClick(); + void __fastcall PerformLabelDoubleClick(); +private: + void __fastcall MouseLeave(); + void __fastcall OnDragScrollTimer(TObject * sender); + +public: + __property TNotifyWavePosEvent OnWaveDoubleClick = { read = FOnWaveDoubleClick, write = FOnWaveDoubleClick }; + __property TLinkSelectedEvent OnLinkDoubleClick = { read = FOnLinkDoubleClick, write = FOnLinkDoubleClick }; + __property TLabelSelectedEvent OnLabelDoubleClick = { read = FOnLabelDoubleClick, write = FOnLabelDoubleClick }; + + __property PopupMenu; + +//-- keyboad input + void __fastcall CMWantSpecialKey(TCMWantSpecialKey &message); + DYNAMIC void __fastcall KeyDown(Word &Key, Classes::TShiftState Shift); + +}; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/looptuner2/WaveWriterUnit.cpp b/tools/win32/krdevui/looptuner2/WaveWriterUnit.cpp new file mode 100644 index 0000000..845ecca --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveWriterUnit.cpp @@ -0,0 +1,172 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include +#include "WaveReaderUnit.h" + +#include "WaveWriterUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TWaveWriterForm *WaveWriterForm; +//--------------------------------------------------------------------------- +__fastcall TWaveWriterForm::TWaveWriterForm(TComponent* Owner) + : TForm(Owner) +{ + CloseLock = false; +} +//--------------------------------------------------------------------------- +#define ONE_SIZE 65536 +void __fastcall TWaveWriterForm::WriteWaveData(TWaveReader *reader, int start, int length, + AnsiString filename) +{ + UserBreak = false; + CloseLock = true; + Label->Caption = ExtractFileName(filename) +" に出力中 ..."; + TStream *out; + + try + { + out = new TFileStream(filename, fmCreate|fmShareDenyWrite); + } + catch(Exception &e) + { + MessageDlg("出力ファイルに書き込むことができません", mtError, + TMsgDlgButtons() << mbOK, 0); + CloseLock = false; + ModalResult = mrCancel; + return; + } + + + // ヘッダを書く + try + { + DWORD size; + out->Write("RIFF", 4); + size = length * reader->Channels * 2 + 44; // 44= ヘッダサイズ + out->Write(&size, 4); + out->Write("WAVEfmt \x10\x00\x00\x00", 12); // WAVEfmt + WAVEFORMATEX wfe; + wfe.wFormatTag = (WORD)WAVE_FORMAT_PCM; + wfe.nChannels = (WORD)reader->Channels; + wfe.nSamplesPerSec = reader->Frequency; + wfe.nAvgBytesPerSec = reader->Frequency * reader->Channels * 2; + wfe.nBlockAlign = (WORD)reader->Channels * 2; + wfe.wBitsPerSample = (WORD)reader->BitsPerSample; + wfe.cbSize = 0; // ただし、このメンバは記録されない + + out->Write(&wfe, 16); + + out->Write("data", 4); + size = length * reader->Channels * 2; + out->Write(&size, 4); + + + int total = length; + int current = 0; + + while(length) + { + ProgressBar->Position = (__int64)current *50L / (__int64)total; + + Application->ProcessMessages(); + if(UserBreak) + { + delete out; + DeleteFile(filename); + CloseLock = false; + ModalResult = mrCancel; + return; + } + + int onesize = ONE_SIZE > length ? length : ONE_SIZE; + short int *buf = new short int [onesize * reader->Channels ]; + + reader->GetData(buf, start, onesize); + + if(onesize > out->Write(buf, onesize * reader->Channels * 2)) + { + MessageDlg("出力ファイルに書き込むことができません", mtError, + TMsgDlgButtons() << mbOK, 0); + delete [] buf; + delete out; + DeleteFile(filename); + CloseLock = false; + ModalResult = mrCancel; + return; + } + + delete [] buf; + start += onesize; + current += onesize; + length -= onesize; + + } + + delete out; + CloseLock = false; + ModalResult = mrOk; + return; + } + catch(...) + { + MessageDlg("ファイル出力中にエラーが発生しました", mtError, + TMsgDlgButtons() << mbOK, 0); + CloseLock = false; + ModalResult = mrCancel; + return; + } +} +//--------------------------------------------------------------------------- +void __fastcall TWaveWriterForm::CancelButtonClick(TObject *Sender) +{ + UserBreak = true; +} +//--------------------------------------------------------------------------- + +void __fastcall TWaveWriterForm::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + if(CloseLock) + { + UserBreak = true; + CanClose = false; + } + else + { + CanClose = true; + } +} +//--------------------------------------------------------------------------- + +void __fastcall TWaveWriterForm::FormClose(TObject *Sender, + TCloseAction &Action) +{ + Action = caFree; // 自動的に解放されるので、呼び出し側での解放は不要 +} +//--------------------------------------------------------------------------- + +void __fastcall TWaveWriterForm::TimerTimer(TObject *Sender) +{ + Timer->Enabled = false; + CancelButton->Enabled = true; + WriteWaveData(WaveReader, Start, Length, FileName); +} +//--------------------------------------------------------------------------- + +void __fastcall TWaveWriterForm::FormDestroy(TObject *Sender) +{ + // +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/looptuner2/WaveWriterUnit.dfm b/tools/win32/krdevui/looptuner2/WaveWriterUnit.dfm new file mode 100644 index 0000000..ed89c56 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveWriterUnit.dfm @@ -0,0 +1,55 @@ +object WaveWriterForm: TWaveWriterForm + Left = 125 + Top = 96 + BorderIcons = [] + BorderStyle = bsSingle + Caption = '出力中 ...' + ClientHeight = 82 + ClientWidth = 418 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poMainFormCenter + OnClose = FormClose + OnCloseQuery = FormCloseQuery + OnDestroy = FormDestroy + PixelsPerInch = 96 + TextHeight = 12 + object Label: TLabel + Left = 16 + Top = 8 + Width = 36 + Height = 12 + Caption = ' ' + end + object ProgressBar: TProgressBar + Left = 16 + Top = 24 + Width = 385 + Height = 17 + Min = 0 + Max = 50 + TabOrder = 0 + end + object CancelButton: TButton + Left = 171 + Top = 48 + Width = 75 + Height = 25 + Cancel = True + Caption = 'キャンセル' + Enabled = False + TabOrder = 1 + OnClick = CancelButtonClick + end + object Timer: TTimer + Interval = 200 + OnTimer = TimerTimer + Left = 320 + Top = 48 + end +end diff --git a/tools/win32/krdevui/looptuner2/WaveWriterUnit.h b/tools/win32/krdevui/looptuner2/WaveWriterUnit.h new file mode 100644 index 0000000..e045a9e --- /dev/null +++ b/tools/win32/krdevui/looptuner2/WaveWriterUnit.h @@ -0,0 +1,51 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#ifndef WaveWriterUnitH +#define WaveWriterUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TWaveReader; +class TWaveWriterForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TProgressBar *ProgressBar; + TButton *CancelButton; + TLabel *Label; + TTimer *Timer; + void __fastcall CancelButtonClick(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall FormClose(TObject *Sender, TCloseAction &Action); + void __fastcall TimerTimer(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); +private: // ユーザー宣言 + bool CloseLock; + bool UserBreak; + void __fastcall WriteWaveData(TWaveReader *reader, int start, int length, + AnsiString filename); + + +public: // ユーザー宣言 + TWaveReader * WaveReader; + int Start; + int Length; + AnsiString FileName; + __fastcall TWaveWriterForm(TComponent* Owner); + +}; +//--------------------------------------------------------------------------- +extern PACKAGE TWaveWriterForm *WaveWriterForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/looptuner2/help/Find.html b/tools/win32/krdevui/looptuner2/help/Find.html new file mode 100644 index 0000000..4e4bb8a --- /dev/null +++ b/tools/win32/krdevui/looptuner2/help/Find.html @@ -0,0 +1,74 @@ + + + +Loop Tuner リファレンス - 継ぎ目を探す + + +
+
■ サウンドを読み込む ■
+
+
+ ループチューナを起動し、「ファイル(F)|開く(O)...」で対象のサウンドを指定すると開くことができます。大きなファイルを指定した場合は時間が掛かる場合があります。
+ 開くとそのサウンドの波形が表示されます。
+
+
+
+サウンドを開いた 之 図 +
+
+
+
+
■ ループ領域を指定する ■
+
+
+ サウンドを開けば、ループする部分 ( ループ領域 ) を指定することができます。波形が表示されている上でドラッグをするとその部分が選択されますが、そこがループ領域となります。
+ ループ領域の開始点、あるいは終了点付近ではマウスカールが変わり、ドラッグすると開始点あるいは終了点の微調整を行うことができます。
+
+ 波形上でダブルクリックをするとその部分から再生されますので、それを頼りにループ領域を指定してください。
+ 最初はおおざっぱに指定して、あとからループの開始点と終了点を拡大して徐々に調整していくのが良いでしょう。ループの継ぎ目部分を再生したいときは、メニューから「再生(P)|ループ部分を再生(R)」(Rキー)を選択すると、継ぎ目の部分を再生することができます。
+
+
+
+おおざっぱに指定する 之 図 +
+
+
+
+より細かく指定する 之 図 ( ループ終了点付近 ) +
+
+
+
+ 指定が悪いと、ループ部分でプチというノイズが入る場合があります。
+ BGM の継ぎ目を探す場合、スネアあるいはシンバル系のドラムの直前をループの継ぎ目にするとノイズが目立ちません。高い音、破裂音などの直前も好都合です。下図のループの終了点までの部分 ( 緑色の部分 ) に比べると、終了点以後の部分のほうがギザギザが目立つ ( 高音が多い ) ようになってますが、こういう所も好都合です。
+
+ また、よりシビアな状況では、倍率 1/1 ( 一番高倍率 ) にてサンプル単位で調整する必要がある場合があります。この場合は、通常、波形が 0 位置と交差する位置 ( クロッシング・ポイント ) をループ開始点とループ終了点で指定するとすこしはノイズが目立たなくなる場合が多いです ( 下図の選択領域と非選択領域の境界がクロッシング・ポイントです )。
+
+
+
+サンプル単位で指定する 之 図 ( ループ終了点付近 ) +
+
+
+ 編集にはキーボードのショートカットを使用すると便利です。
+ このほか、継ぎ目の指定にはいくつかのテクニック(?)があります。
+
+
+
+
■ 保存する ■
+
+
+ メニューから「ファイル(F)|保存(S)」を選択すると、ループの情報が保存されます。保存されるのは、編集中のサウンドのファイル名に ".sli" を付加したファイル名で ( 拡張子が .sli に変わったファイル、というわけではありません )、編集中のサウンドと同じディレクトリに保存されます。吉里吉里はサウンドを再生するときにこの .sli ファイルを見つけると、ループ情報ファイルとしてループ再生をするときに利用します。
+
+ もし、ループ領域の後の「再生されない部分」があまりにも長い場合は、削除してもかまいませんが、もし圧縮形式を使っている場合は、エンコード前のデータにて再生されない部分を切り落とし、エンコードし直してください。このとき、ループ終了点ぴったりで切り落とさずに、0.5 秒ぐらいの余裕をもって切り落としてください。そうでないと再びエンコードしたときに終了点付近の音質や位置がずれる場合があります ( とくに Ogg Vorbis )。
+
+
+
+
目次に戻る
+
+
+ + + + + diff --git a/tools/win32/krdevui/looptuner2/help/Form.html b/tools/win32/krdevui/looptuner2/help/Form.html new file mode 100644 index 0000000..b6da94f --- /dev/null +++ b/tools/win32/krdevui/looptuner2/help/Form.html @@ -0,0 +1,236 @@ + + + +Loop Tuner リファレンス - 画面 + + +
+
■ 画面 ■
+
+
+ 画面の説明です。知りたい部分をクリックしてください。
+
+
+tune1.png +
+ +開く +保存 +元に戻す +開始点に移動 +終了点に移動 +再生 +ループ再生 +ループ部分を再生 +停止 +再生位置に追従 +時間軸拡大 +時間軸縮小 +ファイルメニュー +ループ領域メニュー +再生メニュー +表示メニュー +ヘルプメニュー +全体表示 +波形表示 +スクロールバー +表示率 +カーソル位置 +再生位置 +ループ領域 +ヒント + +
+
+
+
■ 画面の説明 ■
+
+ +
+・全体表示 +
    + サウンドの全体の情報がこの横に細長い部分に表示されます。 [ ] で囲まれた部分が、全体に対して現在表示されている部分、縦線は現在の再生位置です。選択領域も表示されます。クリックすると、そこの位置を表示することができます。
    +
+ +
+・波形表示 +
    + サウンドの波形が表示されます。
    +
    +・ドラッグをするとループ領域を指定することができます
    +・ダブルクリックをするとその位置から再生することができます
    +・右クリックをするとコンテキストメニューが表示されます
    +・既に選択されているループ領域の開始点と終了点付近では、ドラッグによってループ領域の微調整を行うことができます。
    +
+ +
+・スクロールバー +
    + 表示領域をスクロールすることができます。
    +
+ +
+・表示率表示 +
    + 現在表示中の表示率を表示します。1/1024 と表示されている場合は、画面上の 1 pixel が 1024 サンプルに相当することを示しています。 +
+ +
+・カーソル位置 +
+
    + マウスカーソルのある場所の位置を表示します。 +
+ +
+・再生位置 +
    + 再生中の位置を表示します。 +
+ +
+・ループ領域 +
    + ループ領域を表示します。 +
+ +
+・ヒント +
    + マウスカーソルのある位置のボタンやメニューなどのヒントを表示します。 +
+
+
+
+
+
目次に戻る
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + diff --git a/tools/win32/krdevui/looptuner2/help/Intro.html b/tools/win32/krdevui/looptuner2/help/Intro.html new file mode 100644 index 0000000..69a7a55 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/help/Intro.html @@ -0,0 +1,48 @@ + + +Loop Tuner リファレンス - ループチューナとは + + +
+
■ ループチューナ ■
+
+
+ ループチューナは、PCM をループさせるときのループの継ぎ目を探すツールです。
+ PCM を単にループさせるだけならば、単一の PCM を頭から最後まで繰り返して再生するだけでも良いのですが、たとえばその PCM の頭や最後に無音部分があればループの時に曲がとぎれてしまいますし、曲が導入部分、繰り返し部分に分かれていると、単一の PCM を頭から最後まで繰り返して再生するだけでは、繰り返すときにまた導入部分から再生することになります。
+ ループチューナは、このような場合に、PCM の繰り返し部分をうまく見つけることによって、継ぎ目を感じさせない(シームレスな)ループを作成するために使います。BGM を PCM で再生するときにループさせたいときや、長めの効果音をループさせたいときに効果を発揮すると思います。

+
+ ループチューナは、吉里吉里用に拡張子が .sli のファイルを作成します。吉里吉里はこれを見つけるとループ情報ファイルとして読み込み、PCM をループさせるときに利用します。
+ .sli ファイルの書式は単純ですので、ほかのプログラムにも流用できるかと思います。
+
+ なお、ループチューナは外見は Wave 編集ソフトによくにていますが、Wave 編集ソフトではありません。Wave を編集する場合は、市販あるいはオンラインの Wave 編集ソフトを別に用意してください ( というわけで 編集機能をつけてくれ、という要望も勘弁してください(汗) )。
+
+
+
+
■ 原理 ■
+
+
+ 原理と言うほどの物でもないです(^^; +
+ ループチューナでは、サウンドには「ループまでの部分」と「ループする部分」(ループ領域)があると考えます ( 正確には「再生されない余分な部分」もありますが )。
+
+ サウンドは、まず「ループまでの部分」が普通に再生されます。次に、「ループする部分」もそのまま再生されます。そして「ループする部分」の最後にきたとき、次は「ループする部分」の最初に再生位置が移り、あとはそのままループ部分を繰り返し再生します。
+
+
+
+ループの概念 之 図 +
+
+ ループチューナは、この「ループする」部分を、サウンドの中から選択することによってループを指定します。ループまでの部分が無くて、サウンドの先頭からループが開始されてもかまいません。
+ ループ終了点に達するとすぐにループ開始点に来ますので、シームレスなループを作る場合はこのループ開始点とループ終了点の間につなぎ目を感じさせないような位置を探して指定しなければなりません。場合によっては PCM の 1 サンプル単位で厳密に調整しないとループ位置でノイズが入る、などということもあり得ます。
+
+ ループさせるための BGM などを作る場合も、ループされることを考慮して作らないとなりません(^^;
+
+
+
+
+
目次に戻る
+
+
+ + + diff --git a/tools/win32/krdevui/looptuner2/help/Menus.html b/tools/win32/krdevui/looptuner2/help/Menus.html new file mode 100644 index 0000000..4f01b01 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/help/Menus.html @@ -0,0 +1,345 @@ + + + +Loop Tuner リファレンス - メニュー + + + +
+
■ ファイル(F) ■
+
+ +
+・開く(O) ... +
    + 対象のサウンドを開きます。サウンドを指定してください。
    +
+ +
+・保存する(S) ... ( ショートカットキー : Ctrl + S ) +
    + 現在の対象のサウンドのループ情報を保存します ( 対象のサウンドを保存する訳ではありません )。ループ情報は、対象のサウンドのファイル名に ".sli" を付加したファイルで、対象のサウンドと同じディレクトリに保存されます。
    +
+ +
+・閉じる(C) +
    + 現在の対象のサウンドを閉じます。 +
+ +
+・ループまでを .wav 出力(P) +
    + ループまでの部分を .wave ( RIFF 無圧縮 WAVE ) としてファイルに出力します。入力ファイルが 16bit 精度以外であっても 16bit 精度の物が出力されますので注意してください。 +
+ +
+・ループ部分を .wav 出力(L) +
    + ループの部分を .wave ( RIFF 無圧縮 WAVE ) としてファイルに出力します。入力ファイルが 16bit 精度以外であっても 16bit 精度の物が出力されますので注意してください。 +
+ +
+・全体を .wav 出力(E) +
    + サウンドの全体を .wave ( RIFF 無圧縮 WAVE ) としてファイルに出力します。入力ファイルが 16bit 精度以外であっても 16bit 精度の物が出力されますので注意してください。 +
+ +
+・終了(X) +
    + アプリケーションを終了します。 +
+
+ +
+
+
■ ループ領域(R) ■
+
+ +
+・元に戻す(U) ( ショートカットキー : Ctrl + Z ) +
    + ループ領域を直前の状態に戻します。 +
+ +
+・やり直し(R) ( ショートカットキー : Ctrl + Shift + Z ) +
    + 「元に戻す」で戻したループ領域を、また「元に戻す」前の状態に戻します。 +
+ +
+・開始点に移動(B) ( ショートカットキー : B ) +
    + ループ領域の開始点に移動します。高倍率で作業をしているときに便利です。 +
+ +
+・終了点に移動(N) ( ショートカットキー : N ) +
    + ループ領域の終了点に移動します。高倍率で作業をしているときに便利です。 +
+ +
+・開始点を左に1サンプル(Z) ( ショートカットキー : Z ) +
    + ループ領域の開始点を左に1サンプル分移動します。 +
+ +
+・開始点を右に1サンプル(X) ( ショートカットキー : X ) +
    + ループ領域の開始点を右に1サンプル分移動します。 +
+ +
+・終了点を左に1サンプル(C) ( ショートカットキー : C ) +
    + ループ領域の終了点を左に1サンプル分移動します。 +
+ +
+・終了点を右に1サンプル(V) ( ショートカットキー : V ) +
    + ループ領域の終了点を右に1サンプル分移動します。 +
+ +
+・解除(F) +
    + ループ領域を解除し、ループ領域が選択されていない状態にします。
    +
+
+ +
+
+
■ 再生(P) ■
+
+ +
+・再生(P) ( ショートカットキー : P ) +
    + サウンドの先頭から、ループをせずに最後まで演奏します。
    +
+ +
+・ループ再生(L) ( ショートカットキー : L ) +
    + サウンドの先頭から再生しますが、ループします。
    +
+ +
+・ループ部分を再生(R) ( ショートカットキー : R ) +
    + ループの終了点の手前 2 秒前 ( 場合によってはループの開始点 ) から再生を開始し、ループの継ぎ目付近を再生します。ループ部分を再生中、あるいはループ再生中は、ループ領域を選択し直すと自動的にこの「ループ部分を再生」になります。
    +
+ +
+・停止(S) ( ショートカットキー : S ) +
    + 再生を停止します。 +
+
+ +
+
+
■ 表示(V) ■
+
+ +
+・再生位置に追従(F) ( ショートカットキー : F ) +
    + このメニュー項目がチェックされている状態では、自動的に現在の再生位置を追従して ( スクロールしながら ) 表示するようになります。
    + 解除すると追従はされなくなります。
    + スクロールバーを操作したとき、右クリックをしたとき、ループ領域を変更したときには自動的に解除されます。
    +
+ +
+・時間軸拡大(I) ( ショートカットキー : I ) +
    + 波形を拡大し、より細かく表示します。 +
+ +
+・時間軸縮小(O) ( ショートカットキー : O ) +
    + 波形を縮小し、よりおおざっぱに表示します。 +
+ +
+・ツールバーを表示する(R) +
    + このメニュー項目がチェックされている状態では、ツールバーを表示します。 +
+ +
+・ステータスバーを表示する(B) +
    + このメニュー項目がチェックされている状態では、ステータスバーを表示します。 +
+ +
+・時間で表示(T) +
    + ステータスバーの再生位置、ループ位置などの位置情報を時間単位で指定します。分:秒.ミリ秒 の形式で表示されます。 +
+ +
+・サンプル数で表示(S) +
    + ステータスバーの再生位置、ループ位置などの位置情報をサンプル数単位で表示します。 +
+
+ +
+
+
■ ヘルプ(H) ■
+
+ +
+・ヘルプ(H) +
    + ヘルプを表示します。 +
+ +
+・バージョン情報(I) +
    + バージョン情報を表示します。 +
+
+
+
+
+
目次に戻る
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + diff --git a/tools/win32/krdevui/looptuner2/help/Prepare.html b/tools/win32/krdevui/looptuner2/help/Prepare.html new file mode 100644 index 0000000..2fe89b9 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/help/Prepare.html @@ -0,0 +1,80 @@ + + + +Loop Tuner リファレンス - 準備 + + +
+
■ 利用可能な形式 ■
+
+
+ ループチューナは、現時点で以下の PCM の形式のファイルを扱うことができます。
+
+・無圧縮 Wave ( 拡張子は .wav ) ただし いくつか制限あり
+・MS-ADPCM ( 拡張子は .wav )
+・TCWF ( 拡張子は .tcw )
+・Ogg Vorbis ( 拡張子は .ogg )
+
+
+ ループ部分が 4 秒未満の小さなものでは、各圧縮形式を用いるよりは無圧縮 Wave を使うことを強く推奨します ( 圧縮形式では再生位置の変更に掛かるオーバーヘッドが大きいので、頻繁に再生位置の変更が発生するのは好ましくない )。
+
+
+
+
■ 読み込み可能な無圧縮 Wave 形式について ■
+
+
+ 以下の形式を読み込むことができます。
+
+・8bit, 16bit, 24bit, 32bit の 普通の整数リニア PCM ( wFormatTag = WAVE_FORMAT_PCM のもの )
+・32bit の浮動小数点数 PCM ( wFormatTag = WAVE_FORMAT_IEEE_FLOAT のもの )
+・wFormatTag = WAVE_FORMAT_EXTENSIBLE の 8 〜 32bit 整数リニア PCM と 32bit 浮動小数点数 PCM
+
+ いずれも、総チャンネル数が 8 チャンネル以下のものに限られます。また、特殊な形式では正常に読み込めない場合もあります。
+
+ ループチューナは、16bit 精度以外のデータを受け取った場合、内部処理の簡略化のため、ファイルの読み込み時に強制的に 16bit に変換してしまいますので注意してください。[ファイル - 全体を wav 出力] でも 16bit 整数リニア PCM が出力されます。
+
+
+
+
■ マルチチャンネルファイルについて ■
+
+
+ スピーカー位置を指定できる wFormatTag = WAVE_FORMAT_EXTENSIBLE の形式のファイルを読み込んだ場合を除き、ループチューナは ファイルに格納されているチャンネル数に応じて以下のように解釈します (OggVorbis も含む)。
+
+・1チャンネルの場合 : モノラル
+・2チャンネルの場合 : ステレオ
+・4チャンネルの場合 : 4チャンネルサラウンド (チャンネルの先頭から順に 前左、前右、後左、後右)
+・6チャンネルの場合 : 5.1チャンネルサラウンド (チャンネルの先頭から順に 前左、前中央、前右、後左、後右、低周波)
+
+ これ以外のチャンネル数の物を読み込んだ場合の動作は不定です。
+
+ Windows 95/98/NT4.0 では、モノラルやステレオ以外のファイル、WAVE_FORMAT_EXTENSIBLE 形式のファイルの再生はサポート外です。
+
+
+
■ プラグイン DLL について ■
+
+
+ Loop Tuner は、Loop Tuner 実行可能ファイル (krkrlt.exe) の置いてあるフォルダの親のフォルダの下にある plugin フォルダ (つまり Loop Tuner の置いてあるフォルダから見れば兄弟の位置にある plugin フォルダ ) からプラグインを探します。これは、(配布時のファイル構成そのままならば) 吉里吉里用のプラグインを参照することになります。実際、Loop Tuner が用いるプラグインは吉里吉里用のPCMデコード系プラグインです。
+ Loop Tuner の置いてあるフォルダ下に plugin というディレクトリを作成し、そこにプラグインを置いても使用することができます。
+
+
+
+
■ 録音する ■
+
+
+ ループチューナでそのサウンドを扱う限り、形式は PCM で無ければなりません。まずは無圧縮 Wave としてサウンドを保存してください。
+ このときに作成する Wave は、繰り返すのに十分な時間分が記録されている必要があります。「再生されない余分な部分」となるべき部分もすこし余裕をもって作成したほうがいいです。
+ サウンドの頭の無音部分の除去、音質の調整などはこの時点で行ってください。
+
+ その後に、もし圧縮形式を用いる場合は、各圧縮形式にエンコードしてください。ただし、このときにはエンコード前の無圧縮 Wave は消さずに取っておくことをお勧めします ( 再生されない余分な部分を後で切り落としたくなるかもしれないからです )。
+
+
+
+
+
目次に戻る
+
+
+ + + + + diff --git a/tools/win32/krdevui/looptuner2/help/hline.png b/tools/win32/krdevui/looptuner2/help/hline.png new file mode 100644 index 0000000000000000000000000000000000000000..bb7cde8fd82c4a89de59002d8e67c50c3ab83680 GIT binary patch literal 123 zcmeAS@N?(olHy`uVBq!ia0y~yU}^xe899IiL-tjN)j-P0)5S5Q;#TsX(;xaD{{R0! zfhT3*CxIjmIkT-(UM-&#yW&yE2JTSZu-y_85|WaVGY+UsX+7oKp;*y!by3H{E`I&p Y43X#0|9^O>MiXSJr>mdKI;Vst0GOREBme*a literal 0 HcmV?d00001 diff --git a/tools/win32/krdevui/looptuner2/help/index.html b/tools/win32/krdevui/looptuner2/help/index.html new file mode 100644 index 0000000..fd0c30c --- /dev/null +++ b/tools/win32/krdevui/looptuner2/help/index.html @@ -0,0 +1,45 @@ + + +Loop Tuner リファレンス + + +
ループ チューナ リファレンス
+
+
+
■ 目次 ■
+
+
+
+ループチューナとは
+
+準備
+
+継ぎ目を探す
+
+
+画面説明
+
+メニュー説明
+
+
+
+
+
■ その他 ■
+
+
+
+ 最新版は以下からダウンロードできます。
+
+ 吉里吉里 ダウンロードページ http://kikyou.info/tvp/
+
+ 質問・意見・バグ報告などは、上記ページか、以下まで・・・
+  W.Dee <dee@kikyou.info>
+
+
+ 使用条件、配布条件は吉里吉里 SDK のそれに準じます。
+
+
+ + + + diff --git a/tools/win32/krdevui/looptuner2/help/loaded.png b/tools/win32/krdevui/looptuner2/help/loaded.png new file mode 100644 index 0000000000000000000000000000000000000000..632fa7b41436f730d10573c3ed12051e8ff7ce32 GIT binary patch literal 8607 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 literal 0 HcmV?d00001 diff --git a/tools/win32/krdevui/looptuner2/help/loop0.png b/tools/win32/krdevui/looptuner2/help/loop0.png new file mode 100644 index 0000000000000000000000000000000000000000..942a985fa32bb388906b93ed3c5b42c0947b82d5 GIT binary patch literal 1077 zcmV-51j_q~P)n(>1?CP69RQUDG88zZ z4h#tK2QX9&hykH2pdeMjpbBL|VWOZkaRd^Ps1k$H=1P6%$6d~Mu`l*ZE>Hm;Vn2WV zvETF0QyhROb)4vzggKEmQR>s&%h+78MJ5NcZR@|`!p_7vNbV+lU>R4{)%Ka3``07s zEen5qr`6kv9J^W$C&PCrq-nx>0I)x{K+_Zp43;mAQdSFn2yA_>X)UQ{Rj~1XoC|YW zFH0?&Cd#@a%j3_R0Bzq*IIi_FyQPd*wD~e+UMQl$cwRz_j7N7z)Ji~M#-~Nh{Ti*AM4UmBz5C*O_xsDDW*`F zv=B+MCt`@JX%G2PTps9BJ(AYr@+91Gs%iKW&Qq`?R6>?AuuBi@5}=X?LpPm;ckWnX z@aF7#95I9Uw;Kx82d}$PlTzzz0aU8IPvcYB4-XqvqzZI-KfZ+mAnd+M{p_(zao|nC zzaDp059f>Pzn7RnGG8ffB&`~yvO;YeC@DS3=OMFuxN4Wy=aLXNu zQzj3;#Dy<Q%B8V7BW>2fe z*M~_)=v|>qvZneKad3?OQqIVfAZMD`Z<|e&*WfS?EfJ zYI88#+5Uazdl6&qNT#i|@+ih6`=Ev18m1J!3yZ4Vsv?a=k4Pr(F!M4jKf`H$Cbw(R vTjJ(ty36^Q54k5UJU??VtdXC|ON7iXvhBv3*|YIz00000NkvXXu0mjfuTS}% literal 0 HcmV?d00001 diff --git a/tools/win32/krdevui/looptuner2/help/tune0.png b/tools/win32/krdevui/looptuner2/help/tune0.png new file mode 100644 index 0000000000000000000000000000000000000000..191c023fccc6a926dc576e80c9c2d7f5eeeaa06f GIT binary patch literal 8037 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 OT`n&JlCG9C4f;Pru$A%v literal 0 HcmV?d00001 diff --git a/tools/win32/krdevui/looptuner2/help/tune1.png b/tools/win32/krdevui/looptuner2/help/tune1.png new file mode 100644 index 0000000000000000000000000000000000000000..8ce6fa7a73ff57cdde6161eaa368d057fe86910a GIT binary patch literal 8648 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 AS^xk5 literal 0 HcmV?d00001 diff --git a/tools/win32/krdevui/looptuner2/looptune.bpr b/tools/win32/krdevui/looptuner2/looptune.bpr new file mode 100644 index 0000000..e9e9752 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/looptune.bpr @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=0 +MajorVer=2 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1041 +CodePage=932 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=2.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[Excluded Packages] +C:\WINDOWS\System32\ibsmp50.bpl=Borland C++ InterBase Alerter Component +$(BCB)\Bin\applet50.bpl=Borland Control Panel Applet Package +$(BCB)\Bin\dcl31w50.bpl=Delphi 1.0 Compatibility Components +$(BCB)\Bin\bcbsmp50.bpl=Borland C++ Sample Components +$(BCB)\Bin\dclqrt50.bpl=QuickReport Components +$(BCB)\Bin\dclbde50.bpl=Borland BDE DB Components +$(BCB)\Bin\dcldb50.bpl=Borland Database Components +$(BCB)\Bin\dcltee50.bpl=TeeChart 5.0 Components +$(BCB)\Bin\dcltqr50.bpl=TeeChart 5.0 for QuickReport Components Design Package +$(BCB)\Bin\dclib50.bpl=InterBase Data Access Components +$(BCB)\Bin\bcbie50.bpl=Borland C++Builder Internet Explorer 5 Components Package +$(BCB)\Bin\dclnet50.bpl=Borland Internet Components +$(BCB)\Bin\DBWEBXPRT.BPL=Borland Web Wizard Package +$(BCB)\Bin\DCLNMF50.bpl=NetMasters Fastnet Tools +$(BCB)\Bin\dclocx50.bpl=Borland Sample Imported ActiveX Controls +$(BCB)\Bin\dclite50.bpl=Borland Integrated Translation Environment +$(BCB)\Bin\bcb2kaxserver50.bpl=Borland C++Builder COM Server Components Sample Package + +[HistoryLists\hlIncludePath] +Count=4 +Item0=..\..\..\..\core\base;..\..\..\..\core\sound\win32;..\..\..\..\core\sound;$(BCB)\include;$(BCB)\include\vcl;..\..\..\..\core\tjs2 +Item1=..\..\..\..\core\base;..\..\..\..\core\sound\win32;..\..\..\..\core\sound;$(BCB)\include;$(BCB)\include\vcl +Item2=$(BCB)\include;$(BCB)\include\vcl +Item3=;;$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=3 +Item0=..\..\..\..\core\base;..\..\..\..\core\sound\win32;..\..\..\..\core\sound;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item1=$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item2=;;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=4 +Item0=TVP_IN_LOOP_TUNER;_DEBUG +Item1=TVP_IN_LOOP_TUNER +Item2=_DEBUG;TVP_IN_LOOP_TUNER +Item3=_DEBUG + +[HistoryLists\hlIntOutputDir] +Count=1 +Item0=..\intermediate + +[HistoryLists\hlFinalOutputDir] +Count=2 +Item0=..\..\..\..\..\bin\win32\tools\ +Item1=..\..\..\..\..\bin\win32\tools + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication= +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + + \ No newline at end of file diff --git a/tools/win32/krdevui/looptuner2/looptune.cpp b/tools/win32/krdevui/looptuner2/looptune.cpp new file mode 100644 index 0000000..3abfea9 --- /dev/null +++ b/tools/win32/krdevui/looptuner2/looptune.cpp @@ -0,0 +1,173 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop +#include +#include "LoopTunerMainUnit.h" +#include "looptune.h" +USERES("looptune.res"); +USEUNIT("WaveReader.cpp"); +USEUNIT("RIFFWaveContext.cpp"); +USEUNIT("TSSWaveContext.cpp"); +USEUNIT("WaveView.cpp"); +USEUNIT("DSound.cpp"); +USEFORM("LoopTunerMainUnit.cpp", TSSLoopTuner2MainForm); +USEFORM("EditLabelAttribUnit.cpp", EditLabelAttribFrame); /* TFrame: File Type */ +USEFORM("EditLinkAttribUnit.cpp", EditLinkAttribFrame); /* TFrame: File Type */ +USEFORM("LinkDetailUnit.cpp", LinkDetailForm); +USEFORM("LabelDetailUnit.cpp", LabelDetailForm); +USEUNIT("..\..\..\..\core\sound\WaveLoopManager.cpp"); +USEUNIT("..\..\..\..\core\sound\win32\tvpsnd.c"); +USEUNIT("..\..\..\..\core\base\CharacterSet.cpp"); +USEUNIT("TotalView.cpp"); +//--------------------------------------------------------------------------- +static bool FindOtherLoopTunerInstanceAndNotify(); +//--------------------------------------------------------------------------- +WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ + try + { + if(!FindOtherLoopTunerInstanceAndNotify()) return 0; + + Application->Initialize(); + Application->Title = "Loop Tuner"; + Application->CreateForm(__classid(TTSSLoopTuner2MainForm), &TSSLoopTuner2MainForm); + Application->Run(); + } + catch (Exception &exception) + { + Application->ShowException(&exception); + } + + CommitAndCloseIniFile(); + return 0; +} +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +// exported 'main' function +//--------------------------------------------------------------------------- +extern "C" int _export PASCAL UIExecLoopTuner(void) +{ + if(FindOtherLoopTunerInstanceAndNotify()) + { + Application->Initialize(); + TTSSLoopTuner2MainForm * form = new TTSSLoopTuner2MainForm(Application); + form->ShowModal(); + CommitAndCloseIniFile(); + } + ExitProcess(0); + return 0; +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// support function for communicating other loop tuner instances +//--------------------------------------------------------------------------- +static bool FindOtherLoopTunerInstanceAndNotify() +{ + HWND wnd = FindWindow("TTSSLoopTuner2MainForm", NULL); + if(wnd) + { + char buf[256]; + GetWindowText(wnd, buf, 256-1); + if(strstr(buf, "(//designing//)")==NULL) + { + PostMessage(wnd, WM_SHOWFRONT, 0, 0); + int i; + int paramcount = ParamCount(); + for(i=1; i<=paramcount; i++) + { + if(FileExists(ParamStr(i))) + { + AnsiString data = "open:" + AnsiString(ParamStr(i)); + COPYDATASTRUCT cds; + cds.dwData = 0x746f8ab3; + cds.cbData = data.Length() + 1; + cds.lpData = data.c_str(); + SendMessage(wnd, WM_COPYDATA, NULL, (LPARAM)&cds); + break; + } + } + return false; // exit the application + } + } + return true; // continue the application +} +//--------------------------------------------------------------------------- + + + + + + + +//--------------------------------------------------------------------------- +// global supporting functions +//--------------------------------------------------------------------------- +static TMemIniFile * MemIniFile = NULL; +//--------------------------------------------------------------------------- +TMemIniFile * __fastcall GetIniFile() +{ + if(!MemIniFile) MemIniFile = new TMemIniFile(ParamStr(0) + ".ini"); + return MemIniFile; +} +//--------------------------------------------------------------------------- +void __fastcall CommitIniFile() +{ + if(MemIniFile) MemIniFile->UpdateFile(); +} +//--------------------------------------------------------------------------- +void __fastcall CommitAndCloseIniFile() +{ + if(MemIniFile) + { + MemIniFile->UpdateFile(); + delete MemIniFile; + MemIniFile = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall ReadWindowBasicInformationFromIniFile(const char * section, TForm * form) +{ + // window position and size + int w, h, l, t; + w = GetIniFile()->ReadInteger(section, "Width", -1); + if(w == -1) w = form->Width; + h = GetIniFile()->ReadInteger(section, "Height", -1); + if(h == -1) h = form->Height; + l = GetIniFile()->ReadInteger(section, "Left", -1); + if(l == -1) l = form->Left; + t = GetIniFile()->ReadInteger(section, "Top", -1); + if(t == -1) t = form->Top; + + if(l > Screen->DesktopWidth + Screen->DesktopLeft) l = 0; + if(t > Screen->DesktopHeight + Screen->DesktopTop) t = 0; + + form->SetBounds(l, t, w, h); +} +//--------------------------------------------------------------------------- +void __fastcall WriteWindowBasicInformationToIniFile(const char * section, TForm * form) +{ + // window position and size + GetIniFile()->WriteInteger(section, "Width", form->Width); + GetIniFile()->WriteInteger(section, "Height", form->Height); + GetIniFile()->WriteInteger(section, "Left", form->Left); + GetIniFile()->WriteInteger(section, "Top", form->Top); +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/looptuner2/looptune.drc b/tools/win32/krdevui/looptuner2/looptune.drc new file mode 100644 index 0000000..601b4fc --- /dev/null +++ b/tools/win32/krdevui/looptuner2/looptune.drc @@ -0,0 +1,391 @@ +/* + Generated by the Borland C++ Incremental Linker + because -GD was supplied to the linker. + + It contains compiler-generated resource bound to the executable. + If it is empty, no compiler-generated resources were bound to the + produced executable. +*/ + +#define Sysconst_SShortDayNameMon 65344 +#define Sysconst_SShortDayNameTue 65345 +#define Sysconst_SShortDayNameWed 65346 +#define Sysconst_SShortDayNameThu 65347 +#define Sysconst_SShortDayNameFri 65348 +#define Sysconst_SShortDayNameSat 65349 +#define Sysconst_SLongDayNameSun 65350 +#define Sysconst_SLongDayNameMon 65351 +#define Sysconst_SLongDayNameTue 65352 +#define Sysconst_SLongDayNameWed 65353 +#define Sysconst_SLongDayNameThu 65354 +#define Sysconst_SLongDayNameFri 65355 +#define Sysconst_SLongDayNameSat 65356 +#define Sysconst_SShortMonthNameOct 65360 +#define Sysconst_SShortMonthNameNov 65361 +#define Sysconst_SShortMonthNameDec 65362 +#define Sysconst_SLongMonthNameJan 65363 +#define Sysconst_SLongMonthNameFeb 65364 +#define Sysconst_SLongMonthNameMar 65365 +#define Sysconst_SLongMonthNameApr 65366 +#define Sysconst_SLongMonthNameMay 65367 +#define Sysconst_SLongMonthNameJun 65368 +#define Sysconst_SLongMonthNameJul 65369 +#define Sysconst_SLongMonthNameAug 65370 +#define Sysconst_SLongMonthNameSep 65371 +#define Sysconst_SLongMonthNameOct 65372 +#define Sysconst_SLongMonthNameNov 65373 +#define Sysconst_SLongMonthNameDec 65374 +#define Sysconst_SShortDayNameSun 65375 +#define Sysconst_SIntfCastError 65376 +#define Sysconst_SSafecallException 65377 +#define Sysconst_SAssertError 65378 +#define Sysconst_SAbstractError 65379 +#define Sysconst_SModuleAccessViolation 65380 +#define Sysconst_SWin32Error 65381 +#define Sysconst_SUnkWin32Error 65382 +#define Sysconst_SShortMonthNameJan 65383 +#define Sysconst_SShortMonthNameFeb 65384 +#define Sysconst_SShortMonthNameMar 65385 +#define Sysconst_SShortMonthNameApr 65386 +#define Sysconst_SShortMonthNameMay 65387 +#define Sysconst_SShortMonthNameJun 65388 +#define Sysconst_SShortMonthNameJul 65389 +#define Sysconst_SShortMonthNameAug 65390 +#define Sysconst_SShortMonthNameSep 65391 +#define Sysconst_SControlC 65392 +#define Sysconst_SPrivilege 65393 +#define Sysconst_SException 65394 +#define Sysconst_SExceptTitle 65395 +#define Sysconst_SInvalidFormat 65396 +#define Sysconst_SArgumentMissing 65397 +#define Sysconst_SInvalidVarCast 65398 +#define Sysconst_SInvalidVarOp 65399 +#define Sysconst_SDispatchError 65400 +#define Sysconst_SReadAccess 65401 +#define Sysconst_SWriteAccess 65402 +#define Sysconst_SVarArrayCreate 65403 +#define Sysconst_SVarNotArray 65404 +#define Sysconst_SVarArrayBounds 65405 +#define Sysconst_SExternalException 65406 +#define Sysconst_SAssertionFailed 65407 +#define Sysconst_STooManyOpenFiles 65408 +#define Sysconst_SAccessDenied 65409 +#define Sysconst_SEndOfFile 65410 +#define Sysconst_SDiskFull 65411 +#define Sysconst_SInvalidInput 65412 +#define Sysconst_SDivByZero 65413 +#define Sysconst_SRangeError 65414 +#define Sysconst_SIntOverflow 65415 +#define Sysconst_SInvalidOp 65416 +#define Sysconst_SZeroDivide 65417 +#define Sysconst_SOverflow 65418 +#define Sysconst_SUnderflow 65419 +#define Sysconst_SInvalidPointer 65420 +#define Sysconst_SInvalidCast 65421 +#define Sysconst_SAccessViolation 65422 +#define Sysconst_SStackOverflow 65423 +#define Consts_SDockZoneNotFound 65424 +#define Consts_SDockZoneHasNoCtl 65425 +#define Consts_SDuplicateItem 65426 +#define Comstrs_sInsertError 65427 +#define Comconst_SOleError 65428 +#define Comconst_SNoMethod 65429 +#define Comconst_SVarNotObject 65430 +#define Sysconst_SInvalidInteger 65431 +#define Sysconst_SInvalidFloat 65432 +#define Sysconst_SInvalidDate 65433 +#define Sysconst_SInvalidTime 65434 +#define Sysconst_SInvalidDateTime 65435 +#define Sysconst_SOutOfMemory 65436 +#define Sysconst_SInOutError 65437 +#define Sysconst_SFileNotFound 65438 +#define Sysconst_SInvalidFilename 65439 +#define Consts_SmkcHome 65440 +#define Consts_SmkcLeft 65441 +#define Consts_SmkcUp 65442 +#define Consts_SmkcRight 65443 +#define Consts_SmkcDown 65444 +#define Consts_SmkcIns 65445 +#define Consts_SmkcDel 65446 +#define Consts_SmkcShift 65447 +#define Consts_SmkcCtrl 65448 +#define Consts_SmkcAlt 65449 +#define Consts_SOutOfRange 65450 +#define Consts_SIconToClipboard 65451 +#define Consts_SBitsIndexError 65452 +#define Consts_SDuplicateMenus 65453 +#define Consts_SDockedCtlNeedsName 65454 +#define Consts_SDockTreeRemoveError 65455 +#define Consts_SMsgDlgCancel 65456 +#define Consts_SMsgDlgHelp 65457 +#define Consts_SMsgDlgAbort 65458 +#define Consts_SMsgDlgRetry 65459 +#define Consts_SMsgDlgIgnore 65460 +#define Consts_SMsgDlgAll 65461 +#define Consts_SMsgDlgNoToAll 65462 +#define Consts_SMsgDlgYesToAll 65463 +#define Consts_SmkcBkSp 65464 +#define Consts_SmkcTab 65465 +#define Consts_SmkcEsc 65466 +#define Consts_SmkcEnter 65467 +#define Consts_SmkcSpace 65468 +#define Consts_SmkcPgUp 65469 +#define Consts_SmkcPgDn 65470 +#define Consts_SmkcEnd 65471 +#define Consts_SGroupIndexTooLow 65472 +#define Consts_SNoMDIForm 65473 +#define Consts_SControlParentSetToSelf 65474 +#define Consts_SCannotDragForm 65475 +#define Consts_SVMetafiles 65476 +#define Consts_SVEnhMetafiles 65477 +#define Consts_SVIcons 65478 +#define Consts_SVBitmaps 65479 +#define Consts_SInvalidProperty 65480 +#define Consts_SMsgDlgWarning 65481 +#define Consts_SMsgDlgError 65482 +#define Consts_SMsgDlgInformation 65483 +#define Consts_SMsgDlgConfirm 65484 +#define Consts_SMsgDlgYes 65485 +#define Consts_SMsgDlgNo 65486 +#define Consts_SMsgDlgOK 65487 +#define Consts_SInvalidImageList 65488 +#define Consts_SImageIndexError 65489 +#define Consts_SImageReadFail 65490 +#define Consts_SImageWriteFail 65491 +#define Consts_SWindowDCError 65492 +#define Consts_SWindowClass 65493 +#define Consts_SCannotFocus 65494 +#define Consts_SParentRequired 65495 +#define Consts_SMDIChildNotVisible 65496 +#define Consts_SVisibleChanged 65497 +#define Consts_SCannotShowModal 65498 +#define Consts_SPropertyOutOfRange 65499 +#define Consts_SMenuIndexError 65500 +#define Consts_SMenuReinserted 65501 +#define Consts_SMenuNotFound 65502 +#define Consts_SNoTimers 65503 +#define Consts_SInvalidName 65504 +#define Consts_SDuplicateClass 65505 +#define Consts_SInvalidPropertyValue 65506 +#define Consts_SInvalidPropertyPath 65507 +#define Consts_SUnknownProperty 65508 +#define Consts_SReadOnlyProperty 65509 +#define Consts_SPropertyException 65510 +#define Consts_SAncestorNotFound 65511 +#define Consts_SInvalidBitmap 65512 +#define Consts_SInvalidIcon 65513 +#define Consts_SInvalidMetafile 65514 +#define Consts_SChangeIconSize 65515 +#define Consts_SUnknownClipboardFormat 65516 +#define Consts_SOutOfResources 65517 +#define Consts_SNoCanvasHandle 65518 +#define Consts_SInvalidImageSize 65519 +#define Consts_SAssignError 65520 +#define Consts_SFCreateError 65521 +#define Consts_SFOpenError 65522 +#define Consts_SReadError 65523 +#define Consts_SWriteError 65524 +#define Consts_SMemoryStreamError 65525 +#define Consts_SCantWriteResourceStreamError 65526 +#define Consts_SClassNotFound 65527 +#define Consts_SInvalidImage 65528 +#define Consts_SResNotFound 65529 +#define Consts_SListIndexError 65530 +#define Consts_SListCapacityError 65531 +#define Consts_SListCountError 65532 +#define Consts_SSortedListError 65533 +#define Consts_SDuplicateString 65534 +#define Consts_SDuplicateName 65535 +STRINGTABLE +BEGIN + Sysconst_SShortDayNameMon, "Mon" + Sysconst_SShortDayNameTue, "Tue" + Sysconst_SShortDayNameWed, "Wed" + Sysconst_SShortDayNameThu, "Thu" + Sysconst_SShortDayNameFri, "Fri" + Sysconst_SShortDayNameSat, "Sat" + Sysconst_SLongDayNameSun, "Sunday" + Sysconst_SLongDayNameMon, "Monday" + Sysconst_SLongDayNameTue, "Tuesday" + Sysconst_SLongDayNameWed, "Wednesday" + Sysconst_SLongDayNameThu, "Thursday" + Sysconst_SLongDayNameFri, "Friday" + Sysconst_SLongDayNameSat, "Saturday" + Sysconst_SShortMonthNameOct, "Oct" + Sysconst_SShortMonthNameNov, "Nov" + Sysconst_SShortMonthNameDec, "Dec" + Sysconst_SLongMonthNameJan, "January" + Sysconst_SLongMonthNameFeb, "February" + Sysconst_SLongMonthNameMar, "March" + Sysconst_SLongMonthNameApr, "April" + Sysconst_SLongMonthNameMay, "May" + Sysconst_SLongMonthNameJun, "June" + Sysconst_SLongMonthNameJul, "July" + Sysconst_SLongMonthNameAug, "August" + Sysconst_SLongMonthNameSep, "September" + Sysconst_SLongMonthNameOct, "October" + Sysconst_SLongMonthNameNov, "November" + Sysconst_SLongMonthNameDec, "December" + Sysconst_SShortDayNameSun, "Sun" + Sysconst_SIntfCastError, "Interface はサポートされていません" + Sysconst_SSafecallException, "safecall メソッド内で例外が発生しました。" + Sysconst_SAssertError, "%s (%s, %d 行)" + Sysconst_SAbstractError, "Abstract エラー" + Sysconst_SModuleAccessViolation, "モジュール '%1:s' のアドレス %0:p でアドレス %3:p に対する%2:s違反がおきました。" + Sysconst_SWin32Error, "Win32 エラー。コード : %d.\n%s" + Sysconst_SUnkWin32Error, "Win32 API 呼び出しに失敗しました" + Sysconst_SShortMonthNameJan, "Jan" + Sysconst_SShortMonthNameFeb, "Feb" + Sysconst_SShortMonthNameMar, "Mar" + Sysconst_SShortMonthNameApr, "Apr" + Sysconst_SShortMonthNameMay, "May" + Sysconst_SShortMonthNameJun, "Jun" + Sysconst_SShortMonthNameJul, "Jul" + Sysconst_SShortMonthNameAug, "Aug" + Sysconst_SShortMonthNameSep, "Sep" + Sysconst_SControlC, "CTRL-C" + Sysconst_SPrivilege, "特権命令違反" + Sysconst_SException, "%sがモジュール %s の %p で発生しました。\n%s%s" + Sysconst_SExceptTitle, "アプリケーション エラー" + Sysconst_SInvalidFormat, "書式文字列 '%s' は正しくないか引数の型と一致しません" + Sysconst_SArgumentMissing, "書式文字列 '%s' の引数が見つかりません" + Sysconst_SInvalidVarCast, "バリアントの型変換が不正です" + Sysconst_SInvalidVarOp, "バリアントに対する演算が正しくありません" + Sysconst_SDispatchError, "バリアントのメソッド呼び出しは使えません" + Sysconst_SReadAccess, "読み込み" + Sysconst_SWriteAccess, "書き込み" + Sysconst_SVarArrayCreate, "バリアント配列を作成できません" + Sysconst_SVarNotArray, "バリアント配列ではありません" + Sysconst_SVarArrayBounds, "バリアント配列の範囲を超えています" + Sysconst_SExternalException, "外部例外 %x" + Sysconst_SAssertionFailed, "アサート失敗" + Sysconst_STooManyOpenFiles, "オープンしたファイルが多すぎます" + Sysconst_SAccessDenied, "ファイルへのアクセスが拒否されました" + Sysconst_SEndOfFile, "ファイルの末尾以降を読み込みました" + Sysconst_SDiskFull, "ディスクがいっぱいです" + Sysconst_SInvalidInput, "入力値が数値ではありません" + Sysconst_SDivByZero, "ゼロによる除算" + Sysconst_SRangeError, "範囲チェックエラー" + Sysconst_SIntOverflow, "整数のオーバーフロー" + Sysconst_SInvalidOp, "不正な浮動小数点数演算命令" + Sysconst_SZeroDivide, "0 による浮動小数点数除算" + Sysconst_SOverflow, "浮動小数点数のオーバーフロー" + Sysconst_SUnderflow, "浮動小数点数のアンダーフロー" + Sysconst_SInvalidPointer, "無効なポインタ操作" + Sysconst_SInvalidCast, "無効なクラス型キャスト" + Sysconst_SAccessViolation, "アドレス %0:p でアドレス %2:p に対する%1:s違反がおきました。" + Sysconst_SStackOverflow, "スタック オーバーフロー" + Consts_SDockZoneNotFound, " - ドッキングゾーンが見つかりません。" + Consts_SDockZoneHasNoCtl, " - ドッキングゾーンはコントロールを持ちません。" + Consts_SDuplicateItem, "リストは重複を許しません。($0%x)" + Comstrs_sInsertError, "アイテムの挿入ができません" + Comconst_SOleError, "OLE エラー %.8x" + Comconst_SNoMethod, "メソッド '%s' はオートメーション オブジェクトでサポートしていません" + Comconst_SVarNotObject, "バリアントはオートメーション オブジェクトを参照していません" + Sysconst_SInvalidInteger, "'%s' は整数ではありません" + Sysconst_SInvalidFloat, "'%s' は浮動小数点数ではありません" + Sysconst_SInvalidDate, "'%s' は日付ではありません" + Sysconst_SInvalidTime, "'%s' は時刻ではありません" + Sysconst_SInvalidDateTime, "'%s' は日付または時刻ではありません" + Sysconst_SOutOfMemory, "メモリが足りません" + Sysconst_SInOutError, "I/O エラー (%d)" + Sysconst_SFileNotFound, "ファイルが見つかりません" + Sysconst_SInvalidFilename, "不正なファイル名です" + Consts_SmkcHome, "Home" + Consts_SmkcLeft, "Left" + Consts_SmkcUp, "Up" + Consts_SmkcRight, "Right" + Consts_SmkcDown, "Down" + Consts_SmkcIns, "Ins" + Consts_SmkcDel, "Del" + Consts_SmkcShift, "Shift+" + Consts_SmkcCtrl, "Ctrl+" + Consts_SmkcAlt, "Alt+" + Consts_SOutOfRange, "%d から %d の間の値でなければなりません" + Consts_SIconToClipboard, "クリップボードはアイコンには対応していません" + Consts_SBitsIndexError, "インデックスが範囲を超えました" + Consts_SDuplicateMenus, "メニュー '%s' は既に他のフォームで使われています" + Consts_SDockedCtlNeedsName, "ドッキングコントロールは名前を持っていなければなりません" + Consts_SDockTreeRemoveError, "ドッキングツリーからコントロールを削除する際のエラー" + Consts_SMsgDlgCancel, "キャンセル" + Consts_SMsgDlgHelp, "ヘルプ(&H)" + Consts_SMsgDlgAbort, "中止(&A)" + Consts_SMsgDlgRetry, "再試行(&R)" + Consts_SMsgDlgIgnore, "無視(&I)" + Consts_SMsgDlgAll, "すべて(&A)" + Consts_SMsgDlgNoToAll, "すべていいえ(&O)" + Consts_SMsgDlgYesToAll, "すべてはい(&A)" + Consts_SmkcBkSp, "BkSp" + Consts_SmkcTab, "Tab" + Consts_SmkcEsc, "Esc" + Consts_SmkcEnter, "Enter" + Consts_SmkcSpace, "Space" + Consts_SmkcPgUp, "PgUp" + Consts_SmkcPgDn, "PgDn" + Consts_SmkcEnd, "End" + Consts_SGroupIndexTooLow, "GroupIndex は直前のメニューアイテムの GroupIndex より小さくすることができません" + Consts_SNoMDIForm, "フォームが作成できません。有効な MDI フォームがありません" + Consts_SControlParentSetToSelf, "自分自身を親とすることはできません" + Consts_SCannotDragForm, "フォームをドラッグすることはできません" + Consts_SVMetafiles, "メタファイル" + Consts_SVEnhMetafiles, "エンハンス メタファイル" + Consts_SVIcons, "アイコン" + Consts_SVBitmaps, "ビットマップ" + Consts_SInvalidProperty, "不正なプロパティの値です" + Consts_SMsgDlgWarning, "警告" + Consts_SMsgDlgError, "エラー" + Consts_SMsgDlgInformation, "情報" + Consts_SMsgDlgConfirm, "確認" + Consts_SMsgDlgYes, "はい(&Y)" + Consts_SMsgDlgNo, "いいえ(&N)" + Consts_SMsgDlgOK, "OK" + Consts_SInvalidImageList, "不正なイメージ リスト" + Consts_SImageIndexError, "不正なインデックスがイメージ リストに渡されました" + Consts_SImageReadFail, "ストリームからの ImageList データの読み込みに失敗しました" + Consts_SImageWriteFail, "ストリームへの ImageList データの書き込みに失敗しました" + Consts_SWindowDCError, "デバイス コンテキストの作成に失敗しました" + Consts_SWindowClass, "ウィンドウクラスの作成でエラーが発生しました" + Consts_SCannotFocus, "無効/非表示ウィンドウにはフォーカスを設定できません" + Consts_SParentRequired, "コントロール '%s' は親ウィンドウを持っていません" + Consts_SMDIChildNotVisible, "MDI 子フォームを隠すことはできません" + Consts_SVisibleChanged, "OnShow/OnHide イベントの処理中は表示状態の変更はできません" + Consts_SCannotShowModal, "表示されているウィンドウをモーダルにすることはできません" + Consts_SPropertyOutOfRange, "プロパティ %s の範囲を超えています" + Consts_SMenuIndexError, "メニューインデックスが範囲を越えました" + Consts_SMenuReinserted, "メニューを二度追加しました" + Consts_SMenuNotFound, "サブメニューがメニューにありません" + Consts_SNoTimers, "タイマーを取得できません" + Consts_SInvalidName, "コンポーネント名に ''%s'' は使えません" + Consts_SDuplicateClass, "クラス名 %s はすでに使われています" + Consts_SInvalidPropertyValue, "不正なプロパティの値です" + Consts_SInvalidPropertyPath, "不正なプロパティのパスです" + Consts_SUnknownProperty, "プロパティが存在しません" + Consts_SReadOnlyProperty, "プロパティは書き込み禁止です" + Consts_SPropertyException, "%s%s%s の読み込み中のエラー : %s" + Consts_SAncestorNotFound, "'%s' の継承元が存在しません" + Consts_SInvalidBitmap, "ビットマップイメージが不正です" + Consts_SInvalidIcon, "アイコンイメージが不正です" + Consts_SInvalidMetafile, "メタファイルが不正です" + Consts_SChangeIconSize, "アイコンの大きさは変更できません" + Consts_SUnknownClipboardFormat, "未対応のクリップボード データです" + Consts_SOutOfResources, "システム リソースが足りません" + Consts_SNoCanvasHandle, "Canvas に対する描画ができません" + Consts_SInvalidImageSize, "イメージサイズが正しくありません" + Consts_SAssignError, "%s を %s に代入することはできません" + Consts_SFCreateError, "ファイル %s を作成できません" + Consts_SFOpenError, "ファイル %s は開けません" + Consts_SReadError, "ストリームからの読み込みエラー" + Consts_SWriteError, "ストリームへの書き込みエラー" + Consts_SMemoryStreamError, "メモリストリームの拡大中にメモリが足りなくなりました" + Consts_SCantWriteResourceStreamError, "読み込み専用リソース ストリームには書き込めません" + Consts_SClassNotFound, "クラス %s が見つかりません" + Consts_SInvalidImage, "不正なストリーム フォーマット" + Consts_SResNotFound, "%s リソースが見つかりません" + Consts_SListIndexError, "リストのインデックスが範囲を超えています (%d)" + Consts_SListCapacityError, "リストの容量が超えました (%d)" + Consts_SListCountError, "リストの個数を超えました (%d)" + Consts_SSortedListError, "ソートされる文字列リストに対しては許されない動作です" + Consts_SDuplicateString, "文字列リストは重複を許しません" + Consts_SDuplicateName, "コンポーネント名 %s はすでに使われています" +END + diff --git a/tools/win32/krdevui/looptuner2/looptune.h b/tools/win32/krdevui/looptuner2/looptune.h new file mode 100644 index 0000000..cac0b2b --- /dev/null +++ b/tools/win32/krdevui/looptuner2/looptune.h @@ -0,0 +1,22 @@ +//--------------------------------------------------------------------------- +/* + TVP2 ( T Visual Presenter 2 ) A script authoring tool + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- + + +#include + +//--------------------------------------------------------------------------- +// global supporting functions +//--------------------------------------------------------------------------- +TMemIniFile * __fastcall GetIniFile(); +void __fastcall CommitIniFile(); +void __fastcall CommitAndCloseIniFile(); +void __fastcall ReadWindowBasicInformationFromIniFile(const char * section, TForm * form); +void __fastcall WriteWindowBasicInformationToIniFile(const char * section, TForm * form); +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/looptuner2/looptune.res b/tools/win32/krdevui/looptuner2/looptune.res new file mode 100644 index 0000000000000000000000000000000000000000..0f229632a1edfbf83368c3cd5f3d49c89ea62741 GIT binary patch literal 17048 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 and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "JPEGQualityUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TJPEGQualityForm *JPEGQualityForm; +//--------------------------------------------------------------------------- +__fastcall TJPEGQualityForm::TJPEGQualityForm(TComponent* Owner) + : TForm(Owner) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TJPEGQualityForm::TrackBarChange(TObject *Sender) +{ + QualityLabel->Caption = AnsiString(TrackBar->Position); +} +//--------------------------------------------------------------------------- +void __fastcall TJPEGQualityForm::RestoreDefaultButtonClick( + TObject *Sender) +{ + TrackBar->Position = 90; +} +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +void __fastcall ShowJPEGQualityForm(TForm *parent, int & quality) +{ + TJPEGQualityForm *form = new TJPEGQualityForm(parent); + form->TrackBar->Position = quality; + int mr = form->ShowModal(); + if(mr == mrOk) + quality = form->TrackBar->Position; + delete form; +} +//--------------------------------------------------------------------------- + + diff --git a/tools/win32/krdevui/tpc/JPEGQualityUnit.dfm b/tools/win32/krdevui/tpc/JPEGQualityUnit.dfm new file mode 100644 index 0000000..06cb8f4 --- /dev/null +++ b/tools/win32/krdevui/tpc/JPEGQualityUnit.dfm @@ -0,0 +1,108 @@ +object JPEGQualityForm: TJPEGQualityForm + Left = 214 + Top = 359 + BorderStyle = bsDialog + Caption = 'JPEG オプション' + ClientHeight = 113 + ClientWidth = 382 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poMainFormCenter + PixelsPerInch = 96 + TextHeight = 12 + object Label1: TLabel + Left = 8 + Top = 8 + Width = 71 + Height = 12 + Caption = 'クオリティ(&Q) :' + FocusControl = TrackBar + end + object Label2: TLabel + Left = 264 + Top = 32 + Width = 46 + Height = 12 + Caption = '画質 : 高' + end + object Label3: TLabel + Left = 264 + Top = 48 + Width = 97 + Height = 12 + Caption = 'ファイルサイズ : 大' + end + object Label4: TLabel + Left = 56 + Top = 32 + Width = 46 + Height = 12 + Caption = '画質 : 低' + end + object Label5: TLabel + Left = 8 + Top = 48 + Width = 97 + Height = 12 + Caption = 'ファイルサイズ : 小' + end + object QualityLabel: TLabel + Left = 88 + Top = 8 + Width = 12 + Height = 12 + Caption = '50' + end + object TrackBar: TTrackBar + Left = 112 + Top = 32 + Width = 145 + Height = 29 + Max = 100 + Min = 1 + Orientation = trHorizontal + PageSize = 5 + Frequency = 1 + Position = 50 + SelEnd = 0 + SelStart = 0 + TabOrder = 0 + TickMarks = tmBottomRight + TickStyle = tsNone + OnChange = TrackBarChange + end + object RestoreDefaultButton: TButton + Left = 16 + Top = 80 + Width = 123 + Height = 25 + Caption = 'デフォルトに戻す(&D)' + TabOrder = 1 + OnClick = RestoreDefaultButtonClick + end + object OKButton: TButton + Left = 200 + Top = 80 + Width = 75 + Height = 25 + Caption = 'OK' + Default = True + ModalResult = 1 + TabOrder = 2 + end + object CancelButton: TButton + Left = 288 + Top = 80 + Width = 75 + Height = 25 + Cancel = True + Caption = 'キャンセル' + ModalResult = 2 + TabOrder = 3 + end +end diff --git a/tools/win32/krdevui/tpc/JPEGQualityUnit.h b/tools/win32/krdevui/tpc/JPEGQualityUnit.h new file mode 100644 index 0000000..3393e5a --- /dev/null +++ b/tools/win32/krdevui/tpc/JPEGQualityUnit.h @@ -0,0 +1,42 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef JPEGQualityUnitH +#define JPEGQualityUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +void __fastcall ShowJPEGQualityForm(TForm *parent, int & quality); +//--------------------------------------------------------------------------- +class TJPEGQualityForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TLabel *Label1; + TTrackBar *TrackBar; + TLabel *Label2; + TLabel *Label3; + TLabel *Label4; + TLabel *Label5; + TLabel *QualityLabel; + TButton *RestoreDefaultButton; + TButton *OKButton; + TButton *CancelButton; + void __fastcall TrackBarChange(TObject *Sender); + void __fastcall RestoreDefaultButtonClick(TObject *Sender); +private: // ユーザー宣言 +public: // ユーザー宣言 + __fastcall TJPEGQualityForm(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TJPEGQualityForm *JPEGQualityForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/tpc/LogViewerUnit.cpp b/tools/win32/krdevui/tpc/LogViewerUnit.cpp new file mode 100644 index 0000000..335cb4f --- /dev/null +++ b/tools/win32/krdevui/tpc/LogViewerUnit.cpp @@ -0,0 +1,27 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "LogViewerUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TLogViewerForm *LogViewerForm; +//--------------------------------------------------------------------------- +__fastcall TLogViewerForm::TLogViewerForm(TComponent* Owner) + : TForm(Owner) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TLogViewerForm::Panel1Resize(TObject *Sender) +{ + CloseButton->Left = (Panel1->Width - CloseButton->Width) >> 1; +} +//--------------------------------------------------------------------------- diff --git a/tools/win32/krdevui/tpc/LogViewerUnit.dfm b/tools/win32/krdevui/tpc/LogViewerUnit.dfm new file mode 100644 index 0000000..29324a3 --- /dev/null +++ b/tools/win32/krdevui/tpc/LogViewerUnit.dfm @@ -0,0 +1,53 @@ +object LogViewerForm: TLogViewerForm + Left = 47 + Top = 354 + Width = 463 + Height = 328 + BorderWidth = 10 + Caption = 'ログ' + Color = clBtnFace + Constraints.MinHeight = 100 + Constraints.MinWidth = 200 + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poMainFormCenter + PixelsPerInch = 96 + TextHeight = 12 + object Panel1: TPanel + Left = 0 + Top = 241 + Width = 435 + Height = 33 + Align = alBottom + BevelOuter = bvNone + TabOrder = 0 + OnResize = Panel1Resize + object CloseButton: TButton + Left = 180 + Top = 8 + Width = 75 + Height = 25 + Caption = '閉じる' + Default = True + ModalResult = 1 + TabOrder = 0 + end + end + object LogEdit: TRichEdit + Left = 0 + Top = 0 + Width = 435 + Height = 241 + Align = alClient + MaxLength = 10000000 + PlainText = True + ReadOnly = True + ScrollBars = ssBoth + TabOrder = 1 + WordWrap = False + end +end diff --git a/tools/win32/krdevui/tpc/LogViewerUnit.h b/tools/win32/krdevui/tpc/LogViewerUnit.h new file mode 100644 index 0000000..b7c8d60 --- /dev/null +++ b/tools/win32/krdevui/tpc/LogViewerUnit.h @@ -0,0 +1,33 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef LogViewerUnitH +#define LogViewerUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TLogViewerForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TPanel *Panel1; + TButton *CloseButton; + TRichEdit *LogEdit; + void __fastcall Panel1Resize(TObject *Sender); +private: // ユーザー宣言 +public: // ユーザー宣言 + __fastcall TLogViewerForm(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TLogViewerForm *LogViewerForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/tpc/ProgressUnit.cpp b/tools/win32/krdevui/tpc/ProgressUnit.cpp new file mode 100644 index 0000000..df3a3b0 --- /dev/null +++ b/tools/win32/krdevui/tpc/ProgressUnit.cpp @@ -0,0 +1,75 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "ProgressUnit.h" +#include "TPCMainUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TProgressForm *ProgressForm; +//--------------------------------------------------------------------------- +__fastcall TProgressForm::TProgressForm(TComponent* Owner, TStringList *list) + : TForm(Owner) +{ + Interrupted = false; + Shutdown = false; + MainForm = (TMainForm*)Owner; + FileList = list; + + AllSucceeded = true; + +} +//--------------------------------------------------------------------------- +void __fastcall TProgressForm::Process() +{ + // + for(int i = 0; i < FileList->Count; i++) + { + CurrentFileLabel->Caption = ExtractFileName(FileList->Strings[i]); + ProgressBar->Position = i * 100 / FileList->Count; + + Application->ProcessMessages(); + + bool success = TPCMainForm->ProcessFile(FileList->Strings[i]); + + if(!success) AllSucceeded = false; + + if(Interrupted) break; + } + + Shutdown = true; + ModalResult = mrOk; + +} +//--------------------------------------------------------------------------- +void __fastcall TProgressForm::WMStartProcess(TMessage &Msg) +{ +} +//--------------------------------------------------------------------------- +void __fastcall TProgressForm::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + CanClose = Shutdown; + Interrupted = true; +} +//--------------------------------------------------------------------------- +void __fastcall TProgressForm::CancelButtonClick(TObject *Sender) +{ + Interrupted = true; +} +//--------------------------------------------------------------------------- +void __fastcall TProgressForm::TimerTimer(TObject *Sender) +{ + Timer->Enabled = false; + Process(); +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/tpc/ProgressUnit.dfm b/tools/win32/krdevui/tpc/ProgressUnit.dfm new file mode 100644 index 0000000..654c2a1 --- /dev/null +++ b/tools/win32/krdevui/tpc/ProgressUnit.dfm @@ -0,0 +1,51 @@ +object ProgressForm: TProgressForm + Left = 195 + Top = 346 + ActiveControl = CancelButton + BorderStyle = bsDialog + Caption = '変換中 ...' + ClientHeight = 98 + ClientWidth = 261 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poMainFormCenter + OnCloseQuery = FormCloseQuery + PixelsPerInch = 96 + TextHeight = 12 + object CurrentFileLabel: TLabel + Left = 8 + Top = 8 + Width = 4 + Height = 12 + end + object ProgressBar: TProgressBar + Left = 8 + Top = 32 + Width = 241 + Height = 16 + Min = 0 + Max = 100 + TabOrder = 0 + end + object CancelButton: TButton + Left = 93 + Top = 64 + Width = 75 + Height = 25 + Cancel = True + Caption = 'キャンセル' + TabOrder = 1 + OnClick = CancelButtonClick + end + object Timer: TTimer + Interval = 100 + OnTimer = TimerTimer + Left = 216 + Top = 64 + end +end diff --git a/tools/win32/krdevui/tpc/ProgressUnit.h b/tools/win32/krdevui/tpc/ProgressUnit.h new file mode 100644 index 0000000..26a5a11 --- /dev/null +++ b/tools/win32/krdevui/tpc/ProgressUnit.h @@ -0,0 +1,54 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef ProgressUnitH +#define ProgressUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TMainForm; +class TProgressForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TProgressBar *ProgressBar; + TLabel *CurrentFileLabel; + TButton *CancelButton; + TTimer *Timer; + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall CancelButtonClick(TObject *Sender); + void __fastcall TimerTimer(TObject *Sender); +private: // ユーザー宣言 + bool Interrupted; + bool Shutdown; + bool AllSucceeded; + TMainForm *MainForm; + TStringList *FileList; +public: // ユーザー宣言 + __fastcall TProgressForm(TComponent* Owner, TStringList *list); + + bool GetInterrupted() const {return Interrupted; } + + + bool GetSucceeded() const { return AllSucceeded; } +protected: + + void __fastcall Process(); +BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER( WM_USER+1, TMessage, WMStartProcess); +END_MESSAGE_MAP(TForm) + void __fastcall WMStartProcess(TMessage &Msg); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TProgressForm *ProgressForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/tpc/TLGMetaInfo.cpp b/tools/win32/krdevui/tpc/TLGMetaInfo.cpp new file mode 100644 index 0000000..28c2ee8 --- /dev/null +++ b/tools/win32/krdevui/tpc/TLGMetaInfo.cpp @@ -0,0 +1,82 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "TLGMetaInfo.h" + +//--------------------------------------------------------------------------- +void SaveTLGWithMetaInfo(TStrings *names, Graphics::TBitmap *in, + AnsiString filename, + void (*saveproc)(Graphics::TBitmap *in, TStream *out)) +{ + // open output filename + TFileStream *filestream = + new TFileStream(filename, fmCreate|fmShareDenyWrite); + try + { + // if no names given, simply write TLG stream + if(!names || names->Count == 0) + { + saveproc(in, filestream); + } + else + { + // write TLG0.0 Structured Data Stream header + filestream->WriteBuffer("TLG0.0\x00sds\x1a\x00", 11); + unsigned int rawlenpos = filestream->Position; + filestream->WriteBuffer("0000", 4); + + // write raw TLG stream + saveproc(in, filestream); + + // write raw data size + unsigned int pos_save = filestream->Position; + filestream->Position = rawlenpos; + unsigned int size = pos_save - rawlenpos - 4; + unsigned char bin[4]; // buffer for writing 32bit integer as little endian format + bin[0] = size & 0xff; + bin[1] = (size >> 8) & 0xff; + bin[2] = (size >> 16) & 0xff; + bin[3] = (size >> 24) & 0xff; + filestream->WriteBuffer(bin, 4); + filestream->Position = pos_save; + + + // write "tags" chunk name + filestream->WriteBuffer("tags", 4); + + // build tag data + AnsiString tag; + for(int i = 0; i < names->Count; i++) + { + AnsiString name = names->Names[i]; + if(name == "") continue; + AnsiString value = names->Values[name]; + tag += AnsiString(name.Length()) + ":" + name + "=" + + AnsiString(value.Length()) + ":" + value + ","; + } + + // write chunk size + size = tag.Length(); + bin[0] = size & 0xff; + bin[1] = (size >> 8) & 0xff; + bin[2] = (size >> 16) & 0xff; + bin[3] = (size >> 24) & 0xff; + filestream->WriteBuffer(bin, 4); + + // write chunk data + filestream->WriteBuffer(tag.c_str(), tag.Length()); + } + } + catch(...) + { + delete filestream; + throw; + } + delete filestream; + +} +//--------------------------------------------------------------------------- + +#pragma package(smart_init) diff --git a/tools/win32/krdevui/tpc/TLGMetaInfo.h b/tools/win32/krdevui/tpc/TLGMetaInfo.h new file mode 100644 index 0000000..3354596 --- /dev/null +++ b/tools/win32/krdevui/tpc/TLGMetaInfo.h @@ -0,0 +1,11 @@ +//--------------------------------------------------------------------------- + +#ifndef TLGMetaInfoH +#define TLGMetaInfoH +//--------------------------------------------------------------------------- +extern void SaveTLGWithMetaInfo(TStrings *names, Graphics::TBitmap *in, + AnsiString filename, + void (*saveproc)(Graphics::TBitmap *in, TStream *out)); +//--------------------------------------------------------------------------- + +#endif diff --git a/tools/win32/krdevui/tpc/TPCMainUnit.cpp b/tools/win32/krdevui/tpc/TPCMainUnit.cpp new file mode 100644 index 0000000..d7d7696 --- /dev/null +++ b/tools/win32/krdevui/tpc/TPCMainUnit.cpp @@ -0,0 +1,1169 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include +#include +#include +#include +#include + +#pragma link "vclx50.lib" + +#include "TPCMainUnit.h" +#include "DeePNGUnit.h" +#include "DeePSDUnit.h" +#include "JPEGQualityUnit.h" +#include "LogViewerUnit.h" +#include "ProgressUnit.h" +#include "TLG5Saver.h" +#include "TLG6Saver.h" +#include "TLGMetaInfo.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TTPCMainForm *TPCMainForm; +//--------------------------------------------------------------------------- +unsigned long MMXReady = 0; +extern "C" +{ + void __fastcall CheckMMX(void) + { + MMXReady = false; // umm... + } +} +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +static AnsiString SelectFolder(HWND owner) +{ + BROWSEINFO bi; + bi.hwndOwner = owner; + bi.pidlRoot = NULL; + bi.pszDisplayName = "フォルダを選択してください"; + bi.lpszTitle = "フォルダの選択"; + bi.ulFlags = BIF_RETURNONLYFSDIRS; + bi.lpfn = NULL; + bi.lParam = 0; + bi.iImage = 0; + + PItemIDList id; + + id = SHBrowseForFolder(&bi); + + if(id != NULL) + { + char path[MAX_PATH]; + SHGetPathFromIDList(id, path); + return AnsiString(path); + } + return ""; +} +//--------------------------------------------------------------------------- + + + + + + +//--------------------------------------------------------------------------- +// SaveImage +//--------------------------------------------------------------------------- +static AnsiString AddImageExtension(AnsiString base, int type) +{ + // type : 0(BMP) 1(JPEG) 2(PNG) + switch(type) + { + case 0: return base + ".bmp"; + case 1: return base + ".jpg"; + case 2: return base + ".png"; + default: return base; + } +} +//--------------------------------------------------------------------------- +static void SaveImage(Graphics::TBitmap *bmp, AnsiString filename, int type, int jpegq, TStringList *tags) +{ + // save the image + // type : 0(BMP) 1(JPEG) 2(PNG) + // jpeg : JPEG quality + // tags : meta information (for PNG) + // the extension is to be automatically added + if(type == 0) + { + bmp->SaveToFile(filename + ".bmp"); + } + else if(type == 1) + { + TJPEGImage *image = NULL; + try + { + image = new TJPEGImage(); + if(bmp->PixelFormat == pf8bit) + image->Grayscale = true; + image->Assign(bmp); + image->CompressionQuality = jpegq; + image->SaveToFile(filename + ".jpg"); + } + catch(...) + { + if(image) delete image; + throw; + } + if(image) delete image; + } + else if(type == 2) + { + TDeePNG *image = new TDeePNG(); + try + { + image->Assign(bmp); + image->SetTags(tags); + image->SaveToFile(filename + ".png"); + } + catch(...) + { + delete image; + throw; + } + delete image; + } +} +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +// SeparateMainAndMask +//--------------------------------------------------------------------------- +static Graphics::TBitmap * SeparateMask(Graphics::TBitmap *bmp) +{ + bmp->PixelFormat = pf32bit; + Graphics::TBitmap * mask = new Graphics::TBitmap(); + try + { + int w, h; + mask->Width = w = bmp->Width; + mask->Height = h = bmp->Height; + + SetGrayscalePalette(mask, 8); + + for(int y = 0; y < h; y++) + { + unsigned char * dest = (unsigned char *)mask->ScanLine[y]; + DWORD * src = (DWORD *)bmp->ScanLine[y]; + for(int x = 0; x < w; x++) dest[x] = src[x] >> 24; + } + } + catch(...) + { + delete mask; + } + + bmp->PixelFormat = pf24bit; + + return mask; +} +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +// ClearFullTransparentColor +//--------------------------------------------------------------------------- +static void ClearFullTransparentColor(Graphics::TBitmap *bmp) +{ + // clear the color where the transparency is fully transparent + // bmp->PixelFormat must be pf32bit + + int w, h; + w = bmp->Width; + h = bmp->Height; + + for(int y = 0; y < h; y++) + { + DWORD * p = (DWORD *)bmp->ScanLine[y]; + for(int x = 0; x < w; x++) + { + DWORD c = p[x]; + if(!(c & 0xff000000)) c = 0; + p[x] = c; + } + } +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// CheckTransparentImage +//--------------------------------------------------------------------------- +static bool CheckTransparentImage(Graphics::TBitmap *bmp) +{ + // check whether given image has transparent color + // bmp must be 32bpp image. + + for(int y = 0; y < bmp->Height; y++) + { + DWORD *pixel = (DWORD*)bmp->ScanLine[y]; + DWORD *pixellim = pixel + bmp->Width; + while(pixel < pixellim) + { + if((*pixel & 0xff000000) != 0xff000000) return true; + pixel ++; + } + } + return false; +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// ExpandOpaqueColor +//--------------------------------------------------------------------------- +static void ExpandOpaqueColor(Graphics::TBitmap *bmp, int n) +{ + // Expand the opaque color to fully transparent color + // this algorithm is *very* slow + + // basically, for fully transparent pixel, find the nearest opaque pixel + // (that is, not fully transparent pixel) and set opaue pixel's color to + // the fully transparent pixel. + + int nd_start = n*n * 2; + int w, h; + w = bmp->Width; + h = bmp->Height; + int pitch; + + if(bmp->Height > 1) + pitch = (DWORD*)bmp->ScanLine[1] - (DWORD*)bmp->ScanLine[0]; + else + pitch = 0; + + DWORD* pixel = (DWORD*)bmp->ScanLine[0]; + + for(int y = 0; y < h; y++) + { + DWORD *scl = pixel + y * pitch; + int yystart = y - n < 0 ? 0 : y - n; + int yyend = y + n >= h ? h - 1 : y + n; + for(int x = 0; x < w; x++) + { + if(!(scl[x] & 0xff000000)) + { + // the pixel is fully transparent + int nearestdist = nd_start; + int r, g, b; + int npix; + int xxstart = x - n < 0 ? 0 : x - n; + int xxend = x + n >= w ? w - 1 : x + n; + for(int yy = yystart; yy <= yyend; yy++) + { + int dy = yy - y; + dy *= dy; + if(dy > nearestdist) continue; + DWORD *scl = pixel + yy * pitch; + for(int xx = xxstart; xx <= xxend; xx++) + { + DWORD px = scl[xx]; + if(px & 0xff000000) + { + // opaque + int dx = xx - x; + int dist = dx*dx + dy; + if(nearestdist > dist) + { + npix = 1; + r = (px&0xff0000) >> 16; + g = (px&0x00ff00) >> 8; + b = (px&0x0000ff); + nearestdist = dist; + } + else if(nearestdist == dist) + { + npix++; + r += ((px&0xff0000) >> 16); + g += ((px&0x00ff00) >> 8 ); + b += ((px&0x0000ff) ); + } + } + } + } + if(nearestdist != nd_start) + { + // nearest opaque pixel found + r /= npix; + g /= npix; + b /= npix; + scl[x] = (r << 16) + (g << 8) + b; + } + else + { + // not found + scl[x] = 0; + } + } + + } + } +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// LoadImage +//--------------------------------------------------------------------------- +# define COMPOSE_GRAYSCALE(r,g,b) (((b)*19 + (g)*183 + (r)*54)>>8) +static void ToGrayscaleImage(Graphics::TBitmap **in) +{ + // do grayscale + + (*in)->PixelFormat = pf24bit; // once convert to 24bpp bitmap + + Graphics::TBitmap *out = new Graphics::TBitmap(); + try + { + int w, h; + out->PixelFormat = pf8bit; + out->Width = w = (*in)->Width; + out->Height = h = (*in)->Height; + SetGrayscalePalette(out, 8); + + for(int y = 0; y < h; y++) + { + const unsigned char * src = (const unsigned char *)(*in)->ScanLine[y]; + unsigned char * dest = (unsigned char *)out->ScanLine[y]; + for(int x = 0; x < w; x++) + { + dest[x] = COMPOSE_GRAYSCALE(src[2], src[1], src[0]); + src += 3; + } + } + } + catch(...) + { + delete out; + throw; + } + + delete (*in); + (*in) = out; +} +//--------------------------------------------------------------------------- +static void BindMaskToMain(Graphics::TBitmap * main, Graphics::TBitmap * mask) +{ + // bind 8bpp mask to 32bpp main + + if(main->Width != mask->Width || mask->Height != mask->Height) + throw Exception("メイン画像とマスク画像のサイズが異なります"); + + if(main->PixelFormat != pf32bit) main->PixelFormat = pf32bit; + if(mask->PixelFormat != pf8bit) mask->PixelFormat = pf8bit; + + int w = main->Width; + int h = main->Height; + + for(int y = 0; y < h; y++) + { + DWORD * m = (DWORD *) main->ScanLine[y]; + const unsigned char * g = (const unsigned char*) mask->ScanLine[y]; + for(int x = 0; x < w; x++) + { + DWORD c = m[x]; + c &= 0xffffff; + c |= (g[x] << 24); + m[x] = c; + } + } +} +//--------------------------------------------------------------------------- +static Graphics::TBitmap *LoadSingleImage(AnsiString infile, + AnsiString & input_type, AnsiString & output_type, TStringList *tags) +{ + // load image + AnsiString ext = ExtractFileExt(infile).LowerCase(); + Graphics::TBitmap * bmp = new Graphics::TBitmap(); + try + { + if(ext == ".bmp") + { + bmp->LoadFromFile(infile); + // all input files is to be assumed as alpha except if there is not specification + if(input_type == "") input_type = "alpha"; + } + else if(ext == ".png") + { + TDeePNG *png = new TDeePNG(); + try + { + png->LoadFromFile(infile); + png->AppendTags(tags); + bmp->Assign(png); + } + catch(...) + { + delete png; + throw; + } + delete png; + // all input files is to be assumed as alpha except if there is not specification + if(input_type == "") input_type = "alpha"; + } + else if(ext == ".jpg" || ext == ".jpeg" || ext == ".jfif") + { + TJPEGImage *jpg = new TJPEGImage(); + try + { + jpg->Performance = jpBestQuality; + jpg->LoadFromFile(infile); + bmp->Assign(jpg); + } + catch(...) + { + delete jpg; + throw; + } + delete jpg; + // all input files is to be assumed as alpha except if there is not specification + if(input_type == "") input_type = "alpha"; + } + else if(ext == ".psd" || ext == ".pdd") + { + TDeePSD *psd = new TDeePSD(); + try + { + psd->LayerMode = output_type; + psd->LoadFromFile(infile); + bmp->Assign(psd); + input_type = psd->LayerMode; + } + catch(...) + { + delete psd; + throw; + } + delete psd; + } + else + { + throw Exception("認識できない画像形式です"); + } + } + catch(...) + { + delete bmp; + throw; + } + + return bmp; +} +//--------------------------------------------------------------------------- +static Graphics::TBitmap * LoadImage(AnsiString infile, + AnsiString & input_type, AnsiString & output_type, TStringList *tags) +{ + // load image + Graphics::TBitmap * bmp = LoadSingleImage(infile, + input_type, output_type, tags); + Graphics::TBitmap * mask = NULL; + + try + { + Graphics::TBitmap *mask = NULL; + + AnsiString maskfile = ChangeFileExt(infile, "") + "_m"; + AnsiString _input_type; // dummy + AnsiString _output_type; // dummy + if(FileExists(maskfile + ".bmp")) + mask = LoadSingleImage(maskfile + ".bmp", _input_type, _output_type, NULL); + else if(FileExists(maskfile + ".png")) + mask = LoadSingleImage(maskfile + ".png", _input_type, _output_type, NULL); + else if(FileExists(maskfile + ".jpg")) + mask = LoadSingleImage(maskfile + ".jpg", _input_type, _output_type, NULL); + else if(FileExists(maskfile + ".jpeg")) + mask = LoadSingleImage(maskfile + ".jpeg", _input_type, _output_type, NULL); + + if(mask) + { + ToGrayscaleImage(&mask); + BindMaskToMain(bmp, mask); + } + + if(bmp->PixelFormat != pf32bit) + { + bmp->PixelFormat = pf24bit; + } + else + { + if(input_type == "alpha" || input_type == "addalpha") + { + if(!CheckTransparentImage(bmp)) + { + bmp->PixelFormat = pf24bit; + input_type = "opaque"; + } + } + } + if(output_type == "") output_type = input_type; + + } + catch(...) + { + delete bmp; + delete mask; + throw; + } + + delete mask; + + return bmp; +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// TMainForm +//--------------------------------------------------------------------------- +__fastcall TTPCMainForm::TTPCMainForm(TComponent* Owner) + : TForm(Owner) +{ + OrgClientHeight = ClientHeight; + OrgCloseButtonTop = CloseButton->Top; + + TranspMainJPEGQuality = 90; + TranspMaskJPEGQuality = 90; + OpaqueJPEGQuality = 90; + TranspMainFormatComboBox->ItemIndex = 1; + TranspMaskFormatComboBox->ItemIndex = 1; + TranspFullTranspColorMethodComboBox->ItemIndex = 6; + FileList = new TStringList(); + LoadFromIni(); + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::FormDestroy(TObject *Sender) +{ + SaveToIni(); + delete FileList; +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::UpdateState() +{ + bool b = TranspSeparatedFormatRadioButton->Checked; + TranspMainFormatLabel->Font->Color = b ? clWindowText : clGrayText; + TranspMaskFormatLabel->Font->Color = b ? clWindowText : clGrayText; + TranspMainFormatComboBox->Enabled = b; + TranspMaskFormatComboBox->Enabled = b; + TranspMainJPEGOptionButton->Enabled = b && TranspMainFormatComboBox->ItemIndex == 1; + TranspMaskJPEGOptionButton->Enabled = b && TranspMaskFormatComboBox->ItemIndex == 1; + + b = SpecifyFolderRadioButton->Checked; + OutputFolderEdit->Color = b ? clWindow : clBtnFace; + OutputFolderEdit->Enabled = b; + OutputFolderRefButton->Enabled = b; + + OpaqueJPEGOptionButton->Enabled = OpaqueJPEGFormatRadioButton->Checked; + + + b = TranspAssumeInputIsAddAlphaCheckBox->Checked; + TranspOutputAddAlphaFormatCheckBox->Enabled = !b; + if(b) + TranspOutputAddAlphaFormatCheckBox->Checked = b; + else + TranspOutputAddAlphaFormatCheckBox->Checked = + TranspOutputAddAlphaFormatCheckBox->Tag; + + b = !TranspOutputAddAlphaFormatCheckBox->Checked && !TranspAssumeInputIsAddAlphaCheckBox->Checked; + TranspFullTranspColorMethodLabel->Font->Color = b ? clWindowText : clGrayText; + TranspFullTranspColorMethodComboBox->Enabled = b; + + + + if(!ExpandButton->Checked) + { + ClientHeight = ExpandButton->Top + ExpandButton->Height + ExpandButton->Top; + CloseButton->Top = (ClientHeight - CloseButton->Height)/2; + } + else + { + CloseButton->Top = OrgCloseButtonTop; + ClientHeight = OrgClientHeight; + } +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::LoadFromIni() +{ + AnsiString inifilename = ChangeFileExt(ParamStr(0), ".ini"); + + if(!FileExists(inifilename)) return; + + TMemIniFile * ini = new TMemIniFile(inifilename); + + ExpandButton->Checked = ini->ReadBool("Window", "Expand", true); + + OpaqueBMPFormatRadioButton->Checked = ini->ReadBool("Format", "OpaqueBMP", false); + OpaquePNGFormatRadioButton->Checked = ini->ReadBool("Format", "OpaquePNG", true); + OpaqueTLG5FormatRadioButton->Checked = ini->ReadBool("Format", "OpaqueTLG5", false); + OpaqueTLG6FormatRadioButton->Checked = ini->ReadBool("Format", "OpaqueTLG6", false); + OpaqueJPEGFormatRadioButton->Checked = ini->ReadBool("Format", "OpaqueJPEG", false); + OpaqueJPEGQuality = ini->ReadInteger("Format", "OpaqueJPEGQuality", 90); + + TranspBMPFormatRadioButton->Checked = ini->ReadBool("Format", "TranspBMP", false); + TranspPNGFormatRadioButton->Checked = ini->ReadBool("Format", "TranspPNG", true); + TranspTLG5FormatRadioButton->Checked = ini->ReadBool("Format", "TranspTLG5", true); + TranspTLG6FormatRadioButton->Checked = ini->ReadBool("Format", "TranspTLG6", true); + TranspSeparatedFormatRadioButton->Checked = ini->ReadBool("Format", "TranspSeparated", false); + TranspMainFormatComboBox->ItemIndex = ini->ReadInteger("Format", "TranspMainFormat", 1); + TranspMaskFormatComboBox->ItemIndex = ini->ReadInteger("Format", "TranspMaskFormat", 1); + TranspMainJPEGQuality = ini->ReadInteger("Format", "TranspMainJPEGQuality", 90); + TranspMaskJPEGQuality = ini->ReadInteger("Format", "TranspMaskJPEGQuality", 90); + TranspAssumeInputIsAddAlphaCheckBox->Checked = ini->ReadBool("Format", + "TranspAssumeInputIsAddAlpha", false); + TranspOutputAddAlphaFormatCheckBox->Checked = ini->ReadBool("Format", + "TranspOutputAddAlphaFormat", false); + TranspFullTranspColorMethodComboBox->ItemIndex = ini->ReadInteger("Format", + "TranspFullTranspColorMethod", 0); + + SameFolderRadioButton->Checked = ini->ReadBool("Output", "SameFolder", true); + SpecifyFolderRadioButton->Checked = ini->ReadBool("Output", "SpecifyFolder", false); + OutputFolderEdit->Text = ini->ReadString("Output", "OutputFolder", ""); + OverwriteCheckBox->Checked = ini->ReadBool("Output", "Overwrite", false); + + DoNotShowLogWhenNoErrorCheckBox->Checked = ini->ReadBool("Log", + "DoNotShowLogWhenNoError", false); + + delete ini; +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::SaveToIni() +{ + TMemIniFile * ini = new TMemIniFile(ChangeFileExt(ParamStr(0), ".ini")); + + ini->WriteBool("Window", "Expand", ExpandButton->Checked); + + ini->WriteBool("Format", "OpaqueBMP", OpaqueBMPFormatRadioButton->Checked); + ini->WriteBool("Format", "OpaquePNG", OpaquePNGFormatRadioButton->Checked); + ini->WriteBool("Format", "OpaqueTLG5", OpaqueTLG5FormatRadioButton->Checked); + ini->WriteBool("Format", "OpaqueTLG6", OpaqueTLG6FormatRadioButton->Checked); + ini->WriteBool("Format", "OpaqueJPEG", OpaqueJPEGFormatRadioButton->Checked); + ini->WriteInteger("Format", "OpaqueJPEGQuality", OpaqueJPEGQuality); + + ini->WriteBool("Format", "TranspBMP", TranspBMPFormatRadioButton->Checked); + ini->WriteBool("Format", "TranspPNG", TranspPNGFormatRadioButton->Checked); + ini->WriteBool("Format", "TranspTLG5", TranspTLG5FormatRadioButton->Checked); + ini->WriteBool("Format", "TranspTLG6", TranspTLG6FormatRadioButton->Checked); + ini->WriteBool("Format", "TranspSeparated", TranspSeparatedFormatRadioButton->Checked); + ini->WriteInteger("Format", "TranspMainFormat", TranspMainFormatComboBox->ItemIndex); + ini->WriteInteger("Format", "TranspMaskFormat", TranspMaskFormatComboBox->ItemIndex); + ini->WriteInteger("Format", "TranspMainJPEGQuality", TranspMainJPEGQuality); + ini->WriteInteger("Format", "TranspMaskJPEGQuality", TranspMaskJPEGQuality); + ini->WriteBool("Format", "TranspAssumeInputIsAddAlpha", TranspAssumeInputIsAddAlphaCheckBox->Checked); + ini->WriteBool("Format", "TranspOutputAddAlphaFormat", TranspOutputAddAlphaFormatCheckBox->Checked); + ini->WriteInteger("Format", "TranspFullTranspColorMethod", TranspFullTranspColorMethodComboBox->ItemIndex); + + ini->WriteBool("Output", "SameFolder", SameFolderRadioButton->Checked); + ini->WriteBool("Output", "SpecifyFolder", SpecifyFolderRadioButton->Checked); + ini->WriteString("Output", "OutputFolder", OutputFolderEdit->Text); + ini->WriteBool("Output", "Overwrite", OverwriteCheckBox->Checked); + + ini->WriteBool("Log", "DoNotShowLogWhenNoError", + DoNotShowLogWhenNoErrorCheckBox->Checked); + + ini->UpdateFile(); + delete ini; +} +//--------------------------------------------------------------------------- + +void __fastcall TTPCMainForm::ExpandButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::OpaqueBMPFormatRadioButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- + +void __fastcall TTPCMainForm::OpaquePNGFormatRadioButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- + +void __fastcall TTPCMainForm::OpaqueTLG5FormatRadioButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::OpaqueTLG6FormatRadioButtonClick( + TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- + +void __fastcall TTPCMainForm::OpaqueJPEGFormatRadioButtonClick( + TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspBMPFormatRadioButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspPNGFormatRadioButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspTLG5FormatRadioButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspTLG6FormatRadioButtonClick( + TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspSeparatedFormatRadioButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspMainFormatComboBoxChange(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- + +void __fastcall TTPCMainForm::TranspMaskFormatComboBoxChange(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspAssumeInputIsAddAlphaCheckBoxClick( + TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspOutputAddAlphaFormatCheckBoxClick(TObject *Sender) +{ + if(TranspOutputAddAlphaFormatCheckBox->Enabled) + { + TranspOutputAddAlphaFormatCheckBox->Tag = + TranspOutputAddAlphaFormatCheckBox->Checked; + UpdateState(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::SameFolderRadioButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- + +void __fastcall TTPCMainForm::SpecifyFolderRadioButtonClick(TObject *Sender) +{ + UpdateState(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::OpaqueJPEGOptionButtonClick(TObject *Sender) +{ + ShowJPEGQualityForm(this, OpaqueJPEGQuality); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspMainJPEGOptionButtonClick(TObject *Sender) +{ + ShowJPEGQualityForm(this, TranspMainJPEGQuality); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::TranspMaskJPEGOptionButtonClick(TObject *Sender) +{ + ShowJPEGQualityForm(this, TranspMaskJPEGQuality); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::CloseButtonClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::FormShow(TObject *Sender) +{ + DragAcceptFiles(Handle, true); +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::OutputFolderRefButtonClick(TObject *Sender) +{ + AnsiString newfolder = SelectFolder(Handle); + if(newfolder != "") OutputFolderEdit->Text = newfolder; +} +//--------------------------------------------------------------------------- +void __fastcall TTPCMainForm::WMDropFiles(TMessage &Msg) +{ + HDROP hd = (HDROP)Msg.WParam; + + char filename[ MAX_PATH ]; + int filecount= + DragQueryFile(hd, 0xFFFFFFFF, NULL, MAX_PATH); + + FileList->Clear(); + Log = ""; + + try + { + for(int i = filecount-1; i>=0; i--) + { + DragQueryFile(hd, i, filename, MAX_PATH); + + WIN32_FIND_DATA fd; + HANDLE h; + + // existence checking + if((h = FindFirstFile(filename, &fd)) != INVALID_HANDLE_VALUE) + { + FindClose(h); + + if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; + + + AnsiString base = ChangeFileExt(ExtractFileName(filename), ""); + int baselen = base.Length(); + if(baselen < 3 || strcmpi(base.c_str() + baselen - 2, "_m")) + FileList->Add(filename); + } + + } + DragFinish(hd); + + Application->BringToFront(); + BringToFront(); + + TProgressForm *progform = new TProgressForm(this, FileList); + progform->ShowModal(); + bool success = progform->GetSucceeded(); + delete progform; + + if(!success || !DoNotShowLogWhenNoErrorCheckBox->Checked) + { + TLogViewerForm *logviewer = new TLogViewerForm(this); + logviewer->LogEdit->Text = Log; + logviewer->ShowModal(); + delete logviewer; + } + } + catch(...) + { + throw; + } +} +//--------------------------------------------------------------------------- +const char * NotOverwritten = "同名のファイルがあるために上書きしませんでした : "; +bool __fastcall TTPCMainForm::ProcessFile(AnsiString infile) +{ + // process a file + Graphics::TBitmap *inbmp = NULL; + bool error = false; + + try + { + // change current directory + SetCurrentDir(ExtractFileDir(infile)); + + Log += "変換中 " + ExtractFileName(infile) + " ...\n"; + + // check for output files + AnsiString out_base = ChangeFileExt(ExtractFileName(infile), ""); + AnsiString out_dir; + if(SameFolderRadioButton->Checked) + { + // current directory + out_dir = "."; + } + else + { + // specified output directory + out_dir = ExcludeTrailingBackslash(OutputFolderEdit->Text); + ForceDirectories(ExpandFileName(out_dir)); + } + + out_base = out_dir + "/" + out_base; + + + + // read input + AnsiString input_type = TranspAssumeInputIsAddAlphaCheckBox->Checked ? "addalpha" : ""; + AnsiString output_type = TranspOutputAddAlphaFormatCheckBox->Checked ? "addalpha" : ""; + std::auto_ptr tags(new TStringList()); + inbmp = LoadImage(infile, input_type, output_type, tags.get()); + + // overwrite check + if(!OverwriteCheckBox->Checked) + { + if(inbmp->PixelFormat == pf32bit) + { + if(TranspBMPFormatRadioButton->Checked) + { + if(FileExists(out_base + ".bmp")) + throw Exception(NotOverwritten + out_base + ".bmp"); + } + else if(TranspPNGFormatRadioButton->Checked) + { + if(FileExists(out_base + ".png")) + throw Exception(NotOverwritten + out_base + ".png"); + } + else if(TranspTLG5FormatRadioButton->Checked) + { + if(FileExists(out_base + ".tlg")) + throw Exception(NotOverwritten + out_base + ".tlg"); + } + else if(TranspTLG6FormatRadioButton->Checked) + { + if(FileExists(out_base + ".tlg")) + throw Exception(NotOverwritten + out_base + ".tlg"); + } + else if(TranspSeparatedFormatRadioButton->Checked) + { + // main/mask separated type + if(FileExists(AddImageExtension(out_base, TranspMainFormatComboBox->ItemIndex))) + throw Exception(NotOverwritten + + AddImageExtension(out_base, TranspMainFormatComboBox->ItemIndex)); + + if(FileExists(AddImageExtension(out_base + "_m", TranspMaskFormatComboBox->ItemIndex))) + throw Exception(NotOverwritten + + AddImageExtension(out_base + "_m", TranspMaskFormatComboBox->ItemIndex)); + } + } + else + { + if(OpaqueBMPFormatRadioButton->Checked) + { + if(FileExists(out_base + ".bmp")) + throw Exception(NotOverwritten + out_base + ".bmp"); + } + else if(OpaquePNGFormatRadioButton->Checked) + { + if(FileExists(out_base + ".png")) + throw Exception(NotOverwritten + out_base + ".png"); + } + else if(OpaqueTLG5FormatRadioButton->Checked) + { + if(FileExists(out_base + ".tlg")) + throw Exception(NotOverwritten + out_base + ".tlg"); + } + else if(OpaqueTLG6FormatRadioButton->Checked) + { + if(FileExists(out_base + ".tlg")) + throw Exception(NotOverwritten + out_base + ".tlg"); + } + else if(OpaqueJPEGFormatRadioButton->Checked) + { + if(FileExists(out_base + ".jpg")) + throw Exception(NotOverwritten + out_base + ".jpg"); + } + } + } + + // expand full transparent color + if(inbmp->PixelFormat == pf32bit && output_type == "alpha" && + !TranspOutputAddAlphaFormatCheckBox->Checked) + { + switch(TranspFullTranspColorMethodComboBox->ItemIndex) + { + case 0: // remove + ClearFullTransparentColor(inbmp); + break; + case 1: // intact + break; + case 2: // expand(1) + ExpandOpaqueColor(inbmp, 1); + break; + case 3: // expand(2) + ExpandOpaqueColor(inbmp, 2); + break; + case 4: // expand(3) + ExpandOpaqueColor(inbmp, 3); + break; + case 5: // expand(5) + ExpandOpaqueColor(inbmp, 5); + break; + case 6: // expand(8) + ExpandOpaqueColor(inbmp, 8); + break; + } + } + + // convert alpha to addivive alpha + if(inbmp->PixelFormat == pf32bit && + input_type == "alpha" && output_type == "addalpha") + { + ConvertAlphaToAddAlpha(inbmp); + } + + // append 'mode' tag + tags->Append("mode=" + output_type); + + // write output + if(inbmp->PixelFormat == pf32bit) + { + // transparent image + if(TranspBMPFormatRadioButton->Checked) + { + inbmp->SaveToFile(out_base + ".bmp"); + } + else if(TranspPNGFormatRadioButton->Checked) + { + TDeePNG *png = new TDeePNG(); + try + { + png->Assign(inbmp); + png->SetTags(tags.get()); + png->SaveToFile(out_base + ".png"); + } + catch(...) + { + delete png; + throw; + } + delete png; + } + else if(TranspTLG5FormatRadioButton->Checked) + { + SaveTLGWithMetaInfo(tags.get(), inbmp, out_base + ".tlg", SaveTLG5); + } + else if(TranspTLG6FormatRadioButton->Checked) + { + SaveTLGWithMetaInfo(tags.get(), inbmp, out_base + ".tlg", SaveTLG6); + } + else if(TranspSeparatedFormatRadioButton->Checked) + { + // main/mask separated type + Graphics::TBitmap *mask = SeparateMask(inbmp); + try + { + SaveImage(inbmp, out_base, TranspMainFormatComboBox->ItemIndex, TranspMainJPEGQuality, tags.get()); + SaveImage(mask, out_base + "_m", TranspMaskFormatComboBox->ItemIndex, TranspMaskJPEGQuality, tags.get()); + } + catch(...) + { + delete mask; + throw; + } + delete mask; + } + } + else + { + // opaque image + if(OpaqueBMPFormatRadioButton->Checked) + { + inbmp->SaveToFile(out_base + ".bmp"); + } + else if(OpaquePNGFormatRadioButton->Checked) + { + TDeePNG *png = new TDeePNG(); + try + { + png->Assign(inbmp); + png->SetTags(tags.get()); + png->SaveToFile(out_base + ".png"); + } + catch(...) + { + delete png; + throw; + } + delete png; + } + else if(OpaqueTLG5FormatRadioButton->Checked) + { + SaveTLGWithMetaInfo(tags.get(), inbmp, out_base + ".tlg", SaveTLG5); + } + else if(OpaqueTLG6FormatRadioButton->Checked) + { + SaveTLGWithMetaInfo(tags.get(), inbmp, out_base + ".tlg", SaveTLG6); + } + else if(OpaqueJPEGFormatRadioButton->Checked) + { + SaveImage(inbmp, out_base, 1, OpaqueJPEGQuality, NULL); + } + } + } + catch(Exception &e) + { + Log += "エラー: " + e.Message + "\n"; + error = true; + } + catch(...) + { + Log += "不明なエラー\n"; + error = true; + } + + if(!error) + Log += "OK\n"; + + Log += "\n"; + + if(inbmp) delete inbmp; + + return !error; +} +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +extern "C" void _export PASCAL UIExecTPC() +{ + try + { + TPCMainForm = new TTPCMainForm(Application); + TPCMainForm->ShowModal(); + delete TPCMainForm, TPCMainForm = NULL; + } + catch(Exception &e) + { + Application->ShowException(&e); + } + ExitProcess(0); +} +//--------------------------------------------------------------------------- + + + + + + + + + + + + + + diff --git a/tools/win32/krdevui/tpc/TPCMainUnit.dfm b/tools/win32/krdevui/tpc/TPCMainUnit.dfm new file mode 100644 index 0000000..218af8f --- /dev/null +++ b/tools/win32/krdevui/tpc/TPCMainUnit.dfm @@ -0,0 +1,346 @@ +object TPCMainForm: TTPCMainForm + Left = 152 + Top = 7 + ActiveControl = CloseButton + BorderStyle = bsDialog + Caption = '画像フォーマットコンバータ' + ClientHeight = 390 + ClientWidth = 546 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poDefault + OnDestroy = FormDestroy + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 12 + object Label1: TLabel + Left = 8 + Top = 9 + Width = 283 + Height = 12 + Caption = '変換したいファイルをこのウィンドウにドロップしてください' + end + object TranspOuputFormatGroupBox: TGroupBox + Left = 144 + Top = 32 + Width = 393 + Height = 209 + Caption = '透明部分のある画像(&F)' + TabOrder = 2 + object TranspMainFormatLabel: TLabel + Left = 232 + Top = 28 + Width = 75 + Height = 12 + Caption = 'メイン形式(&C) :' + FocusControl = TranspMainFormatComboBox + end + object TranspMaskFormatLabel: TLabel + Left = 232 + Top = 75 + Width = 79 + Height = 12 + Caption = 'マスク形式(&M) :' + FocusControl = TranspMaskFormatComboBox + end + object TranspFullTranspColorMethodLabel: TLabel + Left = 16 + Top = 176 + Width = 146 + Height = 12 + Caption = '完全透明部分の色情報(&U) : ' + FocusControl = TranspFullTranspColorMethodComboBox + end + object TranspBMPFormatRadioButton: TRadioButton + Left = 16 + Top = 24 + Width = 193 + Height = 17 + Caption = 'αチャンネル付き 32bit B&MP' + TabOrder = 0 + OnClick = TranspBMPFormatRadioButtonClick + end + object TranspPNGFormatRadioButton: TRadioButton + Left = 16 + Top = 40 + Width = 161 + Height = 17 + Caption = 'αチャネル付き P&NG' + Checked = True + TabOrder = 1 + TabStop = True + OnClick = TranspPNGFormatRadioButtonClick + end + object TranspSeparatedFormatRadioButton: TRadioButton + Left = 16 + Top = 88 + Width = 153 + Height = 17 + Caption = 'メイン/マスク分離形式(&S)' + TabOrder = 4 + OnClick = TranspSeparatedFormatRadioButtonClick + end + object TranspMainFormatComboBox: TComboBox + Left = 320 + Top = 24 + Width = 57 + Height = 20 + Style = csDropDownList + ItemHeight = 12 + TabOrder = 5 + OnChange = TranspMainFormatComboBoxChange + Items.Strings = ( + 'BMP' + 'JPEG' + 'PNG') + end + object TranspMaskFormatComboBox: TComboBox + Left = 320 + Top = 71 + Width = 57 + Height = 20 + Style = csDropDownList + ItemHeight = 12 + TabOrder = 7 + OnChange = TranspMaskFormatComboBoxChange + Items.Strings = ( + 'BMP' + 'JPEG' + 'PNG') + end + object TranspMainJPEGOptionButton: TButton + Left = 304 + Top = 48 + Width = 73 + Height = 20 + Caption = 'JPEG設定 ...' + TabOrder = 6 + OnClick = TranspMainJPEGOptionButtonClick + end + object TranspMaskJPEGOptionButton: TButton + Left = 304 + Top = 95 + Width = 73 + Height = 20 + Caption = 'JPEG設定 ...' + TabOrder = 8 + OnClick = TranspMaskJPEGOptionButtonClick + end + object TranspFullTranspColorMethodComboBox: TComboBox + Left = 176 + Top = 172 + Width = 97 + Height = 20 + Style = csDropDownList + ItemHeight = 12 + TabOrder = 11 + Items.Strings = ( + '除去' + 'そのまま' + '合成(1pixel)' + '合成(2pixel)' + '合成(3pixel)' + '合成(5pixel)' + '合成(8pixel)') + end + object TranspTLG5FormatRadioButton: TRadioButton + Left = 16 + Top = 56 + Width = 153 + Height = 17 + Caption = 'αチャネル付き T&LG5' + TabOrder = 2 + OnClick = TranspTLG5FormatRadioButtonClick + end + object TranspTLG6FormatRadioButton: TRadioButton + Left = 16 + Top = 72 + Width = 145 + Height = 17 + Caption = 'αチャネル付き TLG&6' + TabOrder = 3 + OnClick = TranspTLG6FormatRadioButtonClick + end + object TranspOutputAddAlphaFormatCheckBox: TCheckBox + Left = 16 + Top = 152 + Width = 353 + Height = 17 + Caption = 'ltAddAlpha形式で出力する(&A)' + TabOrder = 10 + OnClick = TranspOutputAddAlphaFormatCheckBoxClick + end + object Bar1: TPanel + Left = 8 + Top = 128 + Width = 372 + Height = 2 + BevelOuter = bvLowered + TabOrder = 12 + end + object TranspAssumeInputIsAddAlphaCheckBox: TCheckBox + Left = 16 + Top = 136 + Width = 353 + Height = 17 + Caption = '入力画像をltAddAlpha形式であるとみなす(&D)' + TabOrder = 9 + OnClick = TranspAssumeInputIsAddAlphaCheckBoxClick + end + end + object OutputFolderGroup: TGroupBox + Left = 8 + Top = 248 + Width = 529 + Height = 105 + Caption = '出力フォルダ(&O)' + TabOrder = 3 + object SameFolderRadioButton: TRadioButton + Left = 16 + Top = 24 + Width = 249 + Height = 17 + Caption = '入力ファイルと同じフォルダ(&I)' + Checked = True + TabOrder = 0 + TabStop = True + OnClick = SameFolderRadioButtonClick + end + object SpecifyFolderRadioButton: TRadioButton + Left = 16 + Top = 48 + Width = 137 + Height = 17 + Caption = '指定フォルダ(&Y) :' + TabOrder = 1 + OnClick = SpecifyFolderRadioButtonClick + end + object OutputFolderEdit: TEdit + Left = 160 + Top = 46 + Width = 297 + Height = 20 + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS ゴシック' + Font.Pitch = fpFixed + Font.Style = [] + ParentFont = False + TabOrder = 2 + end + object OutputFolderRefButton: TButton + Left = 464 + Top = 46 + Width = 49 + Height = 20 + Caption = '参照 ...' + TabOrder = 3 + OnClick = OutputFolderRefButtonClick + end + object OverwriteCheckBox: TCheckBox + Left = 16 + Top = 72 + Width = 313 + Height = 17 + Caption = '同名のファイルがあった場合に上書きする(&O)' + TabOrder = 4 + end + end + object CloseButton: TButton + Left = 460 + Top = 360 + Width = 75 + Height = 21 + Cancel = True + Caption = '閉じる(&X)' + TabOrder = 5 + OnClick = CloseButtonClick + end + object OpaqueOutputFormatGroupBox: TGroupBox + Left = 8 + Top = 32 + Width = 129 + Height = 209 + Caption = '不透明な画像(&Q)' + TabOrder = 1 + object OpaqueBMPFormatRadioButton: TRadioButton + Left = 16 + Top = 24 + Width = 97 + Height = 17 + Caption = '24bit &BMP' + TabOrder = 0 + OnClick = OpaqueBMPFormatRadioButtonClick + end + object OpaquePNGFormatRadioButton: TRadioButton + Left = 16 + Top = 40 + Width = 97 + Height = 17 + Caption = '&PNG' + Checked = True + TabOrder = 1 + TabStop = True + OnClick = OpaquePNGFormatRadioButtonClick + end + object OpaqueTLG5FormatRadioButton: TRadioButton + Left = 16 + Top = 56 + Width = 97 + Height = 17 + Caption = '&TLG5' + TabOrder = 2 + OnClick = OpaqueTLG5FormatRadioButtonClick + end + object OpaqueJPEGFormatRadioButton: TRadioButton + Left = 16 + Top = 88 + Width = 97 + Height = 17 + Caption = '&JPEG' + TabOrder = 4 + OnClick = OpaqueJPEGFormatRadioButtonClick + end + object OpaqueTLG6FormatRadioButton: TRadioButton + Left = 16 + Top = 72 + Width = 97 + Height = 17 + Caption = 'TL&G6' + TabOrder = 3 + OnClick = OpaqueTLG6FormatRadioButtonClick + end + object OpaqueJPEGOptionButton: TButton + Left = 32 + Top = 109 + Width = 73 + Height = 20 + Caption = 'JPEG設定 ...' + TabOrder = 5 + OnClick = OpaqueJPEGOptionButtonClick + end + end + object DoNotShowLogWhenNoErrorCheckBox: TCheckBox + Left = 8 + Top = 361 + Width = 361 + Height = 17 + Caption = 'エラーが発生しなかった場合はログを表示しない(&K)' + TabOrder = 4 + end + object ExpandButton: TCheckBox + Left = 312 + Top = 6 + Width = 129 + Height = 17 + Caption = 'オプションを表示(&V)' + TabOrder = 0 + OnClick = ExpandButtonClick + end +end diff --git a/tools/win32/krdevui/tpc/TPCMainUnit.h b/tools/win32/krdevui/tpc/TPCMainUnit.h new file mode 100644 index 0000000..3339ea7 --- /dev/null +++ b/tools/win32/krdevui/tpc/TPCMainUnit.h @@ -0,0 +1,110 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef TPCMainUnitH +#define TPCMainUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TTPCMainForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TGroupBox *TranspOuputFormatGroupBox; + TRadioButton *TranspBMPFormatRadioButton; + TRadioButton *TranspPNGFormatRadioButton; + TRadioButton *TranspSeparatedFormatRadioButton; + TLabel *TranspMainFormatLabel; + TLabel *TranspMaskFormatLabel; + TComboBox *TranspMainFormatComboBox; + TComboBox *TranspMaskFormatComboBox; + TGroupBox *OutputFolderGroup; + TRadioButton *SameFolderRadioButton; + TRadioButton *SpecifyFolderRadioButton; + TEdit *OutputFolderEdit; + TButton *OutputFolderRefButton; + TLabel *Label1; + TButton *CloseButton; + TCheckBox *OverwriteCheckBox; + TButton *TranspMainJPEGOptionButton; + TButton *TranspMaskJPEGOptionButton; + TLabel *TranspFullTranspColorMethodLabel; + TComboBox *TranspFullTranspColorMethodComboBox; + TGroupBox *OpaqueOutputFormatGroupBox; + TRadioButton *TranspTLG5FormatRadioButton; + TRadioButton *OpaqueBMPFormatRadioButton; + TRadioButton *OpaquePNGFormatRadioButton; + TRadioButton *OpaqueTLG5FormatRadioButton; + TRadioButton *OpaqueJPEGFormatRadioButton; + TCheckBox *DoNotShowLogWhenNoErrorCheckBox; + TRadioButton *OpaqueTLG6FormatRadioButton; + TRadioButton *TranspTLG6FormatRadioButton; + TCheckBox *ExpandButton; + TButton *OpaqueJPEGOptionButton; + TCheckBox *TranspOutputAddAlphaFormatCheckBox; + TPanel *Bar1; + TCheckBox *TranspAssumeInputIsAddAlphaCheckBox; + void __fastcall TranspBMPFormatRadioButtonClick(TObject *Sender); + void __fastcall TranspPNGFormatRadioButtonClick(TObject *Sender); + void __fastcall TranspSeparatedFormatRadioButtonClick(TObject *Sender); + void __fastcall SameFolderRadioButtonClick(TObject *Sender); + void __fastcall SpecifyFolderRadioButtonClick(TObject *Sender); + void __fastcall TranspMainFormatComboBoxChange(TObject *Sender); + void __fastcall TranspMaskFormatComboBoxChange(TObject *Sender); + void __fastcall TranspMainJPEGOptionButtonClick(TObject *Sender); + void __fastcall TranspMaskJPEGOptionButtonClick(TObject *Sender); + void __fastcall CloseButtonClick(TObject *Sender); + void __fastcall FormDestroy(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall OutputFolderRefButtonClick(TObject *Sender); + void __fastcall OpaqueJPEGOptionButtonClick(TObject *Sender); + void __fastcall OpaqueBMPFormatRadioButtonClick(TObject *Sender); + void __fastcall OpaquePNGFormatRadioButtonClick(TObject *Sender); + void __fastcall OpaqueTLG5FormatRadioButtonClick(TObject *Sender); + void __fastcall OpaqueJPEGFormatRadioButtonClick(TObject *Sender); + void __fastcall TranspTLG5FormatRadioButtonClick(TObject *Sender); + void __fastcall OpaqueTLG6FormatRadioButtonClick(TObject *Sender); + void __fastcall TranspTLG6FormatRadioButtonClick(TObject *Sender); + void __fastcall ExpandButtonClick(TObject *Sender); + void __fastcall TranspOutputAddAlphaFormatCheckBoxClick(TObject *Sender); + void __fastcall TranspAssumeInputIsAddAlphaCheckBoxClick(TObject *Sender); +private: // ユーザー宣言 + int TranspMainJPEGQuality; + int TranspMaskJPEGQuality; + int OpaqueJPEGQuality; + int OrgClientHeight; + int OrgCloseButtonTop; + +public: // ユーザー宣言 + __fastcall TTPCMainForm(TComponent* Owner); + +private: + void __fastcall UpdateState(); + + void __fastcall LoadFromIni(); + void __fastcall SaveToIni(); + TStringList * FileList; + AnsiString Log; + +protected: +BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER( WM_DROPFILES, TMessage, WMDropFiles); +END_MESSAGE_MAP(TForm) + void __fastcall WMDropFiles(TMessage &Msg); + +public: + bool __fastcall ProcessFile(AnsiString infile); + +}; +//--------------------------------------------------------------------------- +extern PACKAGE TTPCMainForm *TPCMainForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/tpc/TPCStub.cpp b/tools/win32/krdevui/tpc/TPCStub.cpp new file mode 100644 index 0000000..2baf77b --- /dev/null +++ b/tools/win32/krdevui/tpc/TPCStub.cpp @@ -0,0 +1,11 @@ +//--------------------------------------------------------------------------- + + +#include "TPCStub.h" +#include "TPCMainUnit.h" + + + +//--------------------------------------------------------------------------- + + diff --git a/tools/win32/krdevui/tpc/TPCStub.h b/tools/win32/krdevui/tpc/TPCStub.h new file mode 100644 index 0000000..57d63b4 --- /dev/null +++ b/tools/win32/krdevui/tpc/TPCStub.h @@ -0,0 +1,6 @@ +//--------------------------------------------------------------------------- + +#ifndef TPCStubH +#define TPCStubH +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/tpc/krkrtpc.res b/tools/win32/krdevui/tpc/krkrtpc.res new file mode 100644 index 0000000000000000000000000000000000000000..cb63411079860f20c1bb83ce9b1ecfe1b064f0ac GIT binary patch literal 4572 zcmeI0PiW)E7018Y-O^3krcMuGi47JZl=KfladI%UV1;Z#OPay zwik&W>c|pkL!sB758Ku~X`xV`iVQXM52Z4cLMd&f&9A}-$H>sjwn_Ho^Je_BWiQ=a za@?`L^Y1(F&3kV~Gb2k<9+*W?J(gbiRK}lXOfGN}6Azxr20cb)0^~tXXUXrD>JlH- z>#-oGs?E(!ZT@3Z`+xj7HZ>)iot2eJ zvT9YJL~oPm4T#=t>^JNO#LtMI5kDh-M*NKUz1Z%l zob*-cj8yBI+J7)5e=&9bY3l9}-(p?U3vJC+5|vjvswG_|8$ES#JuOS- zWSz3CTa)z?S-&eA^;IuQ?S*M2l{s}*%IYRH^)?dqdtHro`ZD&4O}Axp$do&>8gfYw zJ#hUIY*Fp$1toJ8b;>L1))MuS4fVS{jru!Gj(vuGhJA*8hJA*8hJ7|-PZl-ZUeH`p zQMt2%kBO4rhPwTp`lB6v^?-!i@MV^jI3tkEw_KiV+;)Xuy5ADHkg>0U=QV0C=}R+Ma|F8 zvlSQlu2k8MHC?-QjV-yR8#iu*@8kCNHd}L`{r!Em=WQmx1wI5HfcL@wz<;&>zUex0 z^?IE)^YdZD#e$qF@XnA@Pgz4sCp{f@#3mhkK7^5zlVOav%_8eEp}iV9QXiK3B&*G4 z>dfk@t%kO(uBOaPe`wPTOvX1o!R$ukEaPeKGCM{`vk#1qZD(RSum$x~>JaQhz zyQUoMY4B-)WjS{RtaG&Hz03R@K1Gdl_ry7zr>_X^ox}Ie;d|%sy>r+P4nN#H_cP?+ zK%?g<4MRF=pQsJP0X;c9(H)z+y9e~-`21Pe3HmsFaD!#n#U@uRs+%HN9Zg7vj_Bop4K<@ZSag< zq|DOzyT(mB#Y@M_v+`e~x$s-aTmB~Um(VS;Jf+zLa957Mjc%QKik=I4NoDe9c}l;; zoIYbY%>Nv9Pro@c;-Q-he-Dk7bAgr4P)6+s9TXSb0Q6ne6}_ruUDk7yOS**SWxcEl z>`WL_&{KMXzk;5`Z@1`?Fvl~Dd0kaqWc&}X=_0L5t~8|c{Qk`y>O2qghQ1r-sxs%R z$S#L*UwgAR|JTAV3m+8zRrqb;_k~{-{!`ed)g{<7x^GO!1$10N%aQC8dK|kVW*F@$ z+U7o74da)wYw3h_OL`Q&--5p!Sofrg4<3ojdId@8G1m4=tj-L67s&HkU?%tD67{Fi zxkPy+@kVI5mu}@-{&$dLO`}#{6}LTG7jMM~ zzZT@KU}u$>K8~*M1F<&uBR>yYVTL#1t{(IJzS5uGaeTq@to(UBA7swnA#*a)9^=9x tq=$n~asAyQk9Fq7`QXfj;9F+-(T)<4_uUwyu#D6aBggl{gJ-Uv{s=!~V59&5 literal 0 HcmV?d00001 diff --git a/tools/win32/krdevui/tpc/png/DeePNGUnit.cpp b/tools/win32/krdevui/tpc/png/DeePNGUnit.cpp new file mode 100644 index 0000000..2b2706f --- /dev/null +++ b/tools/win32/krdevui/tpc/png/DeePNGUnit.cpp @@ -0,0 +1,762 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "DeePNGUnit.h" +#pragma option push -pr +#include // libpng +#pragma option pop + + +//--------------------------------------------------------------------------- +// Check for pure virtual functions +//--------------------------------------------------------------------------- +static void TestDeePNG(void) +{ + new TDeePNG(); +} +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +// Check for grayscale bitmap +//--------------------------------------------------------------------------- +static bool __fastcall IsGrayscaleBitmap(Graphics::TBitmap *dib) +{ + int psize; + int icol; + + switch(dib->PixelFormat) + { + case pfDevice: + return false; + case pf1bit: + psize = 2; break; + case pf4bit: + psize = 16; break; + case pf8bit: + psize = 256; break; + default: + return false; + } + + PALETTEENTRY palentry[256]; + if(GetPaletteEntries(dib->Palette, 0, psize, palentry) != (UINT)psize) + return false; + + + int c = 0; + icol = 255/(psize-1); + for(int i = 0; i < psize; i++) + { + if(c >= 256) c = 255; + if( + palentry[i].peRed != c || + palentry[i].peGreen != c || + palentry[i].peBlue != c) return false; + c += icol; + } + + return true; +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// Get bitmap color depth +//--------------------------------------------------------------------------- +static int __fastcall GetBitmapColorDepth(Graphics::TBitmap *bmp) +{ + switch(bmp->PixelFormat) + { + case pfDevice: + return 0; + case pf1bit: + return 1; + case pf4bit: + return 4; + case pf8bit: + return 8; + case pf15bit: + return 15; + case pf16bit: + return 16; + case pf24bit: + return 24; + case pf32bit: + return 32; + default: + return 0; + } +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// Set color depth to bitmap +//--------------------------------------------------------------------------- +static int __fastcall SetColorDepth(Graphics::TBitmap *dib, int bit) +{ + int psize; + + if(bit == 1) + { + dib->PixelFormat = pf1bit; + psize = 2; + } + else if(bit == 2) + { + dib->PixelFormat = pf4bit; // 2bpp is not supported on Windows + psize = 4; + } + else if(bit == 4) + { + dib->PixelFormat = pf4bit; + psize = 16; + } + else if(bit == 8) + { + dib->PixelFormat = pf8bit; + psize = 256; + } + else if(bit == 16) + { + dib->PixelFormat = pf8bit; // 16Bit grayscale is not supported + psize = 256; + } + else + { + return 0; + } + + return psize; +} +//--------------------------------------------------------------------------- +// Set grayscale palette to bitmap +//--------------------------------------------------------------------------- +void __fastcall SetGrayscalePalette(Graphics::TBitmap *dib, int bit) +{ + int psize; + int icol; + + psize = SetColorDepth(dib, bit); + + icol = 255/(psize-1); + + int i; + int c = 0; + +#pragma pack(push, 1) + struct + { + WORD palVersion; + WORD palNumEntries; + PALETTEENTRY entry[256]; + } pal; +#pragma pack(pop) + + pal.palVersion = 0x300; + pal.palNumEntries = psize; + + for(i = 0; i < psize; i++) + { + if(c >= 256) c = 255; + pal.entry[i].peRed = pal.entry[i].peGreen = pal.entry[i].peBlue = (BYTE)c; + pal.entry[i].peFlags = 0; + c += icol; + } + + dib->Palette = CreatePalette((const LOGPALETTE*)&pal); +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// function - user_malloc_fn +static png_voidp __fastcall DeePNG_malloc(png_structp ps, png_size_t size) +{ + return System::SysGetMem(size); +} +//--------------------------------------------------------------------------- +// function - user_free_fn +static void __fastcall DeePNG_free (png_structp ps,void*/* png_structp*/ mem) +{ + System::SysFreeMem(mem); +} +//--------------------------------------------------------------------------- +// function - user_error_fn +static void __fastcall DeePNG_error (png_structp ps, png_const_charp msg) +{ + throw EDeePNG(msg); +} +//--------------------------------------------------------------------------- +// function - user_warning_fn +static void __fastcall DeePNG_warning (png_structp ps, png_const_charp msg) +{ + // nothing to do +} +//--------------------------------------------------------------------------- +// function - user_read_data +static void __fastcall DeePNG_read_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + ((Classes::TStream *)png_get_io_ptr(png_ptr))->ReadBuffer((void*)data, length); +} +//--------------------------------------------------------------------------- +// function - user_write_data +static void __fastcall DeePNG_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +{ + ((Classes::TStream *)png_get_io_ptr(png_ptr))->WriteBuffer((void*)data, length); +} +//--------------------------------------------------------------------------- +// function - user_flush +static void __fastcall DeePNG_flush(png_structp png_ptr) +{ + // nothing to do +} +//--------------------------------------------------------------------------- +// user supplied function - read_row_callback +static void __fastcall DeePNG_read_row_callback(png_structp png_ptr, png_uint_32 row, int pass) +{ + +} +//--------------------------------------------------------------------------- +// read_chunk_callback +static int __fastcall PNG_read_chunk_callback(png_structp png_ptr,png_unknown_chunkp chunk) +{ + // handle vpAg chunk (this will contain the virtual page size of the image) + // vpAg chunk can be embeded by ImageMagick -trim option etc. + // we don't care about how the chunk bit properties are being provided. + if( (chunk->name[0] == 0x76/*'v'*/ || chunk->name[0] == 0x56/*'V'*/) && + (chunk->name[1] == 0x70/*'p'*/ || chunk->name[1] == 0x50/*'P'*/) && + (chunk->name[2] == 0x61/*'a'*/ || chunk->name[2] == 0x41/*'A'*/) && + (chunk->name[3] == 0x67/*'g'*/ || chunk->name[3] == 0x47/*'G'*/) && chunk->size >= 9) + { + TDeePNG * deepng = + reinterpret_cast(png_get_user_chunk_ptr(png_ptr)); + // vpAg found + /* + uint32 width + uint32 height + uchar unit + */ + // be careful because the integers are stored in network byte order + #define PNG_read_be32(a) (((unsigned long)(a)[0]<<24)+\ + ((unsigned long)(a)[1]<<16)+((unsigned long)(a)[2]<<8)+\ + ((unsigned long)(a)[3])) + unsigned long width = PNG_read_be32(chunk->data+0); + unsigned long height = PNG_read_be32(chunk->data+4); + unsigned char unit = chunk->data[8]; + + // set vpag information + deepng->SetVirtualPage(width, height, unit); + + return 1; // chunk read success + } + return 0; // did not recognize +} + + +//--------------------------------------------------------------------------- +// TDeePNG +//--------------------------------------------------------------------------- +__fastcall TDeePNG::TDeePNG(void) +{ + // constructor + ofs_set = false; + vpag_set = false; +} +//--------------------------------------------------------------------------- +__fastcall TDeePNG::~TDeePNG(void) +{ + // desturctor +} +//--------------------------------------------------------------------------- +void __fastcall TDeePNG::LoadFromStream(Classes::TStream * Stream) +{ + // LoadFromStream + + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + png_infop end_info = NULL; + + png_bytep *row_pointers = NULL; + BYTE *image = NULL; + + png_uint_32 i; + + try + { + // create png_struct + png_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, + (png_voidp)this, DeePNG_error, DeePNG_warning, + (png_voidp)this, DeePNG_malloc, DeePNG_free); + + // set read_chunk_callback + png_set_read_user_chunk_fn(png_ptr, + reinterpret_cast(this), + PNG_read_chunk_callback); + png_set_keep_unknown_chunks(png_ptr, 2, NULL, 0); + // keep only if safe-to-copy chunks, for all unknown chunks + + // create png_info + info_ptr = png_create_info_struct(png_ptr); + + // create end_info + end_info = png_create_info_struct(png_ptr); + + // set stream input functions + png_set_read_fn(png_ptr, (voidp)Stream, DeePNG_read_data); + + // set read_row_callback + png_set_read_status_fn(png_ptr, DeePNG_read_row_callback); + + // call png_read_info + png_read_info(png_ptr, info_ptr); + + // retrieve IHDR + png_uint_32 width, height; + int bit_depth, color_type, interlace_type, compression_type, filter_type; + png_get_IHDR(png_ptr,info_ptr, &width, &height, &bit_depth, &color_type, + &interlace_type, &compression_type, &filter_type); + + // expand palletted image which has transparent color, to 32bpp + if (png_get_valid(png_ptr, info_ptr,PNG_INFO_tRNS)) + { + png_set_expand(png_ptr); + color_type=PNG_COLOR_TYPE_RGB_ALPHA; + } + + // analyse IHDR ( color_type ) + switch(color_type) + { + case PNG_COLOR_TYPE_GRAY_ALPHA: + PixelFormat=pf32bit; + break; + case PNG_COLOR_TYPE_GRAY: + // w/b + SetGrayscalePalette(this,bit_depth); + break; + case PNG_COLOR_TYPE_PALETTE: + SetColorDepth(this,bit_depth); + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + PixelFormat=pf32bit; + break; + case PNG_COLOR_TYPE_RGB: + PixelFormat=pf24bit; + break; + default: + throw EDeePNG("EDeePNG : Non-supported color type."); + } + + // retrieve offset information + png_int_32 offset_x, offset_y; + int offset_unit_type; + if(png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &offset_unit_type)) + { + ofs_x = offset_x; + ofs_y = offset_y; + ofs_unit = offset_unit_type; + ofs_set = true; + } + else + { + ofs_set = false; + } + + // check size + if(width>=65536 || height>=65536) + { + throw EDeePNG("EDeePNG : Too large image size."); + } + + + // retrieve palette + if(color_type == PNG_COLOR_TYPE_PALETTE) + { + int num_palette; + png_color *palette = NULL; + png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); + + int i; + #pragma pack(push, 1) + struct + { + WORD palVersion; + WORD palNumEntries; + PALETTEENTRY entry[256]; + } pal; + #pragma pack(pop) + pal.palVersion = 0x300; + pal.palNumEntries = num_palette; + for(i = 0; i < num_palette; i++) + { + pal.entry[i].peRed = palette[i].red; + pal.entry[i].peGreen = palette[i].green; + pal.entry[i].peBlue = palette[i].blue; + pal.entry[i].peFlags = 0; + } + Palette = CreatePalette((const LOGPALETTE*)&pal); + } + + // collapse 16bit precision data to 8bit + if(bit_depth == 16) png_set_strip_16(png_ptr); + + // change color component order + if (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_bgr(png_ptr); + + // call png_read_update_info ... + png_read_update_info(png_ptr, info_ptr); + + // set size + Width=width, Height=height; + + // allocate memory for row_pointers + row_pointers = new png_bytep[height]; + png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr); + image = new BYTE[rowbytes*height]; + for(i = 0;i < height; i++) + { + row_pointers[i] = image + i*rowbytes; + } + + // load image + png_read_image(png_ptr, row_pointers); + + // finish loading image + png_read_end(png_ptr, info_ptr); + + // set image to ScanLines + + BYTE *imageptr = image; + if(color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + // IA IA IA .... + + for(i = 0; i < height; i++) + { + BYTE *scanptr = (BYTE*)ScanLine[i]; + png_uint_32 j; + for(j = 0; j < width; j++) + { + BYTE i = *(imageptr++); + scanptr[0] = i; + scanptr[1] = i; + scanptr[2] = i; + scanptr[3] = *(imageptr++); + scanptr += 4; + } + } + } + else + { + // intact copy + + for(i = 0; i < height; i++) + { + BYTE *scanptr = (BYTE*)ScanLine[i]; + memcpy(scanptr, imageptr, rowbytes); + imageptr += rowbytes; + } + + + } + } + catch(...) + { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + if(row_pointers) delete [] row_pointers; + if(image) delete [] image; + throw; + } + + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + if(row_pointers) delete [] row_pointers; + if(image) delete [] image; +} +//--------------------------------------------------------------------------- +void __fastcall TDeePNG::SaveToStream(Classes::TStream * Stream) +{ + // SaveToStream method + // warning: this method would change the pixelformat to pf24bit + // if the pixelformat is pfDevice, pf15bit, pf16bit, or pfCustom. + + + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + png_bytep row_buffer = NULL; + + try + { + // create png_struct + png_ptr = png_create_write_struct_2 + (PNG_LIBPNG_VER_STRING, + (png_voidp)this, DeePNG_error, DeePNG_warning, + (png_voidp)this, DeePNG_malloc, DeePNG_free); + + + // create png_info + info_ptr = png_create_info_struct(png_ptr); + + // set write function + png_set_write_fn(png_ptr, (png_voidp)Stream, + DeePNG_write_data, DeePNG_flush); + + + // set IHDR + if(PixelFormat == pfDevice || PixelFormat == pf15bit || + PixelFormat == pf16bit || PixelFormat == pfCustom) + PixelFormat = pf24bit; + + bool grayscale = IsGrayscaleBitmap(this); + int colordepth = GetBitmapColorDepth(this); + + int w = Width; + int h = Height; + + int color_type; + if(grayscale) + color_type = PNG_COLOR_TYPE_GRAY; + else if(colordepth <= 8) + color_type = PNG_COLOR_TYPE_PALETTE; + else if(colordepth == 32) + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else + color_type = PNG_COLOR_TYPE_RGB; + + png_set_IHDR(png_ptr, info_ptr, w, h, + colordepth < 8 ? colordepth : 8, + color_type, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + // set oFFs + if(ofs_set) + png_set_oFFs(png_ptr, info_ptr, ofs_x, ofs_y, ofs_unit); + + // set palette + if(color_type == PNG_COLOR_TYPE_PALETTE) + { + png_color *palette = (png_colorp)png_malloc(png_ptr, 256 * sizeof(png_color)); + PALETTEENTRY palentry[256]; + int num_palette = GetPaletteEntries(Palette, 0, (1<>24) & 0xff), \ + ((unsigned char *)(p))[1] = (unsigned char)(((a) >>16) & 0xff), \ + ((unsigned char *)(p))[2] = (unsigned char)(((a) >> 8) & 0xff), \ + ((unsigned char *)(p))[3] = (unsigned char)(((a) ) & 0xff) ) + PNG_write_be32(vpag_chunk_data, vpag_w); + PNG_write_be32(vpag_chunk_data + 4, vpag_h); + vpag_chunk_data[8] = (unsigned char)vpag_unit; + png_write_chunk(png_ptr, png_vpAg, vpag_chunk_data, 9); + } + +/* + // change RGB order + if(color_type = PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) + png_set_bgr(png_ptr); + // ???? why this does not work ? +*/ + // write image + if(color_type == PNG_COLOR_TYPE_RGB) + { + row_buffer = (png_bytep)png_malloc(png_ptr, 3 * w + 6); + try + { + png_bytep row_pointer = row_buffer; + + for(int i = 0; i < h; i++) + { + png_bytep in = (png_bytep)ScanLine[i]; + png_bytep out = row_buffer; + for(int x = 0; x < w; x++) + { + out[2] = in[0]; + out[1] = in[1]; + out[0] = in[2]; + out += 3; + in += 3; + } + png_write_row(png_ptr, row_pointer); + } + } + catch(...) + { + png_free(png_ptr, row_buffer); + throw; + } + png_free(png_ptr, row_buffer); + } + else if(color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + row_buffer = (png_bytep)png_malloc(png_ptr, 4 * w + 6); + try + { + png_bytep row_pointer = row_buffer; + + for(int i = 0; i < h; i++) + { + png_bytep in = (png_bytep)ScanLine[i]; + png_bytep out = row_buffer; + for(int x = 0; x < w; x++) + { + out[2] = in[0]; + out[1] = in[1]; + out[0] = in[2]; + out[3] = in[3]; + out += 4; + in += 4; + } + png_write_row(png_ptr, row_pointer); + } + } + catch(...) + { + png_free(png_ptr, row_buffer); + throw; + } + png_free(png_ptr, row_buffer); + } + else + { + for(int i = 0; i < h; i++) + { + png_bytep row_pointer = (png_bytep)ScanLine[i]; + png_write_row(png_ptr, row_pointer); + } + } + + + // finish writing + png_write_end(png_ptr, info_ptr); + + } + catch(...) + { + png_destroy_write_struct(&png_ptr, &info_ptr); + throw; + } + + png_destroy_write_struct(&png_ptr, &info_ptr); +} +//--------------------------------------------------------------------------- +void TDeePNG::SetTags(TStringList *tags) +{ + if(tags) + { + AnsiString offs_x = tags->Values["offs_x"]; + AnsiString offs_y = tags->Values["offs_y"]; + AnsiString offs_unit = tags->Values["offs_unit"]; + if(offs_x != "" && offs_y != "" && + (offs_unit == "pixel" || offs_unit == "micrometer")) + { + int unit ; + if(offs_unit == "pixel") + unit = PNG_OFFSET_PIXEL; + else if(offs_unit == "micrometer") + unit = PNG_OFFSET_MICROMETER; + SetOffset(offs_x.ToInt(), offs_y.ToInt(), unit); + } + } + + if(tags) + { + AnsiString vpag_w = tags->Values["vpag_w"]; + AnsiString vpag_h = tags->Values["vpag_h"]; + AnsiString vpag_unit = tags->Values["vpag_unit"]; + if(vpag_w != "" && vpag_h != "" && + (vpag_unit == "pixel" || vpag_unit == "micrometer")) + { + int unit ; + if(vpag_unit == "pixel") + unit = PNG_OFFSET_PIXEL; + else if(vpag_unit == "micrometer") + unit = PNG_OFFSET_MICROMETER; + SetVirtualPage(vpag_w.ToInt(), vpag_h.ToInt(), unit); + } + } +} +//--------------------------------------------------------------------------- +void TDeePNG::AppendTags(TStringList *tags) +{ + if(tags && ofs_set) + { + tags->Append("offs_x=" + AnsiString(ofs_x)); + tags->Append("offs_y=" + AnsiString(ofs_y)); + switch(ofs_unit) + { + case PNG_OFFSET_PIXEL: + tags->Append("offs_unit=pixel"); + break; + case PNG_OFFSET_MICROMETER: + tags->Append("offs_unit=micrometer"); + break; + default: + tags->Append("offs_unit=unknown"); + break; + } + } + + if(tags && vpag_set) + { + tags->Append("vpag_w=" + AnsiString(vpag_w)); + tags->Append("vpag_h=" + AnsiString(vpag_h)); + switch(vpag_unit) + { + case PNG_OFFSET_PIXEL: + tags->Append("vpag_unit=pixel"); + break; + case PNG_OFFSET_MICROMETER: + tags->Append("vpag_unit=micrometer"); + break; + default: + tags->Append("vpag_unit=unknown"); + break; + } + } +} +//--------------------------------------------------------------------------- +static void InitTDeePNG() +{ + TPicture::RegisterFileFormat( + __classid(TPicture), "png", "Portable Network Graphic", + __classid(TDeePNG)); +} +static void UninitTDeePNG() +{ + TPicture::UnregisterGraphicClass(__classid(TPicture),__classid(TDeePNG)); +} +#pragma startup InitTDeePNG +#pragma exit UninitTDeePNG +//--------------------------------------------------------------------------- + +//#pragma package(smart_init) diff --git a/tools/win32/krdevui/tpc/png/DeePNGUnit.h b/tools/win32/krdevui/tpc/png/DeePNGUnit.h new file mode 100644 index 0000000..6dbd0da --- /dev/null +++ b/tools/win32/krdevui/tpc/png/DeePNGUnit.h @@ -0,0 +1,106 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef DeePNGUnitH +#define DeePNGUnitH + +#include + +//--------------------------------------------------------------------------- +extern void __fastcall SetGrayscalePalette(Graphics::TBitmap *dib, int bit); +//--------------------------------------------------------------------------- +// 例外クラス +class EDeePNG : public Exception +{ +public: + __fastcall EDeePNG(const System::AnsiString Msg) : Sysutils::Exception( + Msg) { } + __fastcall EDeePNG(const System::AnsiString Msg, const System::TVarRec + * Args, const int Args_Size) : Sysutils::Exception(Msg, Args, Args_Size) { } + __fastcall EDeePNG(int Ident, Extended Dummy) : Sysutils::Exception( + Ident, Dummy) { } + __fastcall EDeePNG(int Ident, const System::TVarRec * Args, const + int Args_Size) : Sysutils::Exception(Ident, Args, Args_Size) { } + __fastcall EDeePNG(const System::AnsiString Msg, int AHelpContext + ) : Sysutils::Exception(Msg, AHelpContext) { } + __fastcall EDeePNG(const System::AnsiString Msg, const System::TVarRec + * Args, const int Args_Size, int AHelpContext) : Sysutils::Exception(Msg, + Args, Args_Size, AHelpContext) { } + __fastcall EDeePNG(int Ident, int AHelpContext) : Sysutils:: + Exception(Ident, AHelpContext) { } + __fastcall EDeePNG(int Ident, const System::TVarRec * Args + , const int Args_Size, int AHelpContext) : Sysutils::Exception(Ident, + Args, Args_Size, AHelpContext) { } + + __fastcall virtual ~EDeePNG(void) { } + +}; +//--------------------------------------------------------------------------- +// TDeePNG クラス +class TDeePNG : public Graphics::TBitmap +{ +private: +protected: + bool ofs_set; + int ofs_x; + int ofs_y; + int ofs_unit; + bool vpag_set; + int vpag_w; + int vpag_h; + int vpag_unit; + +public: + // コンストラクタとデストラクタ + __fastcall TDeePNG(void); + __fastcall ~TDeePNG(void); + + // Stream I/O のオーバーライド + void __fastcall LoadFromStream(Classes::TStream * Stream); + void __fastcall SaveToStream(Classes::TStream * Stream); + + // オフセット + void SetOffset(int ofs_x, int ofs_y, int ofs_unit) + { + this->ofs_x = ofs_x; + this->ofs_y = ofs_y; + this->ofs_unit = ofs_unit; + this->ofs_set = true; + } + bool GetOffset(int &ofs_x, int &ofs_y, int &ofs_unit) + { + if(!this->ofs_set) return false; + ofs_x = this->ofs_x; + ofs_y = this->ofs_y; + ofs_unit = this->ofs_unit; + return true; + } + // 仮想ページサイズ + void SetVirtualPage(int vpag_w, int vpag_h, int vpag_unit) + { + this->vpag_w = vpag_w; + this->vpag_h = vpag_h; + this->vpag_unit = vpag_unit; + this->vpag_set = true; + } + bool GetVirtualPage(int &vpag_w, int &vpag_h, int &vpag_unit) + { + if(!this->vpag_set) return false; + vpag_w = this->vpag_w; + vpag_h = this->vpag_h; + vpag_unit = this->vpag_unit; + return true; + } + // タグ + void SetTags(TStringList *tags); // set tag information from tags + void AppendTags(TStringList *tags); // append tag information to tags + +public: +}; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/tpc/psd/DeePSDUnit.cpp b/tools/win32/krdevui/tpc/psd/DeePSDUnit.cpp new file mode 100644 index 0000000..a290be7 --- /dev/null +++ b/tools/win32/krdevui/tpc/psd/DeePSDUnit.cpp @@ -0,0 +1,1109 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +/* + This is very limited loader for PSD (Photoshop native data format). + This can only load PSD data of RGB, and the layer is 'normal' blend mode + ('linear dodge' blend mode can also be loaded in additive alpha mode), + 8bit for each color/alpha component. + Otherwise the loading will fail. +*/ +//--------------------------------------------------------------------------- + + +#include +#pragma hdrstop + +#include "DeePSDUnit.h" + + +//--------------------------------------------------------------------------- +// Check for pure virtual functions +//--------------------------------------------------------------------------- +static void TestDeePSD(void) +{ + new TDeePSD(); +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// integer types +//--------------------------------------------------------------------------- +typedef unsigned long tui32; +typedef long ti32; +typedef unsigned short tui16; +typedef short ti16; +typedef unsigned char tui8; +typedef char ti8; +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// Endian converters +//--------------------------------------------------------------------------- +static void SwapBytes32(tui8 * data) +{ + tui8 tmp; + tmp = data[3]; + data[3] = data[0]; + data[0] = tmp; + tmp = data[2]; + data[2] = data[1]; + data[1] = tmp; +} +//--------------------------------------------------------------------------- +static void inline SwapUI32(tui32 & data) { SwapBytes32((tui8*)&data); } +//--------------------------------------------------------------------------- +static void SwapBytes16(tui8 * data) +{ + tui8 tmp; + tmp = data[1]; + data[1] = data[0]; + data[0] = tmp; +} +//--------------------------------------------------------------------------- +static void inline SwapUI16(tui16 & data) { SwapBytes16((tui8*)&data); } +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +// Integer reader +//--------------------------------------------------------------------------- +static tui32 Read32(TStream *in) +{ + tui32 tmp; + in->ReadBuffer(&tmp, 4); + SwapUI32(tmp); + return tmp; +} +//--------------------------------------------------------------------------- +static tui16 Read16(TStream *in) +{ + tui16 tmp; + in->ReadBuffer(&tmp, 2); + SwapUI16(tmp); + return tmp; +} +//--------------------------------------------------------------------------- +static tui8 Read8(TStream *in) +{ + tui8 tmp; + in->ReadBuffer(&tmp, 1); + return tmp; +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// Structure definitions +//--------------------------------------------------------------------------- +#pragma pack(push, 1) +struct TPSDFileHeader +{ + tui8 Signature[4]; // always "8BPS" + tui16 Version; // BE; always 1 + tui8 Reserved[6]; // always zero + tui16 Channels; // BE + tui32 Rows; // BE + tui32 Columns; // BE + tui16 Depth; // BE + tui16 Mode; // BE + + void ToLittleEndian() + { + SwapBytes16((tui8*)&Version); + SwapBytes16((tui8*)&Channels); + SwapBytes16((tui8*)&Depth); + SwapBytes16((tui8*)&Mode); + SwapBytes32((tui8*)&Rows); + SwapBytes32((tui8*)&Columns); + } +}; + +struct TPSDChannelInfo +{ + ti16 ID; + tui32 Length; +}; + +struct TPSDLayerRecord +{ + ti32 Top; + ti32 Left; + ti32 Bottom; + ti32 Right; + tui16 Channels; + + TPSDChannelInfo ChannelInfo[5]; + + tui8 BlendSig[4]; + tui8 BlendMode[4]; + + tui8 Opacity; + tui8 Clipping; + tui8 Flags; + + tui8 Reserved; +}; + +#pragma pack(pop) +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +// 'normal' blend function +//--------------------------------------------------------------------------- +static unsigned char OpacityOnOpacityTable[256*256]; +static unsigned char NegativeMulTable[256*256]; +static bool TableInit = false; +#define ALPHA_BLEND(s, d, opa) (((d)*(255-(opa)) + (s)*(opa)) * ((1<<20) / 255) >> 20) +//--------------------------------------------------------------------------- +static void InitTable() +{ + if(TableInit) return; + + for(int a = 0; a<256; a++) + { + for(int b = 0; b<256; b++) + { + float c; + int ci; + int addr = b*256+ a; + + if(a) + { + float at = a/255.0, bt = b/255.0; + c = bt / at; + c /= (1.0 - bt + c); + ci = (int)(c*255); + if(ci>=256) ci = 255; /* will not overflow... */ + } + else + { + ci=255; + } + + OpacityOnOpacityTable[addr]=(unsigned char)ci; + /* higher byte of the index is source opacity */ + /* lower byte of the index is destination opacity */ + + NegativeMulTable[addr] = (unsigned char) + ( 255 - (255-a)*(255-b)/ 255 ); + } + } + + TableInit = true; +} +//--------------------------------------------------------------------------- +static void NormalBlendFunc(tui32 *dest, tui32 *src, int len) +{ + InitTable(); + + while(len--) + { + tui32 s = *src; + tui32 d = *dest; + tui32 r; + int addr = ((s >> 16) & 0xff00) + (d >> 24); // table addr + r = NegativeMulTable[addr] << 24; + int sopa = OpacityOnOpacityTable[addr]; + + int sv, dv; + sv = s & 0xff; + dv = d & 0xff; + r |= ALPHA_BLEND(sv, dv, sopa); + sv = (s & 0xff00)>>8; + dv = (d & 0xff00)>>8; + r |= (ALPHA_BLEND(sv, dv, sopa) << 8); + sv = (s & 0xff0000)>>16; + dv = (d & 0xff0000)>>16; + r |= (ALPHA_BLEND(sv, dv, sopa) << 16); + *dest = r; + + src++; + dest++; + } +} +//--------------------------------------------------------------------------- + + + + + + +//--------------------------------------------------------------------------- +// 'additive' blend function +//--------------------------------------------------------------------------- +static inline int satadd(int a, int b) +{ + int r = a + b; + if(r > 255) r = 255; + r |= -(r > 255); + return r & 0xff; +} +static inline int ratio(int a, int b, int ratio) +{ + // return (b*ratio + a*(255-ratio)) / 255 + return ((b*ratio + a*(255-ratio)) * ((1<<20) / 255)) >> 20; +} +static void AdditiveBlendFunc(tui32 * dest , tui32 * src, int len) +{ + while(len--) + { + tui32 s = *src; + tui32 d = *dest; + + int opa = s >> 24; + + *dest = + (ratio((d )&0xff, satadd((d )&0xff, (s )&0xff), opa) )+ + (ratio((d>> 8)&0xff, satadd((d>> 8)&0xff, (s>> 8)&0xff), opa)<< 8)+ + (ratio((d>>16)&0xff, satadd((d>>16)&0xff, (s>>16)&0xff), opa)<<16)+ + (d & 0xff000000) ; + src++; + dest++; + } +} +//--------------------------------------------------------------------------- +static void AdditiveCopyFunc(tui32 * dest , tui32 * src, int len) +{ + while(len--) + { + tui32 s = *src; + tui32 d = *dest; + + int opa = s >> 24; + + *dest = ((((s )&0xff) * opa / 255) ) + + ((((s>> 8)&0xff) * opa / 255)<<8 ) + + ((((s>>16)&0xff) * opa / 255)<<16) ; + src++; + dest++; + } +} +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +// copy rectangle +//--------------------------------------------------------------------------- +//--------------------------------------------------------------------------- +static void CopyBitmapRect(Graphics::TBitmap *dest, int x, int y, + Graphics::TBitmap *ref, TRect refrect, int mode) +{ + // Copy bitmap rectangle + + // bound check + int bmpw, bmph; + + bmpw = ref->Width; + bmph = ref->Height; + + if(refrect.left < 0) + x -= refrect.left, refrect.left = 0; + if(refrect.right > bmpw) + refrect.right = bmpw; + + if(refrect.left >= refrect.right) return; + + if(refrect.top < 0) + y -= refrect.top, refrect.top = 0; + if(refrect.bottom > bmph) + refrect.bottom = bmph; + + if(refrect.top >= refrect.bottom) return; + + bmpw = dest->Width; + bmph = dest->Height; + + TRect rect; + rect.left = x; + rect.top = y; + rect.right = rect.left + (refrect.right - refrect.left); + rect.bottom = rect.top + (refrect.bottom - refrect.top); + + if(rect.left < 0) + { + refrect.left += -rect.left; + rect.left = 0; + } + + if(rect.right > bmpw) + { + refrect.right -= (rect.right - bmpw); + rect.right = bmpw; + } + + if(refrect.left >= refrect.right) return; // not drawable + + if(rect.top < 0) + { + refrect.top += -rect.top; + rect.top = 0; + } + + if(rect.bottom > bmph) + { + refrect.bottom -= (rect.bottom - bmph); + rect.bottom = bmph; + } + + if(refrect.top >= refrect.bottom) return; // not drawable + + + // transfer + int w = rect.right - rect.left; + int h = rect.bottom - rect.top; + + for(int y = 0; y < h; y ++) + { + tui32 *d = (tui32*)dest->ScanLine[y + rect.top]; + tui32 *s = (tui32*)ref->ScanLine[y + refrect.top]; + if(mode == 0) + memmove(d+ rect.left, s + refrect.left, w * sizeof(tui32)); + else if(mode == 1) + NormalBlendFunc(d+ rect.left, s + refrect.left, w); + else if(mode == 2) + AdditiveCopyFunc(d + rect.left, s + refrect.left, w); + else if(mode == 3) + AdditiveBlendFunc(d + rect.left, s + refrect.left, w); + } +} +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// Set opacity to image +//--------------------------------------------------------------------------- +static void SetBitmapOpacity(Graphics::TBitmap *bmp, int opa) +{ + // bmp must be a 32bpp bitmap + + int w = bmp->Width; + int h = bmp->Height; + + opa <<= 20; + opa /= 255; + + for(int y = 0; y < h; y++) + { + tui32 *scl = (tui32*)bmp->ScanLine[y]; + for(int x = 0; x< w; x++) + { + tui32 d = scl[x]; + int o = d >> 24; + o *= opa; + o >>= 20; + d &= 0xffffff; + d |= o << 24; + scl[x] = d; + } + } + +} +//--------------------------------------------------------------------------- +/* +static void SetBitmapAdditiveOpacity(Graphics::TBitmap *bmp, int opa) +{ + // bmp must be a 32bpp bitmap + + int w = bmp->Width; + int h = bmp->Height; + + opa <<= 20; + opa /= 255; + + for(int y = 0; y < h; y++) + { + tui32 *scl = (tui32*)bmp->ScanLine[y]; + for(int x = 0; x< w; x++) + { + tui32 d = scl[x]; + + scl[x] = + ((((d ) & 0xff) * opa >> 20) )+ + ((((d>> 8) & 0xff) * opa >> 20) << 8)+ + ((((d>>16) & 0xff) * opa >> 20) <<16); + + } + } +} +*/ +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// ConvertAlphaToAddAlpha +//--------------------------------------------------------------------------- +void ConvertAlphaToAddAlpha(Graphics::TBitmap *in) +{ + // convert alpha to additive alpha + + int w = in->Width; + int h = in->Height; + + for(int y = 0; y < h; y++) + { + DWORD * p = (DWORD *)in->ScanLine[y]; + for(int x = 0; x < w; x++) + { + DWORD s = p[x]; + int alpha = (s >> 24) & 0xff; + + p[x] = (s & 0xff000000) + + ((((s ) & 0xff) * alpha / 255) )+ + ((((s>>8 ) & 0xff) * alpha / 255)<<8 )+ + ((((s>>16) & 0xff) * alpha / 255)<<16) ; + } + } +} +//--------------------------------------------------------------------------- + + + + +//--------------------------------------------------------------------------- +// Read pixel data +//--------------------------------------------------------------------------- +static Graphics::TBitmap *ReadPixelData30(TStream *Stream, + int w, int h) +{ + // read Photoshop 3.0 data + // channel count must be 3 + + Graphics::TBitmap *bmp = new Graphics::TBitmap(); + + try + { + // set BMP size + bmp->PixelFormat = pf24bit; + bmp->Width = w; + bmp->Height = h; + + // for each channel + int mode = Read16(Stream); + + if(mode == 0) + { + // uncompressed image + throw EDeePSD("TDeePSD: Uncompressed Photoshop 3.0 image is not supported." + AnsiString(mode)); + } + else if(mode == 1) + { + // RLE compressed image + tui16 * linelen = NULL; + tui8 * linebuf = NULL; + try + { + int h3 = h * 3; + linelen = new tui16[h3]; + tui16 * ll = linelen; + Stream->ReadBuffer(linelen, h3 * sizeof(tui16)); + for(int i = 0; i < h3; i++) + SwapBytes16((tui8*)(linelen + i)); + + for(int c = 0; c < 3; c++) + { + for(int y = 0; y < h; y++) + { + tui8 *scl = (tui8*)bmp->ScanLine[y] + "\x02\x01\x00"[c]; + + linebuf = new tui8[*ll]; + + Stream->ReadBuffer(linebuf, *ll); + + ll++; + + int x = 0; + tui8 *lp = linebuf; + while(x < w) + { + int n; + n = (int)*lp; + lp++; + if(n >= 128) n -= 256; + if(n == -128) + { + ;// ?? no operation + } + else if(n < 0) // run length + { + n = -n + 1; + tui8 v = *lp; + lp++; + while(n--) + *scl = v, scl += 3, x++; + } + else + { + // literal copy + n++; + while(n--) + *scl = *(lp++), scl += 3, x++; + } + + } + + delete [] linebuf; + linebuf = NULL; + } + } + } + catch(...) + { + if(linelen) delete [] linelen; + if(linebuf) delete [] linebuf; + throw; + } + if(linelen) delete [] linelen; + if(linebuf) delete [] linebuf; + } + else + { + throw EDeePSD("TDeePSD: The image has " + "unsupported compression mode : " + AnsiString(mode)); + } + } + catch(...) + { + delete bmp; + throw; + } + + return bmp; +} +//--------------------------------------------------------------------------- +static Graphics::TBitmap *ReadPixelData(TStream *Stream, TPSDLayerRecord *lr, + int laynum) +{ + int w = lr->Right - lr->Left; + int h = lr->Bottom - lr->Top; + if(w < 0) w = -w; // is this needed? + if(h < 0) h = -h; + + Graphics::TBitmap *bmp = new Graphics::TBitmap(); + + try + { + // set BMP size + bmp->PixelFormat = pf32bit; + bmp->Width = w; + bmp->Height = h; + + // clear BMP + for(int y = 0; y < h; y++) + { + DWORD *scl = (DWORD*)bmp->ScanLine[y]; + for(int x = 0; x < w; x++) + { + scl[x] = 0xff000000; + } + } + + // for each channel + for(int ch = 0; ch < lr->Channels; ch++) + { + int readstart = Stream->Position; + int mode = Read16(Stream); + int bitpos; + bool readskip = false; + tui32 bitmask; + switch(lr->ChannelInfo[ch].ID) + { + case -2: + readskip = true; break; // user supplied layer mask + case -1: + bitpos = 24; bitmask = 0x00ffffff; break; // alpha + case 0: + bitpos = 16; bitmask = 0xff00ffff; break; // R + case 1: + bitpos = 8; bitmask = 0xffff00ff; break; // G + case 2: + bitpos = 0; bitmask = 0xffffff00; break; // B + default: + readskip = true; break; // unknown channel ID +// throw EDeePSD("TDeePSD: Layer #" + AnsiString(laynum) + " has " +// "unsupported channel ID : " + +// AnsiString((int)lr->ChannelInfo[ch].ID)); + } + + if(!readskip) + { + + if(mode == 0) + { + // uncompressed image + tui8 * data = new tui8[w * h]; + try + { + Stream->ReadBuffer(data, w * h); + + tui8 *p = data; + for(int y = 0; y < h; y++) + { + tui32 * scl = (tui32*)bmp->ScanLine[y]; + for(int x = 0; x < w; x++) + { + tui32 d = scl[x]; + d &= bitmask; + d |= (*p<ReadBuffer(linelen, h * sizeof(tui16)); + for(int i = 0; i < h; i++) + SwapBytes16((tui8*)(linelen + i)); + for(int y = 0; y < h; y++) + { + tui32 *scl = (tui32*)bmp->ScanLine[y]; + linebuf = new tui8[linelen[y]]; + + Stream->ReadBuffer(linebuf, linelen[y]); + + int x = 0; + tui8 *lp = linebuf; + while(x < w) + { + int n; + n = (int)*lp; + lp++; + if(n >= 128) n -= 256; + if(n == -128) + { + ;// ?? no operation + } + else if(n < 0) // run length + { + n = -n + 1; + tui32 v = *lp << bitpos; + lp++; + while(n--) + { + tui32 d = scl[x]; + d &= bitmask; + d |= v; + scl[x] = d; + x++; + } + } + else + { + // literal copy + n++; + while(n--) + { + tui32 d = scl[x]; + d &= bitmask; + d |= (*lp << bitpos); + lp++; + scl[x] = d; + x++; + } + } + + } + + delete [] linebuf; + linebuf = NULL; + } + } + catch(...) + { + if(linelen) delete [] linelen; + if(linebuf) delete [] linebuf; + throw; + } + if(linelen) delete [] linelen; + if(linebuf) delete [] linebuf; + } + else + { + throw EDeePSD("TDeePSD: Layer #" + AnsiString(laynum) + " has " + "unsupported compression mode : " + AnsiString(mode)); + } + } + + Stream->Position = readstart + lr->ChannelInfo[ch].Length; + } + } + catch(...) + { + delete bmp; + throw; + } + + return bmp; +} +//--------------------------------------------------------------------------- + + + + + +//--------------------------------------------------------------------------- +// TDeePSD +//--------------------------------------------------------------------------- +__fastcall TDeePSD::TDeePSD(void) +{ + // constructor + FLayerMode = ""; +} +//--------------------------------------------------------------------------- +__fastcall TDeePSD::~TDeePSD(void) +{ + // desturctor + +} +//--------------------------------------------------------------------------- +void __fastcall TDeePSD::LoadFromStream(Classes::TStream * Stream) +{ + // LoadFromStream + + // check file header + TPSDFileHeader header; + Stream->ReadBuffer(&header, sizeof(header)); + header.ToLittleEndian(); + + if(memcmp(&header.Signature, "8BPS", 4)) + throw EDeePSD("TDeePSD: This is not a PSD file."); + + if(header.Version != 1) + throw EDeePSD("TDeePSD: Invalid PSD version."); + +// if(header.Channels != 4) +// throw EDeePSD("TDeePSD: Unsupported number of channels " + +// AnsiString((int)header.Channels)+ " (must be 4)"); + + if(header.Mode != 3) + throw EDeePSD("TDeePSD: Unsupported color mode (must be RGB)"); + + if(header.Depth != 8) + throw EDeePSD("TDeePSD: Unsupported bits per channel " + + AnsiString((int)header.Depth) + " (must be 8)"); + + // skip Color mode data section + { + tui32 size = Read32(Stream); + Stream->Position += size; + } + + // skip Image resources section + { + tui32 size = Read32(Stream); + Stream->Position += size; + } + + // Set size + PixelFormat = pf32bit; + Width = header.Columns; + Height = header.Rows; + + // clear image + for(int y = 0; y < Height; y++) + memset(ScanLine[y], 0, Width * sizeof(tui32)); + + // read layer info section + int layinfosize = Read32(Stream); // size of layer info section; discard + + if(layinfosize) + { + + Read32(Stream); // discard + + int nlayers; + nlayers = (ti16)Read16(Stream); + + if(nlayers < 0) nlayers = -nlayers; + + TPSDLayerRecord * lr = new TPSDLayerRecord[nlayers]; + + try + { + for(int lay = 0; lay < nlayers; lay++) + { + // for each layers + TPSDLayerRecord *clr = lr + lay; + + clr->Top = Read32(Stream); + clr->Left = Read32(Stream); + clr->Bottom = Read32(Stream); + clr->Right = Read32(Stream); + clr->Channels = Read16(Stream); + if(clr->Channels > 5) + throw EDeePSD("TDeePSD: Layer #" + AnsiString(lay) + " has " + "unsupported layer channel count " + AnsiString((int)clr->Channels) + + " (must be smaller than 6)"); + for(int i = 0; i < clr->Channels; i++) + { + clr->ChannelInfo[i].ID = Read16(Stream); + clr->ChannelInfo[i].Length = Read32(Stream); + } + + Stream->ReadBuffer(clr->BlendSig, 4); + if(memcmp(clr->BlendSig, "8BIM", 4)) + throw EDeePSD("TDeePSD: This file is corrupted."); + + Stream->ReadBuffer(clr->BlendMode, 4); + + clr->Opacity = Read8(Stream); + clr->Clipping = Read8(Stream); + clr->Flags = Read8(Stream); + Read8(Stream); // filler + + // skip extra bytes + tui32 extra_bytes = Read32(Stream); + Stream->Position += extra_bytes; + + } + + + // check layer mode structure + AnsiString org_layer_mode = FLayerMode; + bool visible_found = false; + if(FLayerMode == "addalpha") + { + // Additive Alpha output mode + bool additive_found = false; + for(int lay = 0; lay < nlayers; lay++) + { + TPSDLayerRecord *clr = lr + lay; + + if(clr->Opacity != 0 && !(clr->Flags & 2)) + { + + if(!memcmp(clr->BlendMode, "norm", 4)) + { + // alpha blend mode + if(additive_found) + throw EDeePSD("TDeePSD: Layer #" + AnsiString(lay) + " is normal blend mode but " + "cannot load normal blend mode layer over linear dodge blend mode layer"); + } + else if(!memcmp(clr->BlendMode, "lddg", 4)) + { + // linear dodge (additive) + additive_found = true; + } + else + throw EDeePSD("TDeePSD: Layer #" + AnsiString(lay) + " has " + "unsupported blend mode '" + AnsiString((char*)clr->BlendMode, 4) + + "' (must be 'norm' [normal] blend or 'lddg' [linear dodge] blend)"); + + visible_found = true; + } + } + } + else + { + // normal mode + // we only can pile 'normal' blend mode. + // other blend modes cannot be piled yet. + + FLayerMode = ""; + + for(int lay = 0; lay < nlayers; lay++) + { + TPSDLayerRecord *clr = lr + lay; + if(clr->Opacity != 0 && !(clr->Flags & 2)) + { + + + if(FLayerMode != "") + { + if(FLayerMode != "alpha" || memcmp(clr->BlendMode, "norm", 4)) + { + throw EDeePSD("TDeePSD: Layer #" + AnsiString(lay) + " has " + "blend mode '" + AnsiString((char*)clr->BlendMode, 4) + + "' but currently this PSD loader cannot pile layers more than one in this mode."); + } + } + if(!memcmp(clr->BlendMode, "norm", 4)) + FLayerMode = "alpha"; + else if(!memcmp(clr->BlendMode, "lddg", 4)) + FLayerMode = "psadd"; + else if(!memcmp(clr->BlendMode, "lbrn", 4)) + FLayerMode = "pssub"; + else if(!memcmp(clr->BlendMode, "mul ", 4)) + FLayerMode = "psmul"; + else if(!memcmp(clr->BlendMode, "scrn", 4)) + FLayerMode = "psscreen"; + else if(!memcmp(clr->BlendMode, "over", 4)) + FLayerMode = "psoverlay"; + else if(!memcmp(clr->BlendMode, "hLit", 4)) + FLayerMode = "pshlight"; + else if(!memcmp(clr->BlendMode, "sLit", 4)) + FLayerMode = "psslight"; + else if(!memcmp(clr->BlendMode, "div ", 4)) + FLayerMode = "psdodge"; + else if(!memcmp(clr->BlendMode, "idiv", 4)) + FLayerMode = "psburn"; + else if(!memcmp(clr->BlendMode, "lite", 4)) + FLayerMode = "pslighten"; + else if(!memcmp(clr->BlendMode, "dark", 4)) + FLayerMode = "psdarken"; + else if(!memcmp(clr->BlendMode, "diff", 4)) + FLayerMode = "psdiff"; + else if(!memcmp(clr->BlendMode, "smud", 4)) + FLayerMode = "psexcl"; + else + throw EDeePSD("TDeePSD: Layer #" + AnsiString(lay) + " has " + "unsupported blend mode '" + AnsiString((char*)clr->BlendMode, 4) + + "'"); + visible_found = true; + } + } + + if(org_layer_mode != "" && FLayerMode != org_layer_mode) + throw EDeePSD("TDeePSD: Unexpected layer mode '" + FLayerMode + "'"); + } + if(!visible_found) + throw EDeePSD("TDeePSD: This image does not have any visible layer"); + + // read each layer image + bool firstlayer = true; + bool additive_found = false; + for(int lay = 0; lay < nlayers; lay++) + { + // for each layers again + // read pixel data + TPSDLayerRecord *clr = lr + lay; + Graphics::TBitmap *layerbmp = ReadPixelData(Stream, lr + lay, lay); + try + { + if(clr->Opacity != 0 && !(clr->Flags & 2)) + { + TRect refrect; + refrect.left = refrect.top = 0; + refrect.right = layerbmp->Width; + refrect.bottom = layerbmp->Height; + // blend + if(!memcmp(clr->BlendMode, "norm", 4)) + { + // normal alpha blend + if(clr->Opacity != 255) SetBitmapOpacity(layerbmp, clr->Opacity); + if(firstlayer) + CopyBitmapRect(this, clr->Left, clr->Top, layerbmp, refrect, 0); + else + CopyBitmapRect(this, clr->Left, clr->Top, layerbmp, refrect, 1); + } + else if(org_layer_mode == "addalpha" && !memcmp(clr->BlendMode, "lddg", 4)) + { + // linear dodge (additive) blend + if(clr->Opacity != 255) SetBitmapOpacity(layerbmp, clr->Opacity); + if(!additive_found) + { + additive_found = true; + ConvertAlphaToAddAlpha(this); + } + if(firstlayer) + CopyBitmapRect(this, clr->Left, clr->Top, layerbmp, refrect, 2); + else + CopyBitmapRect(this, clr->Left, clr->Top, layerbmp, refrect, 3); + } + else + { + if(clr->Opacity != 255) SetBitmapOpacity(layerbmp, clr->Opacity); + if(firstlayer) + CopyBitmapRect(this, clr->Left, clr->Top, layerbmp, refrect, 0); + } + firstlayer = false; + } + } + catch(...) + { + delete layerbmp; + throw; + } + delete layerbmp; + } + if(org_layer_mode == "addalpha" && !additive_found) + ConvertAlphaToAddAlpha(this); + } + catch(...) + { + delete [] lr; + throw; + } + + delete [] lr; + } + else + { + // layer info section is zero + + if(header.Channels != 3) + throw EDeePSD("TDeePSD: Unsupported number of channels " + + AnsiString((int)header.Channels)+ " (must be 3)"); + + Graphics::TBitmap *layerbmp = + ReadPixelData30(Stream, header.Columns, header.Rows); + + try + { + Assign(layerbmp); + } + catch(...) + { + delete layerbmp; + throw; + } + + delete layerbmp; + FLayerMode = "alpha"; // always assumes alpha + } +} +//--------------------------------------------------------------------------- +void __fastcall TDeePSD::SaveToStream(Classes::TStream * Stream) +{ +} +//--------------------------------------------------------------------------- +static void InitTDeePSD() +{ + TPicture::RegisterFileFormat( + __classid(TPicture), "psd", "Photoshop image", + __classid(TDeePSD)); +} +static void UninitTDeePSD() +{ + TPicture::UnregisterGraphicClass(__classid(TPicture),__classid(TDeePSD)); +} +#pragma startup InitTDeePSD +#pragma exit UninitTDeePSD +//--------------------------------------------------------------------------- + +//#pragma package(smart_init) diff --git a/tools/win32/krdevui/tpc/psd/DeePSDUnit.h b/tools/win32/krdevui/tpc/psd/DeePSDUnit.h new file mode 100644 index 0000000..c7dc9be --- /dev/null +++ b/tools/win32/krdevui/tpc/psd/DeePSDUnit.h @@ -0,0 +1,68 @@ +//--------------------------------------------------------------------------- +/* + fgconvert (graphic converter for transparent images) + Copyright (C) 2000 W.Dee and contributors + + See details of license at "license.txt" +*/ +//--------------------------------------------------------------------------- +#ifndef DeePSDUnitH +#define DeePSDUnitH + +#include + +//--------------------------------------------------------------------------- +extern void __fastcall SetGrayscalePalette(Graphics::TBitmap *dib, int bit); +extern void ConvertAlphaToAddAlpha(Graphics::TBitmap *in); +//--------------------------------------------------------------------------- +// 例外クラス +class EDeePSD : public Exception +{ + +public: + __fastcall EDeePSD(const System::AnsiString Msg) : Sysutils::Exception( + Msg) { } + __fastcall EDeePSD(const System::AnsiString Msg, const System::TVarRec + * Args, const int Args_Size) : Sysutils::Exception(Msg, Args, Args_Size) { } + __fastcall EDeePSD(int Ident, Extended Dummy) : Sysutils::Exception( + Ident, Dummy) { } + __fastcall EDeePSD(int Ident, const System::TVarRec * Args, const + int Args_Size) : Sysutils::Exception(Ident, Args, Args_Size) { } + __fastcall EDeePSD(const System::AnsiString Msg, int AHelpContext + ) : Sysutils::Exception(Msg, AHelpContext) { } + __fastcall EDeePSD(const System::AnsiString Msg, const System::TVarRec + * Args, const int Args_Size, int AHelpContext) : Sysutils::Exception(Msg, + Args, Args_Size, AHelpContext) { } + __fastcall EDeePSD(int Ident, int AHelpContext) : Sysutils:: + Exception(Ident, AHelpContext) { } + __fastcall EDeePSD(int Ident, const System::TVarRec * Args + , const int Args_Size, int AHelpContext) : Sysutils::Exception(Ident, + Args, Args_Size, AHelpContext) { } + + __fastcall virtual ~EDeePSD(void) { } + +}; +//--------------------------------------------------------------------------- +// TDeePSD クラス +class TDeePSD : public Graphics::TBitmap +{ +private: +protected: + AnsiString FLayerMode; + +public: + // コンストラクタとデストラクタ + __fastcall TDeePSD(void); + __fastcall ~TDeePSD(void); + + + // Stream I/O のオーバーライド + void __fastcall LoadFromStream(Classes::TStream * Stream); + void __fastcall SaveToStream(Classes::TStream * Stream); + +public: + __property AnsiString LayerMode = { read = FLayerMode, write = FLayerMode }; + +}; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/krdevui/tpc/tlg5/TLG5Saver.cpp b/tools/win32/krdevui/tpc/tlg5/TLG5Saver.cpp new file mode 100644 index 0000000..4f64ccb --- /dev/null +++ b/tools/win32/krdevui/tpc/tlg5/TLG5Saver.cpp @@ -0,0 +1,227 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + + +#include "slide.h" + +#define BLOCK_HEIGHT 4 +//--------------------------------------------------------------------------- +static void WriteInt32(long num, TStream *out) +{ + char buf[4]; + buf[0] = num & 0xff; + buf[1] = (num >> 8) & 0xff; + buf[2] = (num >> 16) & 0xff; + buf[3] = (num >> 24) & 0xff; + out->WriteBuffer(buf, 4); +} +//--------------------------------------------------------------------------- +static void Compress(Graphics::TBitmap *bmp, TStream * out) +{ + // compress 'bmp' to 'out'. + // bmp will be modified (destroyed). + + int colors; + + // check pixel format + switch(bmp->PixelFormat) + { + case pfDevice: bmp->PixelFormat = pf24bit; break; + case pf1bit: bmp->PixelFormat = pf8bit; break; + case pf4bit: bmp->PixelFormat = pf8bit; break; + case pf8bit: break; + case pf15bit: bmp->PixelFormat = pf24bit; break; + case pf16bit: bmp->PixelFormat = pf24bit; break; + case pf24bit: break; + case pf32bit: break; + default: return; + } + + switch(bmp->PixelFormat) + { + case pf8bit: colors = 1; break; + case pf24bit: colors = 3; break; + case pf32bit: colors = 4; break; + } + + // header + { + out->WriteBuffer("TLG5.0\x00raw\x1a\x00", 11); + out->WriteBuffer(&colors, 1); + int width = bmp->Width; + int height = bmp->Height; + WriteInt32(width, out); + WriteInt32(height, out); + int blockheight = BLOCK_HEIGHT; + WriteInt32(blockheight, out); + } + + int blockcount = (int)((bmp->Height - 1) / BLOCK_HEIGHT) + 1; + + + // buffers/compressors + SlideCompressor * compressor = NULL; + unsigned char *cmpinbuf[4]; + unsigned char *cmpoutbuf[4]; + for(int i = 0; i < colors; i++) + cmpinbuf[i] = cmpoutbuf[i] = NULL; + long written[4]; + int *blocksizes; + + // allocate buffers/compressors + try + { + compressor = new SlideCompressor(); + for(int i = 0; i < colors; i++) + { + cmpinbuf[i] = new unsigned char [bmp->Width * BLOCK_HEIGHT]; + cmpoutbuf[i] = new unsigned char [bmp->Width * BLOCK_HEIGHT * 9 / 4]; + written[i] = 0; + } + blocksizes = new int[blockcount]; + + long blocksizepos = out->Position; + // write block size header + // (later fill this) + for(int i = 0; i < blockcount; i++) + { + out->WriteBuffer(" ", 4); + } + + + // + int block = 0; + for(int blk_y = 0; blk_y < bmp->Height; blk_y += BLOCK_HEIGHT, block++) + { + int ylim = blk_y + BLOCK_HEIGHT; + if(ylim > bmp->Height) ylim = bmp->Height; + + int inp = 0; + + + for(int y = blk_y; y < ylim; y++) + { + // retrieve scan lines + const unsigned char * upper; + if(y != 0) + upper = (const unsigned char *)bmp->ScanLine[y-1]; + else + upper = NULL; + const unsigned char * current; + current = (const unsigned char *)bmp->ScanLine[y]; + + // prepare buffer + int prevcl[4]; + int val[4]; + + for(int c = 0; c < colors; c++) prevcl[c] = 0; + + for(int x = 0; x < bmp->Width; x++) + { + for(int c = 0; c < colors; c++) + { + int cl; + if(upper) + cl = 0[current++] - 0[upper++]; + else + cl = 0[current++]; + val[c] = cl - prevcl[c]; + prevcl[c] = cl; + } + // composite colors + switch(colors) + { + case 1: + cmpinbuf[0][inp] = val[0]; + break; + case 3: + cmpinbuf[0][inp] = val[0] - val[1]; + cmpinbuf[1][inp] = val[1]; + cmpinbuf[2][inp] = val[2] - val[1]; + break; + case 4: + cmpinbuf[0][inp] = val[0] - val[1]; + cmpinbuf[1][inp] = val[1]; + cmpinbuf[2][inp] = val[2] - val[1]; + cmpinbuf[3][inp] = val[3]; + break; + } + + inp++; + } + + } + + + // compress buffer and write to the file + + // LZSS + int blocksize = 0; + for(int c = 0; c < colors; c++) + { + long wrote = 0; + compressor->Store(); + compressor->Encode(cmpinbuf[c], inp, + cmpoutbuf[c], wrote); + if(wrote < inp) + { + out->WriteBuffer("\x00", 1); + WriteInt32(wrote, out); + out->WriteBuffer(cmpoutbuf[c], wrote); + blocksize += wrote + 4 + 1; + } + else + { + compressor->Restore(); + out->WriteBuffer("\x01", 1); + WriteInt32(inp, out); + out->WriteBuffer(cmpinbuf[c], inp); + blocksize += inp + 4 + 1; + } + written[c] += wrote; + } + + blocksizes[block] = blocksize; + } + + + // write block sizes + long pos_save = out->Position; + out->Position = blocksizepos; + for(int i = 0; i < blockcount; i++) + { + WriteInt32(blocksizes[i], out); + } + out->Position = pos_save; + + + + // deallocate buffers/compressors + } + catch(...) + { + for(int i = 0; i < colors; i++) + { + if(cmpinbuf[i]) delete [] cmpinbuf[i]; + if(cmpoutbuf[i]) delete [] cmpoutbuf[i]; + } + if(compressor) delete compressor; + if(blocksizes) delete [] blocksizes; + throw; + } + for(int i = 0; i < colors; i++) + { + if(cmpinbuf[i]) delete [] cmpinbuf[i]; + if(cmpoutbuf[i]) delete [] cmpoutbuf[i]; + } + if(compressor) delete compressor; + if(blocksizes) delete [] blocksizes; +} +//--------------------------------------------------------------------------- +void SaveTLG5(Graphics::TBitmap *in, TStream *out) +{ + Compress(in, out); +} +//--------------------------------------------------------------------------- diff --git a/tools/win32/krdevui/tpc/tlg5/TLG5Saver.h b/tools/win32/krdevui/tpc/tlg5/TLG5Saver.h new file mode 100644 index 0000000..c26bd20 --- /dev/null +++ b/tools/win32/krdevui/tpc/tlg5/TLG5Saver.h @@ -0,0 +1,11 @@ +//--------------------------------------------------------------------------- +#ifndef TLG5Saver_H +#define TLG5Saver_H +//--------------------------------------------------------------------------- +void SaveTLG5(Graphics::TBitmap *in, TStream *out); +//--------------------------------------------------------------------------- +#endif +//--------------------------------------------------------------------------- + + + diff --git a/tools/win32/krdevui/tpc/tlg5/slide.cpp b/tools/win32/krdevui/tpc/tlg5/slide.cpp new file mode 100644 index 0000000..7f9182d --- /dev/null +++ b/tools/win32/krdevui/tpc/tlg5/slide.cpp @@ -0,0 +1,213 @@ +//--------------------------------------------------------------------------- + +#include "slide.h" +//--------------------------------------------------------------------------- +SlideCompressor::SlideCompressor() +{ + S = 0; + for(int i = 0; i < SLIDE_N + SLIDE_M; i++) Text[i] = 0; + for(int i = 0; i < 256*256; i++) + Map[i] = -1; + for(int i = 0; i < SLIDE_N; i++) + Chains[i].Prev = Chains[i].Next = -1; + for(int i = SLIDE_N - 1; i >= 0; i--) + AddMap(i); +} +//--------------------------------------------------------------------------- +SlideCompressor::~SlideCompressor() +{ +} +//--------------------------------------------------------------------------- +int SlideCompressor::GetMatch(const unsigned char*cur, int curlen, int &pos, int s) +{ + // get match length + if(curlen < 3) return 0; + + int place = cur[0] + ((int)cur[1] << 8); + + int maxlen = 0; + if((place = Map[place]) != -1) + { + int place_org; + curlen -= 1; + do + { + place_org = place; + if(s == place || s == ((place + 1) & (SLIDE_N -1))) continue; + place += 2; + int lim = (SLIDE_M < curlen ? SLIDE_M : curlen) + place_org; + const unsigned char *c = cur + 2; + if(lim >= SLIDE_N) + { + if(place_org <= s && s < SLIDE_N) + lim = s; + else if(s < (lim&(SLIDE_N-1))) + lim = s + SLIDE_N; + } + else + { + if(place_org <= s && s < lim) + lim = s; + } + while(Text[place] == *(c++) && place < lim) place++; + int matchlen = place - place_org; + if(matchlen > maxlen) pos = place_org, maxlen = matchlen; + if(matchlen == SLIDE_M) return maxlen; + + } while((place = Chains[place_org].Next) != -1); + } + return maxlen; +} +//--------------------------------------------------------------------------- +void SlideCompressor::AddMap(int p) +{ + int place = Text[p] + ((int)Text[(p + 1) & (SLIDE_N - 1)] << 8); + + if(Map[place] == -1) + { + // first insertion + Map[place] = p; + } + else + { + // not first insertion + int old = Map[place]; + Map[place] = p; + Chains[old].Prev = p; + Chains[p].Next = old; + Chains[p].Prev = -1; + } +} +//--------------------------------------------------------------------------- +void SlideCompressor::DeleteMap(int p) +{ + int n; + if((n = Chains[p].Next) != -1) + Chains[n].Prev = Chains[p].Prev; + + if((n = Chains[p].Prev) != -1) + { + Chains[n].Next = Chains[p].Next; + } + else if(Chains[p].Next != -1) + { + int place = Text[p] + ((int)Text[(p + 1) & (SLIDE_N - 1)] << 8); + Map[place] = Chains[p].Next; + } + else + { + int place = Text[p] + ((int)Text[(p + 1) & (SLIDE_N - 1)] << 8); + Map[place] = -1; + } + + Chains[p].Prev = -1; + Chains[p].Next = -1; +} +//--------------------------------------------------------------------------- +void SlideCompressor::Encode(const unsigned char *in, long inlen, + unsigned char *out, long & outlen) +{ + unsigned char code[40], codeptr, mask; + + if(inlen == 0) return; + + outlen = 0; + code[0] = 0; + codeptr = mask = 1; + + int s = S; + while(inlen > 0) + { + int pos = 0; + int len = GetMatch(in, inlen, pos, s); + if(len >= 3) + { + code[0] |= mask; + if(len >= 18) + { + code[codeptr++] = pos & 0xff; + code[codeptr++] = ((pos &0xf00)>> 8) | 0xf0; + code[codeptr++] = len - 18; + } + else + { + code[codeptr++] = pos & 0xff; + code[codeptr++] = ((pos&0xf00)>> 8) | ((len-3)<<4); + } + while(len--) + { + unsigned char c = 0[in++]; + DeleteMap((s - 1) & (SLIDE_N - 1)); + DeleteMap(s); + if(s < SLIDE_M - 1) Text[s + SLIDE_N] = c; + Text[s] = c; + AddMap((s - 1) & (SLIDE_N - 1)); + AddMap(s); + s++; + inlen--; + s &= (SLIDE_N - 1); + } + } + else + { + unsigned char c = 0[in++]; + DeleteMap((s - 1) & (SLIDE_N - 1)); + DeleteMap(s); + if(s < SLIDE_M - 1) Text[s + SLIDE_N] = c; + Text[s] = c; + AddMap((s - 1) & (SLIDE_N - 1)); + AddMap(s); + s++; + inlen--; + s &= (SLIDE_N - 1); + code[codeptr++] = c; + } + mask <<= 1; + + if(mask == 0) + { + for(int i = 0; i < codeptr; i++) + out[outlen++] = code[i]; + mask = codeptr = 1; + code[0] = 0; + } + } + + if(mask != 1) + { + for(int i = 0; i < codeptr; i++) + out[outlen++] = code[i]; + } + + S = s; +} +//--------------------------------------------------------------------------- +void SlideCompressor::Store() +{ + S2 = S; + int i; + for(i = 0; i < SLIDE_N + SLIDE_M - 1; i++) + Text2[i] = Text[i]; + + for(i = 0; i < 256*256; i++) + Map2[i] = Map[i]; + + for(i = 0; i < SLIDE_N; i++) + Chains2[i] = Chains[i]; +} +//--------------------------------------------------------------------------- +void SlideCompressor::Restore() +{ + S = S2; + int i; + for(i = 0; i < SLIDE_N + SLIDE_M - 1; i++) + Text[i] = Text2[i]; + + for(i = 0; i < 256*256; i++) + Map[i] = Map2[i]; + + for(i = 0; i < SLIDE_N; i++) + Chains[i] = Chains2[i]; +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/krdevui/tpc/tlg5/slide.h b/tools/win32/krdevui/tpc/tlg5/slide.h new file mode 100644 index 0000000..8998917 --- /dev/null +++ b/tools/win32/krdevui/tpc/tlg5/slide.h @@ -0,0 +1,50 @@ +//--------------------------------------------------------------------------- +#ifndef SLIDE_H +#define SLIDE_H +//--------------------------------------------------------------------------- +#define SLIDE_N 4096 +#define SLIDE_M (18+255) +class SlideCompressor +{ + // スライド辞書法 圧縮クラス + struct Chain + { + int Prev; + int Next; + }; + + unsigned char Text[SLIDE_N + SLIDE_M - 1]; + int Map[256*256]; + Chain Chains[SLIDE_N]; + + + unsigned char Text2[SLIDE_N + SLIDE_M - 1]; + int Map2[256*256]; + Chain Chains2[SLIDE_N]; + + + int S; + int S2; + +public: + SlideCompressor(); + virtual ~SlideCompressor(); + +private: + int GetMatch(const unsigned char*cur, int curlen, int &pos, int s); + void AddMap(int p); + void DeleteMap(int p); + +public: + void Encode(const unsigned char *in, long inlen, + unsigned char *out, long & outlen); + + void Store(); + void Restore(); +}; +//--------------------------------------------------------------------------- +#endif +//--------------------------------------------------------------------------- + + + diff --git a/tools/win32/krdevui/tpc/tlg6/GolombTable.cpp b/tools/win32/krdevui/tpc/tlg6/GolombTable.cpp new file mode 100644 index 0000000..65d3e01 --- /dev/null +++ b/tools/win32/krdevui/tpc/tlg6/GolombTable.cpp @@ -0,0 +1,54 @@ +#include "GolombTable.h" + +// golomb bit length table is compressed, so we need to +// decompress it. +char TVPTLG6GolombBitLengthTable[TVP_TLG6_GOLOMB_N_COUNT*2*128][TVP_TLG6_GOLOMB_N_COUNT]; +static bool TVPTLG6GolombTableInit = false; +static short int TVPTLG6GolombCompressed[TVP_TLG6_GOLOMB_N_COUNT][9] = { + {3,7,15,27,63,108,223,448,130,}, + {3,5,13,24,51,95,192,384,257,}, + {2,5,12,21,39,86,155,320,384,}, + {2,3,9,18,33,61,129,258,511,}, + // Tuned by W.Dee, 2004/03/25 +}; + +void TVPTLG6InitGolombTable() +{ + if(TVPTLG6GolombTableInit) return; + for(int n = 0; n < TVP_TLG6_GOLOMB_N_COUNT; n++) + { + int a = 0; + for(int i = 0; i < 9; i++) + { + for(int j = 0; j < TVPTLG6GolombCompressed[n][i]; j++) + TVPTLG6GolombBitLengthTable[a++][n] = (char)i; + } + if(a != TVP_TLG6_GOLOMB_N_COUNT*2*128) + *(char*)0 = 0; // THIS MUST NOT BE EXECUETED! + // (this is for compressed table data check) + } + TVPTLG6GolombTableInit = true; +} + +/* +void TVPTLG6InitGolombTable() +{ + if(TVPTLG6GolombTableInit) return; + for(int n = 0; n < TVP_TLG6_GOLOMB_N_COUNT; n++) + { + for(int a = 0; a < TVP_TLG6_GOLOMB_N_COUNT * 2 * 128; a++) + { + int k; + int nn = (TVP_TLG6_GOLOMB_N_COUNT*2-1) - n; + for (k = 0; (nn << k) < a; k++); + if(k > 8) + k = 8; + else if(k < 0) + k = 0; + TVPTLG6GolombBitLengthTable[a][n] = (char)k; + } + } + TVPTLG6GolombTableInit = true; +} + +*/ diff --git a/tools/win32/krdevui/tpc/tlg6/GolombTable.h b/tools/win32/krdevui/tpc/tlg6/GolombTable.h new file mode 100644 index 0000000..a34c28b --- /dev/null +++ b/tools/win32/krdevui/tpc/tlg6/GolombTable.h @@ -0,0 +1,9 @@ +#ifndef GolombTableH +#define GolombTableH + +// Table for 'k' (predicted bit length) of golomb encoding +#define TVP_TLG6_GOLOMB_N_COUNT 4 +extern char TVPTLG6GolombBitLengthTable[TVP_TLG6_GOLOMB_N_COUNT*2*128][TVP_TLG6_GOLOMB_N_COUNT]; +void TVPTLG6InitGolombTable(); + +#endif diff --git a/tools/win32/krdevui/tpc/tlg6/TLG6BS.cpp b/tools/win32/krdevui/tpc/tlg6/TLG6BS.cpp new file mode 100644 index 0000000..e69de29 diff --git a/tools/win32/krdevui/tpc/tlg6/TLG6BS.h b/tools/win32/krdevui/tpc/tlg6/TLG6BS.h new file mode 100644 index 0000000..a80bf9a --- /dev/null +++ b/tools/win32/krdevui/tpc/tlg6/TLG6BS.h @@ -0,0 +1,193 @@ +//--------------------------------------------------------------------------- +#ifndef TLG6BS_H +#define TLG6BS_H + + + +#include + +// TLG6.0 bitstream output implementation + + +class TLG6BitStream +{ + int BufferBitPos; // bit position of output buffer + long BufferBytePos; // byte position of output buffer + TStream * OutStream; // output stream + unsigned char *Buffer; // output buffer + long BufferCapacity; // output buffer capacity + +public: + TLG6BitStream(TStream * outstream) : + OutStream(outstream), + BufferBitPos(0), + BufferBytePos(0), + Buffer(NULL), + BufferCapacity(0) + { + } + + ~TLG6BitStream() + { + Flush(); + } + +public: + int GetBitPos() const { return BufferBitPos; } + long GetBytePos() const { return BufferBytePos; } + + void Flush() + { + if(Buffer && (BufferBitPos || BufferBytePos)) + { + if(BufferBitPos) BufferBytePos ++; + OutStream->Write(Buffer, BufferBytePos); + BufferBytePos = 0; + BufferBitPos = 0; + } + free(Buffer); + BufferCapacity = 0; + Buffer = NULL; + } + + long GetBitLength() const { return BufferBytePos * 8 + BufferBitPos; } + + void Put1Bit(bool b) + { + if(BufferBytePos == BufferCapacity) + { + // need more bytes + long org_cap = BufferCapacity; + BufferCapacity += 0x1000; + if(Buffer) + Buffer = (unsigned char *)realloc(Buffer, BufferCapacity); + else + Buffer = (unsigned char *)malloc(BufferCapacity); + if(!Buffer) throw Exception("SaveTLG6: Insufficient memory"); + memset(Buffer + org_cap, 0, BufferCapacity - org_cap); + } + + if(b) Buffer[BufferBytePos] |= 1 << BufferBitPos; + BufferBitPos ++; + if(BufferBitPos == 8) + { + BufferBitPos = 0; + BufferBytePos ++; + } + } + + void PutGamma(int v) + { + // Put a gamma code. + // v must be larger than 0. + int t = v; + t >>= 1; + int cnt = 0; + while(t) + { + Put1Bit(0); + t >>= 1; + cnt ++; + } + Put1Bit(1); + while(cnt--) + { + Put1Bit(v&1); + v >>= 1; + } + } + + void PutInterleavedGamma(int v) + { + // Put a gamma code, interleaved. + // interleaved gamma codes are: + // 1 : 1 + // <=3 : 1x0 + // <=7 : 1x0x0 + // <=15 : 1x0x0x0 + // <=31 : 1x0x0x0x0 + // and so on. + // v must be larger than 0. + + v --; + while(v) + { + v >>= 1; + Put1Bit(0); + Put1Bit(v&1); + } + Put1Bit(1); + } + + static int GetGammaBitLengthGeneric(int v) + { + int needbits = 1; + v >>= 1; + while(v) + { + needbits += 2; + v >>= 1; + } + return needbits; + } + + static int GetGammaBitLength(int v) + { + // Get bit length where v is to be encoded as a gamma code. + if(v<=1) return 1; // 1 + if(v<=3) return 3; // x10 + if(v<=7) return 5; // xx100 + if(v<=15) return 7; // xxx1000 + if(v<=31) return 9; // x xxx10000 + if(v<=63) return 11; // xxx xx100000 + if(v<=127) return 13; // xxxxx x1000000 + if(v<=255) return 15; // xxxxxxx 10000000 + if(v<=511) return 17; // xxxxxxx1 00000000 + return GetGammaBitLengthGeneric(v); + } + + void PutNonzeroSigned(int v, int len) + { + // Put signed value into the bit pool, as length of "len". + // v must not be zero. abs(v) must be less than 257. + if(v > 0) v--; + while(len --) + { + Put1Bit(v&1); + v >>= 1; + } + } + + static int GetNonzeroSignedBitLength(int v) + { + // Get bit (minimum) length where v is to be encoded as a non-zero signed value. + // v must not be zero. abs(v) must be less than 257. + if(v == 0) return 0; + if(v < 0) v = -v; + if(v <= 1) return 1; + if(v <= 2) return 2; + if(v <= 4) return 3; + if(v <= 8) return 4; + if(v <= 16) return 5; + if(v <= 32) return 6; + if(v <= 64) return 7; + if(v <= 128) return 8; + if(v <= 256) return 9; + return 10; + } + + void PutValue(long v, int len) + { + // put value "v" as length of "len" + while(len --) + { + Put1Bit(v&1); + v >>= 1; + } + } + +}; + + +#endif +//--------------------------------------------------------------------------- diff --git a/tools/win32/krdevui/tpc/tlg6/TLG6Saver.cpp b/tools/win32/krdevui/tpc/tlg6/TLG6Saver.cpp new file mode 100644 index 0000000..29fbda6 --- /dev/null +++ b/tools/win32/krdevui/tpc/tlg6/TLG6Saver.cpp @@ -0,0 +1,1141 @@ + //--------------------------------------------------------------------------- + +#include +#pragma hdrstop +#include + +#include "TLG6Saver.h" +#include "TLG6BS.h" +#include "GolombTable.h" + +#include "slide.h" + +#define MAX_COLOR_COMPONENTS 4 + +#define FILTER_TRY_COUNT 16 + +#define W_BLOCK_SIZE 8 +#define H_BLOCK_SIZE 8 + +//------------------------------ FOR DEBUG +//#define FILTER_TEST +//#define WRITE_ENTROPY_VALUES +//#define WRITE_VSTXT +//------------------------------ + + +/* + shift-jis + + TLG6 圧縮アルゴリズム(概要) + + TLG6 は吉里吉里2で用いられる画像圧縮フォーマットです。グレースケール、 + 24bitビットマップ、8bitアルファチャンネル付き24bitビットマップに対応し + ています。デザインのコンセプトは「高圧縮率であること」「画像展開において + 十分に高速な実装ができること」です。 + + TLG6 は以下の順序で画像を圧縮します。 + + 1. MED または 平均法 による輝度予測 + 2. リオーダリングによる情報量削減 + 3. 色相関フィルタによる情報量削減 + 4. ゴロム・ライス符号によるエントロピー符号化 + + + + 1. MED または 平均法 による輝度予測 + + TLG6 は MED (Median Edge Detector) あるいは平均法による輝度予測を行 + い、予測値と実際の値の誤差を記録します。 + + MED は、予測対象とするピクセル位置(下図x位置)に対し、左隣のピクセル + の輝度をa、上隣のピクセルの輝度をb、左上のピクセルの輝度をcとし、予 + 測対象のピクセルの輝度 x を以下のように予測します。 + + +-----+-----+ + | c | b | + +-----+-----+ + | a | x | + +-----+-----+ + + x = min(a,b) (c > max(a,b) の場合) + x = max(a,b) (c < min(a,b) の場合) + x = a + b - c (その他の場合) + + MEDは、単純な、周囲のピクセルの輝度の平均による予測などと比べ、画像 + の縦方向のエッジでは上のピクセルを、横方向のエッジでは左のピクセルを + 参照して予測を行うようになるため、効率のよい予測が可能です。 + + 平均法では、a と b の輝度の平均から予測対象のピクセルの輝度 x を予 + 測します。以下の式を用います。 + + x = (a + b + 1) >> 1 + + MED と 平均法は、8x8 に区切られた画像ブロック内で両方による圧縮率を + 比較し、圧縮率の高かった方の方法が選択されます。 + + R G B 画像や A R G B 画像に対してはこれを色コンポーネントごとに行い + ます。 + + 2. リオーダリングによる情報量削減 + + 誤差のみとなったデータは、リオーダリング(並び替え)が行われます。 + TLG6では、まず画像を8×8の小さなブロックに分割します。ブロックは横 + 方向に、左のブロックから順に右のブロックに向かい、一列分のブロック + の処理が完了すれば、その一列下のブロック、という方向で処理を行いま + す。 + その個々のブロック内では、ピクセルを以下の順番に並び替えます。 + + 横位置が偶数のブロック 横位置が奇数のブロック + 1 2 3 4 5 6 7 8 57 58 59 60 61 62 63 64 + 16 15 14 13 12 11 10 9 56 55 54 53 52 51 50 49 + 17 18 19 20 21 22 23 24 41 42 43 44 45 46 47 48 + 32 31 30 29 28 27 26 25 40 39 38 37 36 35 34 33 + 33 34 35 36 37 38 39 40 25 26 27 28 29 30 31 32 + 48 47 46 45 44 43 42 41 24 23 22 21 20 19 18 17 + 49 50 51 52 53 54 55 56 9 10 11 12 13 14 15 16 + 64 63 62 61 60 59 58 57 8 7 6 5 4 3 2 1 + + このような「ジグザグ」状の並び替えを行うことにより、性質(輝度や色相、 + エッジなど)の似たピクセルが連続する可能性が高くなり、後段のエントロ + ピー符号化段でのゼロ・ラン・レングス圧縮の効果を高めることができます。 + + 3. 色相関フィルタによる情報量削減 + + R G B 画像 ( A R G B 画像も同じく ) においては、色コンポーネント間 + の相関性を利用して情報量を減らせる可能性があります。TLG6では、以下の + 16種類のフィルタをブロックごとに適用し、後段のゴロム・ライス符号によ + る圧縮後サイズを試算し、もっともサイズの小さくなるフィルタを適用しま + す。フィルタ番号と MED/平均法の別は LZSS 法により圧縮され、出力され + ます。 + + 0 B G R (フィルタ無し) + 1 B-G G R-G + 2 B G-B R-B-G + 3 B-R-G G-R R + 4 B-R G-B-R R-B-R-G + 5 B-R G-B-R R + 6 B-G G R + 7 B G-B R + 8 B G R-G + 9 B-G-R-B G-R-B R-B + 10 B-R G-R R + 11 B G-B R-B + 12 B G-R-B R-B + 13 B-G G-R-B-G R-B-G + 14 B-G-R G-R R-B-G-R + 15 B G-(B<<1) R-(B<<1) + + これらのフィルタは、多くの画像でテストした中、フィルタの使用頻度を調 + べ、もっとも適用の多かった16個のフィルタを選出しました。 + + 4. ゴロム・ライス符号によるエントロピー符号化 + + 最終的な値はゴロム・ライス符号によりビット配列に格納されます。しかし + 最終的な値には連続するゼロが非常に多いため、ゼロと非ゼロの連続数を + ガンマ符号を用いて符号化します(ゼロ・ラン・レングス)。そのため、ビッ + ト配列中には基本的に + + 1 非ゼロの連続数(ラン・レングス)のガンマ符号 + 2 非ゼロの値のゴロム・ライス符号 (連続数分 繰り返される) + 3 ゼロの連続数(ラン・レングス)のガンマ符号 + + が複数回現れることになります。 + + ガンマ符号は以下の形式で、0を保存する必要がないため(長さ0はあり得な + いので)、表現できる最低の値は1となっています。 + + MSB ← → LSB + (v=1) 1 + (2<=v<=3) x10 x = v-2 + (4<=v<=7) xx100 xx = v-4 + (8<=v<=15) xxx1000 xxx = v-8 + (16<=v<=31) x xxx10000 xxxx = v-16 + (32<=v<=63) xxx xx100000 xxxxx = v-32 + (64<=v<=127) xxxxx x1000000 xxxxxx = v-64 + (128<=v<=255) xxxxxxx 10000000 xxxxxxx = v-128 + (256<=v<=511) xxxxxxx1 00000000 xxxxxxxx = v-256 + : : : + : : : + + ゴロム・ライス符号は以下の方法で符号化します。まず、符号化しようとす + る値をeとします。eには1以上の正の整数と-1以下の負の整数が存在します。 + これを0以上の整数に変換します。具体的には以下の式で変換を行います。 + (変換後の値をmとする) + + m = ((e >= 0) ? 2*e : -2*e-1) - 1 + + この変換により、下の表のように、負のeが偶数のmに、正のeが奇数のmに変 + 換されます。 + + e m + -1 0 + 1 1 + -2 2 + 2 3 + -3 4 + 3 5 + : : + : : + + この値 m がどれぐらいのビット長で表現できるかを予測します。このビッ + ト長を k とします。k は 0 以上の整数です。しかし予測がはずれ、m が k + ビットで表現できない場合があります。その場合は、k ビットで表現でき + なかった分の m、つまり k>>m 個分のゼロを出力し、最後にその終端記号と + して 1 を出力します。 + m が kビットで表現できた場合は、ただ単に 1 を出力します。そのあと、 + m を下位ビットから k ビット分出力します。 + + たとえば e が 66 で k が 5 の場合は以下のようになります。 + + m は m = ((e >= 0) ? 2*e : -2*e-1) - 1 の式により 131 となります。 + 予測したビット数 5 で表現できる値の最大値は 31 ですので、131 である + m は k ビットで表現できないということになります。ですので、m >> k + である 4 個の 0 を出力します。 + + 0000 + + 次に、その4個の 0 の終端記号として 1 を出力します。 + + 10000 + + 最後に m を下位ビットから k ビット分出力します。131 を2進数で表現 + すると 10000011 となりますが、これの下位から 5 ビット分を出力します。 + + + MSB← →LSB + 00011 1 0000 (計10ビット) + ~~~~~ ~ ~~~~ + c b a + + a (m >> k) 個の 0 + b a の 終端記号 + c m の下位 k ビット分 + + これが e=66 k=5 を符号化したビット列となります。 + + 原理的には k の予測は、今までに出力した e の絶対値の合計とそれまでに + 出力した個数を元に、あらかじめ実際の画像の統計から作成されたテーブル + を参照することで算出します。動作を C++ 言語風に記述すると以下のよう + になります。 + + n = 3; // カウンタ + a = 0; // e の絶対値の合計 + + while(e を読み込む) + { + k = table[a][n]; // テーブルから k を参照 + m = ((e >= 0) ? 2*e : -2*e-1) - 1; + e を m と k で符号化; + a += m >> 1; // e の絶対値の合計 (ただし m >>1 で代用) + if(--n < 0) a >>= 1, n = 3; + } + + 4 回ごとに a が半減され n がリセットされるため、前の値の影響は符号化 + が進むにつれて薄くなり、直近の値から効率的に k を予測することができ + ます。 + + + 参考 : + Golomb codes + http://oku.edu.mie-u.ac.jp/~okumura/compression/golomb/ + 三重大学教授 奥村晴彦氏によるゴロム符号の簡単な解説 +*/ + +//--------------------------------------------------------------------------- +#ifdef WRITE_VSTXT +FILE *vstxt = fopen("vs.txt", "wt"); +#endif +#define GOLOMB_GIVE_UP_BYTES 4 +void CompressValuesGolomb(TLG6BitStream &bs, char *buf, int size) +{ + // golomb encoding, -- http://oku.edu.mie-u.ac.jp/~okumura/compression/golomb/ + + // run-length golomb method + bs.PutValue(buf[0]?1:0, 1); // initial value state + + int count; + + int n = TVP_TLG6_GOLOMB_N_COUNT - 1; // 個数のカウンタ + int a = 0; // 予測誤差の絶対値の和 + + count = 0; + for(int i = 0; i < size; i++) + { + if(buf[i]) + { + // write zero count + if(count) bs.PutGamma(count); + + // count non-zero values + count = 0; + int ii; + for(ii = i; ii < size; ii++) + { + if(buf[ii]) count++; else break; + } + + // write non-zero count + bs.PutGamma(count); + + // write non-zero values + for(; i < ii; i++) + { + int e = buf[i]; +#ifdef WRITE_VSTXT + fprintf(vstxt, "%d ", e); +#endif + int k = TVPTLG6GolombBitLengthTable[a][n]; + int m = ((e >= 0) ? 2*e : -2*e-1) - 1; + int store_limit = bs.GetBytePos() + GOLOMB_GIVE_UP_BYTES; + bool put1 = true; + for(int c = (m >> k); c > 0; c--) + { + if(store_limit == bs.GetBytePos()) + { + bs.PutValue(m >> k, 8); +#ifdef WRITE_VSTXT + fprintf(vstxt, "[ %d ] ", m>>k); +#endif + put1 = false; + break; + } + bs.Put1Bit(0); + } + if(store_limit == bs.GetBytePos()) + { + bs.PutValue(m >> k, 8); +#ifdef WRITE_VSTXT + fprintf(vstxt, "[ %d ] ", m>>k); +#endif + put1 = false; + } + if(put1) bs.Put1Bit(1); + bs.PutValue(m, k); + a += (m>>1); + if (--n < 0) { + a >>= 1; n = TVP_TLG6_GOLOMB_N_COUNT - 1; + } + } + +#ifdef WRITE_VSTXT + fprintf(vstxt, "\n"); +#endif + + i = ii - 1; + count = 0; + } + else + { + // zero + count ++; + } + } + + if(count) bs.PutGamma(count); +} +//--------------------------------------------------------------------------- +class TryCompressGolomb +{ + int TotalBits; // total bit count + int Count; // running count + int N; + int A; + bool LastNonZero; + +public: + TryCompressGolomb() + { + Reset(); + } + + TryCompressGolomb(const TryCompressGolomb &ref) + { + Copy(ref); + } + + ~TryCompressGolomb() { ; } + + void Copy(const TryCompressGolomb &ref) + { + TotalBits = ref.TotalBits; + Count = ref.Count; + N = ref.N; + A = ref.A; + LastNonZero = ref.LastNonZero; + } + + void Reset() + { + TotalBits = 1; + Count = 0; + N = TVP_TLG6_GOLOMB_N_COUNT - 1; + A = 0; + LastNonZero = false; + } + + int Try(char *buf, int size) + { + for(int i = 0; i < size; i++) + { + if(buf[i]) + { + // write zero count + if(!LastNonZero) + { + if(Count) + TotalBits += + TLG6BitStream::GetGammaBitLength(Count); + + // count non-zero values + Count = 0; + } + + // write non-zero values + for(; i < size; i++) + { + int e = buf[i]; + if(!e) break; + Count ++; + int k = TVPTLG6GolombBitLengthTable[A][N]; + int m = ((e >= 0) ? 2*e : -2*e-1) - 1; + int unexp_bits = (m>>k); + if(unexp_bits >= (GOLOMB_GIVE_UP_BYTES*8-8/2)) + unexp_bits = (GOLOMB_GIVE_UP_BYTES*8-8/2)+8; + TotalBits += unexp_bits + 1 + k; + A += (m>>1); + if (--N < 0) { + A >>= 1; N = TVP_TLG6_GOLOMB_N_COUNT - 1; + } + } + + // write non-zero count + + i--; + LastNonZero = true; + } + else + { + // zero + if(LastNonZero) + { + if(Count) + { + TotalBits += TLG6BitStream::GetGammaBitLength(Count); + Count = 0; + } + } + + Count ++; + LastNonZero = false; + } + } + return TotalBits; + } + + int Flush() + { + if(Count) + { + TotalBits += TLG6BitStream::GetGammaBitLength(Count); + Count = 0; + } + return TotalBits; + } +}; +//--------------------------------------------------------------------------- +#define DO_FILTER \ + len -= 4; \ + for(d = 0; d < len; d+=4) \ + { FILTER_FUNC(0); FILTER_FUNC(1); FILTER_FUNC(2); FILTER_FUNC(3); } \ + len += 4; \ + for(; d < len; d++) \ + { FILTER_FUNC(0); } + +void ApplyColorFilter(char * bufb, char * bufg, char * bufr, int len, int code) +{ + int d; + unsigned char t; + switch(code) + { + case 0: + break; + case 1: + #define FILTER_FUNC(n) \ + bufr[d+n] -= bufg[d+n], \ + bufb[d+n] -= bufg[d+n]; + DO_FILTER + break; + case 2: + for(int d = 0; d < len; d++) + bufr[d] -= bufg[d], + bufg[d] -= bufb[d]; + break; + case 3: + for(int d = 0; d < len; d++) + bufb[d] -= bufg[d], + bufg[d] -= bufr[d]; + break; + case 4: + for(int d = 0; d < len; d++) + bufr[d] -= bufg[d], + bufg[d] -= bufb[d], + bufb[d] -= bufr[d]; + break; + case 5: + for(int d = 0; d < len; d++) + bufg[d] -= bufb[d], + bufb[d] -= bufr[d]; + break; + case 6: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + bufb[d+n] -= bufg[d+n]; + DO_FILTER + break; + case 7: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + bufg[d+n] -= bufb[d+n]; + DO_FILTER + break; + case 8: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + bufr[d+n] -= bufg[d+n]; + DO_FILTER + break; + case 9: + for(int d = 0; d < len; d++) + bufb[d] -= bufg[d], + bufg[d] -= bufr[d], + bufr[d] -= bufb[d]; + break; + case 10: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + bufg[d+n] -= bufr[d+n], \ + bufb[d+n] -= bufr[d+n]; + DO_FILTER + break; + case 11: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + bufr[d+n] -= bufb[d+n], \ + bufg[d+n] -= bufb[d+n]; + DO_FILTER + break; + case 12: + for(int d = 0; d < len; d++) + bufg[d] -= bufr[d], + bufr[d] -= bufb[d]; + break; + case 13: + for(int d = 0; d < len; d++) + bufg[d] -= bufr[d], + bufr[d] -= bufb[d], + bufb[d] -= bufg[d]; + break; + case 14: + for(int d = 0; d < len; d++) + bufr[d] -= bufb[d], + bufb[d] -= bufg[d], + bufg[d] -= bufr[d]; + break; + case 15: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + t = bufb[d+n]<<1; \ + bufr[d+n] -= t, \ + bufg[d+n] -= t; + DO_FILTER + break; + case 16: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + bufg[d+n] -= bufr[d+n]; + DO_FILTER + break; + case 17: + for(int d = 0; d < len; d++) + bufr[d] -= bufb[d], + bufb[d] -= bufg[d]; + break; + case 18: + for(int d = 0; d < len; d++) + bufr[d] -= bufb[d]; + break; + case 19: + for(int d = 0; d < len; d++) + bufb[d] -= bufr[d], + bufr[d] -= bufg[d]; + break; + case 20: + for(int d = 0; d < len; d++) + bufb[d] -= bufr[d]; + break; + case 21: + for(int d = 0; d < len; d++) + bufb[d] -= bufg[d]>>1; + break; + case 22: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + bufg[d+n] -= bufb[d+n]>>1; + DO_FILTER + break; + case 23: + for(int d = 0; d < len; d++) + bufg[d] -= bufb[d], + bufb[d] -= bufr[d], + bufr[d] -= bufg[d]; + break; + case 24: + for(int d = 0; d < len; d++) + bufb[d] -= bufr[d], + bufr[d] -= bufg[d], + bufg[d] -= bufb[d]; + break; + case 25: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + bufg[d+n] -= bufr[d+n]>>1; + DO_FILTER + break; + case 26: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + bufr[d+n] -= bufg[d+n]>>1; + DO_FILTER + break; + case 27: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + t = bufr[d+n]>>1; \ + bufg[d+n] -= t, \ + bufb[d+n] -= t; + DO_FILTER + break; + case 28: + for(int d = 0; d < len; d++) + bufr[d] -= bufb[d]>>1; + break; + case 29: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + t = bufg[d+n]>>1; \ + bufr[d+n] -= t, \ + bufb[d+n] -= t; + DO_FILTER + break; + case 30: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + t = bufb[d+n]>>1; \ + bufr[d+n] -= t, \ + bufg[d+n] -= t; + DO_FILTER + break; + case 31: + for(int d = 0; d < len; d++) + bufb[d] -= bufr[d]>>1; + break; + case 32: + for(int d = 0; d < len; d++) + bufr[d] -= bufb[d]<<1; + break; + case 33: + for(int d = 0; d < len; d++) + bufb[d] -= bufg[d]<<1; + break; + case 34: + #undef FILTER_FUNC + #define FILTER_FUNC(n) \ + t = bufr[d+n]<<1; \ + bufg[d+n] -= t, \ + bufb[d+n] -= t; + DO_FILTER + break; + case 35: + for(int d = 0; d < len; d++) + bufg[d] -= bufb[d]<<1; + break; + case 36: + for(int d = 0; d < len; d++) + bufr[d] -= bufg[d]<<1; + break; + case 37: + for(int d = 0; d < len; d++) + bufr[d] -= bufg[d]<<1, + bufb[d] -= bufg[d]<<1; + break; + case 38: + for(int d = 0; d < len; d++) + bufg[d] -= bufr[d]<<1; + break; + case 39: + for(int d = 0; d < len; d++) + bufb[d] -= bufr[d]<<1; + break; + + } + +} +//--------------------------------------------------------------------------- +int DetectColorFilter(char *b, char *g, char *r, int size, int &outsize) +{ +#ifndef FILTER_TEST + int minbits = -1; + int mincode = -1; + + char bbuf[H_BLOCK_SIZE*W_BLOCK_SIZE]; + char gbuf[H_BLOCK_SIZE*W_BLOCK_SIZE]; + char rbuf[H_BLOCK_SIZE*W_BLOCK_SIZE]; + TryCompressGolomb bc, gc, rc; + + for(int code = 0; code < FILTER_TRY_COUNT; code++) // 17..27 are currently not used + { + // copy bbuf, gbuf, rbuf into b, g, r. + memcpy(bbuf, b, sizeof(char)*size); + memcpy(gbuf, g, sizeof(char)*size); + memcpy(rbuf, r, sizeof(char)*size); + + // copy compressor + bc.Reset(); + gc.Reset(); + rc.Reset(); + + // Apply color filter + ApplyColorFilter(bbuf, gbuf, rbuf, size, code); + + // try to compress + int bits; + bits = (bc.Try(bbuf, size), bc.Flush()); + if(minbits != -1 && minbits < bits) continue; + bits += (gc.Try(gbuf, size), gc.Flush()); + if(minbits != -1 && minbits < bits) continue; + bits += (rc.Try(rbuf, size), rc.Flush()); + + if(minbits == -1 || minbits > bits) + { + minbits = bits, mincode = code; + } + } + + outsize = minbits; + + return mincode; +#else + static int filter = 0; + + int f = filter; + + filter++; + if(filter >= FILTER_TRY_COUNT) filter = 0; + + outsize = 0; + + return f; +#endif +} +//--------------------------------------------------------------------------- +static void WriteInt32(long num, TStream *out) +{ + char buf[4]; + buf[0] = num & 0xff; + buf[1] = (num >> 8) & 0xff; + buf[2] = (num >> 16) & 0xff; + buf[3] = (num >> 24) & 0xff; + out->WriteBuffer(buf, 4); +} +//--------------------------------------------------------------------------- +static void TLG6InitializeColorFilterCompressor(SlideCompressor &c) +{ + unsigned char code[4096]; + unsigned char dum[4096]; + unsigned char *p = code; + for(int i = 0; i < 32; i++) + { + for(int j = 0; j < 16; j++) + { + p[0] = p[1] = p[2] = p[3] = i; + p += 4; + p[0] = p[1] = p[2] = p[3] = j; + p += 4; + } + } + + long dumlen; + c.Encode(code, 4096, dum, dumlen); +} +//--------------------------------------------------------------------------- +// int ftfreq[256] = {0}; +void SaveTLG6(Graphics::TBitmap *bmp, TStream *out) +{ + DWORD medstart, medend; + DWORD reordertick; +#ifdef WRITE_ENTROPY_VALUES + FILE *vs = fopen("vs.bin", "wb"); +#endif + + int colors; + + TVPTLG6InitGolombTable(); + + // check pixel format + switch(bmp->PixelFormat) + { + case pfDevice: bmp->PixelFormat = pf24bit; break; + case pf1bit: bmp->PixelFormat = pf8bit; break; + case pf4bit: bmp->PixelFormat = pf8bit; break; + case pf8bit: break; + case pf15bit: bmp->PixelFormat = pf24bit; break; + case pf16bit: bmp->PixelFormat = pf24bit; break; + case pf24bit: break; + case pf32bit: break; + default: throw Exception("SaveTLG6: Unsupported Color Type"); + } + + switch(bmp->PixelFormat) + { + case pf8bit: colors = 1; break; + case pf24bit: colors = 3; break; + case pf32bit: colors = 4; break; + } + + // output stream header + { + out->WriteBuffer("TLG6.0\x00raw\x1a\x00", 11); + out->WriteBuffer(&colors, 1); + int n = 0; + out->WriteBuffer(&n, 1); // data flag (0) + out->WriteBuffer(&n, 1); // color type (0) + out->WriteBuffer(&n, 1); // external golomb table (0) + int width = bmp->Width; + int height = bmp->Height; + WriteInt32(width, out); + WriteInt32(height, out); + } + + +/* + // Near lossless filter + if(colors == 3) bmp->PixelFormat = pf32bit; + NearLosslessFilter(bmp); + if(colors == 3) bmp->PixelFormat = pf24bit; +*/ + + // compress + long max_bit_length = 0; + + unsigned char *buf[MAX_COLOR_COMPONENTS]; + for(int i = 0; i < MAX_COLOR_COMPONENTS; i++) buf[i] = NULL; + char *block_buf[MAX_COLOR_COMPONENTS]; + for(int i = 0; i < MAX_COLOR_COMPONENTS; i++) block_buf[i] = NULL; + unsigned char *filtertypes = NULL; + TMemoryStream *memstream = NULL; + + try + { + memstream = new TMemoryStream(); + + TLG6BitStream bs(memstream); + +// int buf_size = bmp->Width * bmp->Height; + + // allocate buffer + for(int c = 0; c < colors; c++) + { + buf[c] = new unsigned char [W_BLOCK_SIZE * H_BLOCK_SIZE * 3]; + block_buf[c] = new char [H_BLOCK_SIZE * bmp->Width]; + } + int w_block_count = (int)((bmp->Width - 1) / W_BLOCK_SIZE) + 1; + int h_block_count = (int)((bmp->Height - 1) / H_BLOCK_SIZE) + 1; + filtertypes = new unsigned char [w_block_count * h_block_count]; + + int fc = 0; + for(int y = 0; y < bmp->Height; y += H_BLOCK_SIZE) + { + int ylim = y + H_BLOCK_SIZE; + if(ylim > bmp->Height) ylim = bmp->Height; + int gwp = 0; + int xp = 0; + for(int x = 0; x < bmp->Width; x += W_BLOCK_SIZE, xp++) + { + int xlim = x + W_BLOCK_SIZE; + if(xlim > bmp->Width) xlim = bmp->Width; + int bw = xlim - x; + + int p0size; // size of MED method (p=0) + int minp = 0; // most efficient method (0:MED, 1:AVG) + int ft; // filter type + int wp; // write point + for(int p = 0; p < 2; p++) + { + int dbofs = (p+1) * (H_BLOCK_SIZE * W_BLOCK_SIZE); + + // do med(when p=0) or take average of upper and left pixel(p=1) + for(int c = 0; c < colors; c++) + { + int wp = 0; + for(int yy = y; yy < ylim; yy++) + { + const unsigned char * sl = x*colors + + c + (const unsigned char *)bmp->ScanLine[yy]; + const unsigned char * usl; + if(yy >= 1) + usl = x*colors + c + (const unsigned char *)bmp->ScanLine[yy-1]; + else + usl = NULL; + for(int xx = x; xx < xlim; xx++) + { + unsigned char pa = xx > 0 ? sl[-colors] : 0; + unsigned char pb = usl ? *usl : 0; + unsigned char px = *sl; + + unsigned char py; + +// py = 0; + if(p == 0) + { + unsigned char pc = (xx > 0 && usl) ? usl[-colors] : 0; + unsigned char min_a_b = pa>pb?pb:pa; + unsigned char max_a_b = pa= max_a_b) + py = min_a_b; + else if(pc < min_a_b) + py = max_a_b; + else + py = pa + pb - pc; + } + else + { + py = (pa+pb+1)>>1; + } + + buf[c][wp] = (unsigned char)(px - py); + + wp++; + sl += colors; + if(usl) usl += colors; + } + } + } + + // reordering + // Transfer the data into block_buf (block buffer). + // Even lines are stored forward (left to right), + // Odd lines are stored backward (right to left). + + wp = 0; + DWORD reorderstart = GetTickCount(); + for(int yy = y; yy < ylim; yy++) + { + int ofs; + if(!(xp&1)) + ofs = (yy - y)*bw; + else + ofs = (ylim - yy - 1) * bw; + bool dir; // false for forward, true for backward + if(!((ylim-y)&1)) + { + // vertical line count per block is even + dir = (yy&1) ^ (xp&1); + } + else + { + // otherwise; + if(xp & 1) + { + dir = (yy&1); + } + else + { + dir = (yy&1) ^ (xp&1); + } + } + + if(!dir) + { + // forward + for(int xx = 0; xx < bw; xx++) + { + for(int c = 0; c < colors; c++) + buf[c][wp + dbofs] = + buf[c][ofs + xx]; + wp++; + } + } + else + { + // backward + for(int xx = bw - 1; xx >= 0; xx--) + { + for(int c = 0; c < colors; c++) + buf[c][wp + dbofs] = + buf[c][ofs + xx]; + wp++; + } + } + } + reordertick += GetTickCount() - reorderstart; + } + + + for(int p = 0; p < 2; p++) + { + int dbofs = (p+1) * (H_BLOCK_SIZE * W_BLOCK_SIZE); + // detect color filter + int size = 0; + int ft_; + if(colors >= 3) + ft_ = DetectColorFilter( + buf[0] + dbofs, + buf[1] + dbofs, + buf[2] + dbofs, wp, size); + else + ft_ = 0; + + // select efficient mode of p (MED or average) + if(p == 0) + { + p0size = size; + ft = ft_; + } + else + { + if(p0size >= size) + minp = 1, ft = ft_; + } + } + + // Apply most efficient color filter / prediction method + wp = 0; + int dbofs = (minp + 1) * (H_BLOCK_SIZE * W_BLOCK_SIZE); + for(int yy = y; yy < ylim; yy++) + { + for(int xx = 0; xx < bw; xx++) + { + for(int c = 0; c < colors; c++) + block_buf[c][gwp + wp] = buf[c][wp + dbofs]; + wp++; + } + } + + ApplyColorFilter(block_buf[0] + gwp, + block_buf[1] + gwp, block_buf[2] + gwp, wp, ft); + + filtertypes[fc++] = (ft<<1) + minp; +// ftfreq[ft]++; + gwp += wp; + } + + // compress values (entropy coding) + for(int c = 0; c < colors; c++) + { + int method; + CompressValuesGolomb(bs, block_buf[c], gwp); + method = 0; +#ifdef WRITE_ENTROPY_VALUES + fwrite(block_buf[c], 1, gwp, vs); +#endif + long bitlength = bs.GetBitLength(); + if(bitlength & 0xc0000000) + throw Exception("SaveTLG6: Too large bit length (given image may be too large)"); + // two most significant bits of bitlength are + // entropy coding method; + // 00 means Golomb method, + // 01 means Gamma method (implemented but not used), + // 10 means modified LZSS method (not yet implemented), + // 11 means raw (uncompressed) data (not yet implemented). + if(max_bit_length < bitlength) max_bit_length = bitlength; + bitlength |= (method << 30); + WriteInt32(bitlength, memstream); + bs.Flush(); + } + + } + + + // write max bit length + WriteInt32(max_bit_length, out); + + // output filter types + { + SlideCompressor comp; + TLG6InitializeColorFilterCompressor(comp); + unsigned char *outbuf = new unsigned char[fc * 2]; + try + { + long outlen; + comp.Encode(filtertypes, fc, outbuf, outlen); + WriteInt32(outlen, out); + out->WriteBuffer(outbuf, outlen); + } + catch(...) + { + delete [] outbuf; + throw; + } + delete [] outbuf; +/* + FILE *f = fopen("ft.txt", "wt"); + int n = 0; + for(int y = 0; y < h_block_count; y++) + { + for(int x = 0; x < w_block_count; x++) + { + int t = filtertypes[n++]; + char b; + if(t & 1) b = 'A'; else b = 'M'; + t >>= 1; + fprintf(f, "%c%x", b, t); + } + fprintf(f, "\n"); + } + fclose(f); +*/ + } + + // copy memory stream to output stream + out->CopyFrom(memstream, 0); + } + catch(...) + { + for(int i = 0; i < MAX_COLOR_COMPONENTS; i++) + { + if(buf[i]) delete [] (buf[i]); + if(block_buf[i]) delete [] (block_buf[i]); + } + if(filtertypes) delete [] filtertypes; + if(memstream) delete memstream; + throw; + } + + for(int i = 0; i < MAX_COLOR_COMPONENTS; i++) + { + if(buf[i]) delete [] (buf[i]); + if(block_buf) delete [] (block_buf[i]); + } + if(filtertypes) delete [] filtertypes; + if(memstream) delete memstream; + +#ifdef WRITE_ENTROPY_VALUES + fclose(vs); +#endif +// printf("med : %d ms\n", medend - medstart); +// printf("reorder : %d ms\n", reordertick); +/* + for(int i = 0; i < 256; i++) + { + if(ftfreq[i]) + { + printf("%3d : %d\n", i, ftfreq[i]); + } + } +*/ +} +//--------------------------------------------------------------------------- + + diff --git a/tools/win32/krdevui/tpc/tlg6/TLG6Saver.h b/tools/win32/krdevui/tpc/tlg6/TLG6Saver.h new file mode 100644 index 0000000..2a82953 --- /dev/null +++ b/tools/win32/krdevui/tpc/tlg6/TLG6Saver.h @@ -0,0 +1,11 @@ +//--------------------------------------------------------------------------- +#ifndef TLG6Saver_H +#define TLG6Saver_H +//--------------------------------------------------------------------------- +void SaveTLG6(Graphics::TBitmap *in, TStream *out); +//--------------------------------------------------------------------------- +#endif +//--------------------------------------------------------------------------- + + + diff --git a/tools/win32/sigchecker/MainUnit.cpp b/tools/win32/sigchecker/MainUnit.cpp new file mode 100644 index 0000000..7747c8e --- /dev/null +++ b/tools/win32/sigchecker/MainUnit.cpp @@ -0,0 +1,390 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include +#include +#include + + +#include "MainUnit.h" + +#if 0 +// テスト用に使っているキーペア +-----BEGIN PUBLIC KEY----- +MIGJAoGBAJYfPysW57qE3J2ddGWEG+RzXUzFkWa0ct3p7qJfuWDB+52DbfS9qSpw +iTHQ54vl7K35x+WDQdn29cfgJxp9UD3fzY4h6E2ReE9vj4h0FCMK8dpCFnQkOD/M +hDSiXfXz7KmfMXppM0CjofvH+IL7BJ3/GcLFcuEw3hEnzoajIm1TAgMBAAE= +-----END PUBLIC KEY----- + +-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQCWHz8rFue6hNydnXRlhBvkc11MxZFmtHLd6e6iX7lgwfudg230 +vakqcIkx0OeL5eyt+cflg0HZ9vXH4CcafVA9382OIehNkXhPb4+IdBQjCvHaQhZ0 +JDg/zIQ0ol318+ypnzF6aTNAo6H7x/iC+wSd/xnCxXLhMN4RJ86GoyJtUwIDAQAB +AoGABHj02FNL3xYzPmzg+V9It3Mqbe2a6dzpaSwdhG/mpXfSB7zRK0/1OML2i2nm +ZBgbB4ngBzn0XcqKQwSuFY9zMwEIB+Bd1KQguslNdTGFyoKFS1aOly768q3KD6G5 +ojl7e8l2RqiZDlY6/0Dz7OdEaHbUXYJ+k3p9EQGeakEbLHkCQQDFEUilrXF0DCE3 +z+BCppl/5R4wrVw0LH4f9lGLV/+36nvV7T1vraSeOUVtWsySfsgqDO/8oLJP+N3c +0fLwOWVLAkEAwwQAur5/SqyA0LoFBjpVQN1rx7vcRYPWB/mKv0XzumAFaQVJpMtO +GhTNLKMbaAXnPT4T5qNhBWeYB5q3jkX7GQJBAJMS3iP/+M9CCjyMIPO9QIwp48ky +aMDrf8m83IjhSRDqqDc1UoeZkWUgmwcNH+YpRpvTgfwJtmpm8rXN3sCYJVcCQAOn +c4wMPb5cdR10Htv7A9XvUDGx53K2AbCskFj9Ko/3dKJ/It4foRsEAMQxWjYcxjRz +kVPlA9BiHIsn7wCPdyECQEncAeBuhPrBiyuszuh90wqjd53MzRSpm28/ynafwmyj +rwW1SrP9HPgBYHz4CzyoFVEn6WTZjo5QYB7TOoFjmfI= +-----END RSA PRIVATE KEY----- + +#endif + +#include "KrkrSignatureUnit.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TMainForm *MainForm; +//--------------------------------------------------------------------------- +static AnsiString ReadTextFile(AnsiString fn) +{ + // fn を全て読み、AnsiString として返す + TFileStream *s = new TFileStream(fn, fmOpenRead|fmShareDenyWrite); + AnsiString ret; + char *buf = NULL; + try + { + int size = s->Size; + buf = new char [ size + 1]; + s->ReadBuffer(buf, size); + buf[size] = '\0'; + ret = buf; + } + catch(...) + { + if(buf) delete [] buf; + delete s; + throw; + } + if(buf) delete [] buf; + delete s; + return ret; +} +//--------------------------------------------------------------------------- +__fastcall TMainForm::TMainForm(TComponent* Owner) + : TForm(Owner) +{ + // 変数初期化 + Checking = false; + Aborting = false; + + // ini ファイルを読み込む + AnsiString inifn = ChangeFileExt(ParamStr(0), ".ini"); + TMemIniFile * memini = new TMemIniFile(inifn); + try + { + // キャプションを読み込む + Caption = memini->ReadString("message", "caption", + "File signature checker"); + Application->Title = Caption; + + // 公開鍵を読み込む + // 公開鍵は ini ファイルをそのまま用いる + // (ini ファイル中に記述された公開鍵を自動的に認識できるため) + PublicKey = ReadTextFile(inifn); + + // notice の読み込みとコンポーネントの位置調整 + AnsiString notice = + memini->ReadString("message", "notice", + "Please press the check button below."); + while(true) + { + int pos = notice.AnsiPos("[cr]"); + if(!pos) break; + AnsiString left = notice.SubString(1, pos - 1); + AnsiString right = notice.c_str() + pos + 4 - 1; + notice = left + "\r\n" + right; + } + AnsiString pnotice = notice; + + Canvas->Font->Assign(NoticeMemo->Font); + RECT r = {0, 0, NoticeMemo->Width - 4, NoticeMemo->Height - 4}; + DrawText(Canvas->Handle, pnotice.c_str(), -1, &r, + DT_CALCRECT|DT_EDITCONTROL|DT_WORDBREAK); + + int ystep = r.bottom + 10 - NoticeMemo->Height; + NoticeMemo->Height += ystep; + NoticeMemo->Text = notice; + ListView->Top += ystep; + ListView->Height -= ystep; + + } + catch(...) + { + delete memini; + throw; + } + delete memini; + + // ファイルのリストを作成 + BaseDir = IncludeTrailingBackslash(ExtractFilePath(ParamStr(0))); + ListView->Items->BeginUpdate(); + try + { + AllFileList = ""; + AllFileCount = 0; + MakeFileList(BaseDir, BaseDir.Length()); + } + catch(...) + { + ListView->Items->EndUpdate(); + throw; + } + ListView->Items->EndUpdate(); + + // ファイル名にあわせて列幅を決定 + int maxwidth; + Canvas->Font->Assign(ListView->Font); + maxwidth = Canvas->TextWidth(ListView->Column[0]->Caption); + for(int i = 0; i < ListView->Items->Count; i++) + { + int width = Canvas->TextWidth(ListView->Items->Item[i]->Caption); + if(width > maxwidth) maxwidth = width; + + // 「未チェック」を状態欄に追加 + ListView->Items->Item[i]->SubItems->Add(NotYetCheckedLabel->Caption); + } + ListView->Column[0]->Width = maxwidth + 12; + + // 状態欄に表示される項目に合わせて列幅を決定 + maxwidth = Canvas->TextWidth(ListView->Column[0]->Caption); + int width; + width = Canvas->TextWidth(NotYetCheckedLabel->Caption); + if(width > maxwidth) maxwidth = width; + width = Canvas->TextWidth(CheckingLabel->Caption); + if(width > maxwidth) maxwidth = width; + width = Canvas->TextWidth(BrokenLabel->Caption); + if(width > maxwidth) maxwidth = width; + width = Canvas->TextWidth(NotBrokenLabel->Caption); + if(width > maxwidth) maxwidth = width; + ListView->Column[1]->Width = maxwidth + 20; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::CloseButtonClick(TObject *Sender) +{ + if(Checking) + Aborting = true; + else + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::CheckButtonClick(TObject *Sender) +{ + // 署名をチェックする + Checking = true; + CheckButton->Enabled = false; + AnsiString orgcheckbuttoncaption = CheckButton->Caption; + CheckButton->Caption = CheckingButtonLabel->Caption; + + bool all_ok = true; + try + { + for(int i = 0; i < ListView->Items->Count; i++) + { + + AnsiString filename = BaseDir + ListView->Items->Item[i]->Caption; + ListView->Items->Item[i]->MakeVisible(false); + CurrentCheckingItem = ListView->Items->Item[i]; + bool res; + try + { + res = CheckSignature(filename, PublicKey, SigProgressNotify); + } + catch(...) + { + res = false; + } + all_ok = all_ok && res; + if(res) + ListView->Items->Item[i]->SubItems->Strings[0] = NotBrokenLabel->Caption; + else + ListView->Items->Item[i]->SubItems->Strings[0] = BrokenLabel->Caption; + + if(Aborting) break; + } + } + catch(...) + { + Checking = false; + CheckButton->Caption = orgcheckbuttoncaption; + CheckButton->Enabled = true; + throw; + } + Checking = false; + CheckButton->Caption = orgcheckbuttoncaption; + CheckButton->Enabled = true; + + MoreThanOneFileIsBrokenLabel->Visible = !all_ok; + + CopyResultButton->Enabled = true; + + if(Aborting) Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::FormCloseQuery(TObject *Sender, bool &CanClose) +{ + if(!Checking) + { + CanClose = true; + return; + } + CanClose = false; + Aborting = true; +} +//--------------------------------------------------------------------------- +bool __fastcall TMainForm::SigProgressNotify(int percent) +{ + // 署名チェック中の進行状態に合わせて呼ばれる + DWORD curtick = GetTickCount(); + if(curtick - LastDisplayedTick < 100) return !Aborting; + LastDisplayedTick = curtick; + + AnsiString str; + str.sprintf(CheckingLabel->Caption.c_str(), percent); + CurrentCheckingItem->SubItems->Strings[0] = str; + + Application->ProcessMessages(); + + return !Aborting; +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::CopyResultButtonClick(TObject *Sender) +{ + // 結果をクリップボードにコピーする + AnsiString str = TDateTime(Now()).DateTimeString() + "\r\n\r\n"; + + for(int i = 0; i < ListView->Items->Count; i++) + { + AnsiString attr = "\t\t\t"; + AnsiString filename = BaseDir + ListView->Items->Item[i]->Caption; + HANDLE hf = CreateFile(filename.c_str(), GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(hf != INVALID_HANDLE_VALUE) + { + FILETIME time; + ZeroMemory(&time, sizeof(time)); + GetFileTime(hf, NULL, NULL, &time); + SYSTEMTIME st; + ZeroMemory(&st, sizeof(st)); + FileTimeToSystemTime(&time, &st); + char tmp[256]; + sprintf(tmp, "\t%d/%02d/%02d %02d:%02d:%02d", + st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + + + attr = tmp; + DWORD sizelow; + DWORD sizehigh; + sizelow = GetFileSize(hf, &sizehigh); + sprintf(tmp, "%Ld", (__int64)((__int64)(sizelow) + + ((__int64)sizehigh << 32))); + attr += "\t" + AnsiString(tmp) + "\t"; + + CloseHandle(hf); + } + + + str += filename + attr + + ListView->Items->Item[i]->SubItems->Strings[0] + "\r\n"; + } + + str.cat_sprintf("\r\nAll files in target directory (0x%04X files):\r\n", AllFileCount); + str += AllFileList; + + Clipboard()->AsText = str; + + Application->MessageBox(TheResultWasCopiedIntoClipboardLabel->Caption.c_str(), + Caption.c_str(), MB_OK|MB_ICONINFORMATION); + +} +//--------------------------------------------------------------------------- +void __fastcall TMainForm::MakeFileList(AnsiString path, int baselen) +{ + // ファイルのリストを作成する + TSearchRec r; + int done; + + done=FindFirst(path + "*.*" ,faAnyFile, r); + try + { + while(!done) + { + if(r.FindData.cFileName[0]!='.') + { + if(! (r.Attr & faDirectory)) + { + // a file + AnsiString name = AnsiString(path.c_str()+ baselen) + + r.FindData.cFileName; + + // append to the list + AllFileList.cat_sprintf("%s\t%11d\t%s\r\n", + FileDateToDateTime(r.Time).FormatString("yyyy/mm/dd hh:nn:ss").c_str(), + r.Size, + (path + r.FindData.cFileName).c_str()); + AllFileCount ++; + + // check file extension + AnsiString fileext = ExtractFileExt(r.FindData.cFileName); + bool add; + if(!fileext.AnsiCompareIC(".sig")) + { + // 拡張子が sig は署名ファイルなので追加しない + add = false; + } + else if(!fileext.AnsiCompareIC(".exe") && + CheckExeHasSignature(path + r.FindData.cFileName)) + { + // EXEファイルかつ署名つきのファイルの場合は追加する + add = true; + } + else + { + // それ以外の場合は、.sig ファイルが存在すれば追加する + add = FileExists(path + r.FindData.cFileName + ".sig"); + } + + if(add) + { + TListItem * item = ListView->Items->Add(); + item->Caption = (path + r.FindData.cFileName).c_str() + + baselen; + } + } + else + { + // a directory + + // append to the list + AllFileList.cat_sprintf("%s\t[directory]\t%s\r\n", + FileDateToDateTime(r.Time).FormatString("yyyy/mm/dd hh:nn:ss").c_str(), + (path + r.FindData.cFileName).c_str()); + AllFileCount ++; + + // recurse + if(r.Name != "." && r.Name != "..") + { + MakeFileList(path + r.FindData.cFileName+ + AnsiString("\\"), baselen); + } + } + } + done=FindNext(r); + } + } + catch(...) + { + FindClose(r); + throw; + } + FindClose(r); +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/sigchecker/MainUnit.dfm b/tools/win32/sigchecker/MainUnit.dfm new file mode 100644 index 0000000..f484355 --- /dev/null +++ b/tools/win32/sigchecker/MainUnit.dfm @@ -0,0 +1,155 @@ +object MainForm: TMainForm + Left = 56 + Top = 76 + ActiveControl = CheckButton + BorderStyle = bsDialog + Caption = 'MainForm' + ClientHeight = 368 + ClientWidth = 490 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + OldCreateOrder = False + Position = poDefaultPosOnly + OnCloseQuery = FormCloseQuery + PixelsPerInch = 96 + TextHeight = 12 + object NotYetCheckedLabel: TLabel + Left = 96 + Top = 328 + Width = 51 + Height = 12 + Caption = '未チェック' + Visible = False + end + object CheckingLabel: TLabel + Left = 152 + Top = 328 + Width = 83 + Height = 12 + Caption = 'チェック中(%d%%)' + Visible = False + end + object BrokenLabel: TLabel + Left = 272 + Top = 328 + Width = 24 + Height = 12 + Caption = '破損' + Visible = False + end + object NotBrokenLabel: TLabel + Left = 240 + Top = 328 + Width = 24 + Height = 12 + Caption = '正常' + Visible = False + end + object MoreThanOneFileIsBrokenLabel: TLabel + Left = 112 + Top = 344 + Width = 148 + Height = 12 + Caption = ' 破損したファイルがあります ' + Color = clRed + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWhite + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + ParentColor = False + ParentFont = False + Visible = False + end + object CheckingButtonLabel: TLabel + Left = 104 + Top = 352 + Width = 57 + Height = 12 + Caption = 'チェック中...' + Visible = False + end + object TheResultWasCopiedIntoClipboardLabel: TLabel + Left = 304 + Top = 328 + Width = 187 + Height = 12 + Caption = '結果をクリップボードにコピーしました' + Visible = False + end + object NoticeMemo: TMemo + Left = 8 + Top = 8 + Width = 473 + Height = 57 + BorderStyle = bsNone + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = 'MS Pゴシック' + Font.Style = [] + ParentFont = False + ReadOnly = True + TabOrder = 0 + end + object ListView: TListView + Left = 8 + Top = 72 + Width = 473 + Height = 249 + Columns = < + item + Caption = 'ファイル名' + Width = 180 + end + item + Caption = '状態' + Width = 80 + end> + ColumnClick = False + GridLines = True + RowSelect = True + ShowWorkAreas = True + SortType = stText + TabOrder = 1 + ViewStyle = vsReport + end + object CheckButton: TButton + Left = 8 + Top = 336 + Width = 89 + Height = 25 + Caption = 'チェック(&V)' + Default = True + TabOrder = 2 + OnClick = CheckButtonClick + end + object CloseButton: TButton + Left = 392 + Top = 336 + Width = 89 + Height = 25 + Cancel = True + Caption = '閉じる(&X)' + TabOrder = 4 + OnClick = CloseButtonClick + end + object CopyResultButton: TButton + Left = 272 + Top = 336 + Width = 107 + Height = 25 + Hint = '結果をクリップボードにコピーします' + Caption = '結果をコピー(&C)' + Enabled = False + ParentShowHint = False + ShowHint = True + TabOrder = 3 + OnClick = CopyResultButtonClick + end +end diff --git a/tools/win32/sigchecker/MainUnit.h b/tools/win32/sigchecker/MainUnit.h new file mode 100644 index 0000000..cefe455 --- /dev/null +++ b/tools/win32/sigchecker/MainUnit.h @@ -0,0 +1,49 @@ +//--------------------------------------------------------------------------- + +#ifndef MainUnitH +#define MainUnitH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TMainForm : public TForm +{ +__published: // IDE 管理のコンポーネント + TMemo *NoticeMemo; + TListView *ListView; + TButton *CheckButton; + TButton *CloseButton; + TLabel *NotYetCheckedLabel; + TLabel *CheckingLabel; + TLabel *BrokenLabel; + TLabel *NotBrokenLabel; + TLabel *MoreThanOneFileIsBrokenLabel; + TLabel *CheckingButtonLabel; + TButton *CopyResultButton; + TLabel *TheResultWasCopiedIntoClipboardLabel; + void __fastcall CloseButtonClick(TObject *Sender); + void __fastcall CheckButtonClick(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall CopyResultButtonClick(TObject *Sender); +private: // ユーザー宣言 + bool Checking; // 署名をチェック中かどうか + bool Aborting; // 閉じるボタンが押されたか + AnsiString BaseDir; + AnsiString PublicKey; + TListItem *CurrentCheckingItem; + AnsiString AllFileList; + int AllFileCount; + DWORD LastDisplayedTick; +public: // ユーザー宣言 + __fastcall TMainForm(TComponent* Owner); +private: // ユーザー宣言 + void __fastcall MakeFileList(AnsiString path, int baselen); + bool __fastcall SigProgressNotify(int percent); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TMainForm *MainForm; +//--------------------------------------------------------------------------- +#endif diff --git a/tools/win32/sigchecker/krkrsiglib/KrkrExecutableUnit.cpp b/tools/win32/sigchecker/krkrsiglib/KrkrExecutableUnit.cpp new file mode 100644 index 0000000..f7c1b53 --- /dev/null +++ b/tools/win32/sigchecker/krkrsiglib/KrkrExecutableUnit.cpp @@ -0,0 +1,72 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "KrkrExecutableUnit.h" + +//--------------------------------------------------------------------------- +#define MIN_KRKR_MARK_SEARCH 512*1024 +#define MAX_KRKR_MARK_SEARCH 4*1024*1024 +//--------------------------------------------------------------------------- +char XOPT_EMBED_AREA_[] = " OPT_EMBED_AREA_"; +char XCORE_SIG_______[] = " CORE_SIG_______"; +char XRELEASE_SIG____[] = " RELEASE_SIG____"; +char XP3_SIG[] = " P3\x0d\x0a\x20\x0a\x1a\x8b\x67\x01"; // mark_size = 11 +//--------------------------------------------------------------------------- +int CheckKrkrExecutable(AnsiString fn, const char *mark) +{ + // Find the mark in the krkr executable. + // All krkr executable have + // "XOPT_EMBED_AREA_" mark at the end of the executable image. + // Additionally + // "XCORE_SIG_______" and "XRELEASE_SIG____" are reserved area for + // signatures. + // "XP3\x0d\x0a\x20\x0a\x1a\x8b\x67\x01" are optional XP3 archive attached + // to the executable. + + // This function returns the mark offset + // (area size bofore specified mark) + int mark_size = strlen(mark); + + TFileStream *st = new TFileStream(fn, fmOpenRead | fmShareDenyWrite); + int imagesize = 0; + try + { + int ofs = MIN_KRKR_MARK_SEARCH; + char buf[4096]; + int read; + bool found = false; + st->Position = ofs; + while( (read = st->Read(buf, sizeof(buf)) ) != 0) + { + for(int i = 0; i < read; i += 16) // the mark is aligned to paragraph (16bytes) + { + if(buf[i] == 'X') + { + if(!memcmp(buf + i + 1, mark + 1, mark_size - 1)) + { + // mark found + imagesize = i + ofs; + found = true; + break; + } + } + } + if(found) break; + ofs += read; + if(ofs >= MAX_KRKR_MARK_SEARCH) break; + } + } + catch(...) + { + delete st; + throw; + } + delete st; + + return imagesize; +} +//--------------------------------------------------------------------------- + +#pragma package(smart_init) diff --git a/tools/win32/sigchecker/krkrsiglib/KrkrExecutableUnit.h b/tools/win32/sigchecker/krkrsiglib/KrkrExecutableUnit.h new file mode 100644 index 0000000..f22c665 --- /dev/null +++ b/tools/win32/sigchecker/krkrsiglib/KrkrExecutableUnit.h @@ -0,0 +1,14 @@ +//--------------------------------------------------------------------------- + +#ifndef KrkrExecutableUnitH +#define KrkrExecutableUnitH +//--------------------------------------------------------------------------- +extern char XOPT_EMBED_AREA_[];// = " OPT_EMBED_AREA_"; +extern char XCORE_SIG_______[];// = " CORE_SIG_______"; +extern char XRELEASE_SIG____[];// = " RELEASE_SIG____"; +extern char XP3_SIG[]; // = " P3\x0d\x0a\x20\x0a\x1a\x8b\x67\x01"; // mark_size = 11 +//--------------------------------------------------------------------------- +extern int CheckKrkrExecutable(AnsiString fn, const char *mark); +//--------------------------------------------------------------------------- + +#endif diff --git a/tools/win32/sigchecker/krkrsiglib/KrkrSignatureUnit.cpp b/tools/win32/sigchecker/krkrsiglib/KrkrSignatureUnit.cpp new file mode 100644 index 0000000..053baa7 --- /dev/null +++ b/tools/win32/sigchecker/krkrsiglib/KrkrSignatureUnit.cpp @@ -0,0 +1,264 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#define _MSC_VER +#include +#undef _MSC_VER + +#include "KrkrExecutableUnit.h" +#include "KrkrSignatureUnit.h" + + +//--------------------------------------------------------------------------- +#define HASH_INIT sha256_init +#define HASH_PROCESS sha256_process +#define HASH_DONE sha256_done +#define HASH_DESC sha256_desc +#define HASH_METHOD_STRING "SHA256" +#define HASH_METHOD_INTERNAL_STRING "sha256" +#define HASH_SIZE 32 +//--------------------------------------------------------------------------- +static bool MakeFileHash(AnsiString fn, unsigned char *hash, int ignorestart, + int ignoreend, TSigProgressNotifyEvent notify) +{ + if(find_hash(HASH_METHOD_INTERNAL_STRING) == -1) + { + int errnum = register_hash(&HASH_DESC); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + } + + + if(notify) + if(!notify(0)) return true; + + int pts = 0; + + TFileStream *fs; + fs = new TFileStream(fn, fmOpenRead | fmShareDenyWrite); + if(ignorestart != -1 && ignoreend == -1) ignoreend = fs->Size; + int signfnsize = fs->Size; + bool interrupted = false; + try + { + hash_state st; + HASH_INIT(&st); + + int read; + unsigned char buf[4096]; + int ofs = 0; + while((read = fs->Read(buf, sizeof(buf))) != 0) + { + if(ignorestart != -1 && read + ofs > ignorestart) + { + read = ignorestart - ofs; + if(read) HASH_PROCESS(&st, buf, read); + break; + } + else + { + HASH_PROCESS(&st, buf, read); + } + ofs += read; + + if(notify) + { + // callback notify + int npts = (int)( (__int64)ofs * (__int64)100 / (__int64)signfnsize ); + if(pts < npts) + { + pts = npts; + if(!notify(pts)) + { + interrupted = true; + break; + } + } + } + } + + if(!interrupted && ignorestart != -1 && fs->Position != ignoreend) + { + fs->Position = ofs = ignoreend; + + while((read = fs->Read(buf, sizeof(buf))) != 0) + { + HASH_PROCESS(&st, buf, read); + ofs += read; + + if(notify) + { + // callback notify + int npts = (int)( (__int64)ofs * (__int64)100 / (__int64)signfnsize ); + if(pts < npts) + { + pts = npts; + if(!notify(pts)) + { + interrupted = true; + break; + } + } + } + } + } + + HASH_DONE(&st, hash); + } + catch(...) + { + delete fs; + throw; + } + delete fs; + + + if(!interrupted && notify) + if(!notify(100)) return true; + + return interrupted; +} +//--------------------------------------------------------------------------- +static void ImportKey(AnsiString inkey, AnsiString startline, AnsiString endline, + rsa_key * key) +{ + const char *pkey = inkey.c_str(); + const char *start = strstr(pkey, startline.c_str()); + if(!start) throw Exception("Cannot find \"" + startline + "\" in the key string"); + const char *end = strstr(pkey, endline.c_str()); + if(!end) throw Exception("Cannot find \"" + endline + "\" in the key string"); + + start += startline.Length(); + char buf[10240]; + unsigned long buf_len; + int errnum; + + buf_len = sizeof(buf) - 1; + errnum = base64_decode((const unsigned char*)(start), + end - start, buf, &buf_len); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + + errnum = rsa_import(buf, buf_len, key); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); +} +//--------------------------------------------------------------------------- +static bool CheckSignatureOfFile(AnsiString pubkey, + AnsiString signfn, int ignorestart, int ignoreend, int ofs, + TSigProgressNotifyEvent notify) +{ + // check signature of the file + if(pubkey == "") throw Exception("Specify public key"); + if(signfn == "") throw Exception("Specify target file"); + + // read pubkey + char buf[10240]; + unsigned long buf_len; + char buf_asc[sizeof(buf)*3/2+2]; + unsigned long buf_asc_len; + + rsa_key key; + + ImportKey(pubkey, "-----BEGIN PUBLIC KEY-----", "-----END PUBLIC KEY-----", + &key); + + // read signature file + + TFileStream *st; + if(ofs == -1) + { + // separated + st = new TFileStream(signfn + ".sig", fmOpenRead); + } + else + { + // embedded + st = new TFileStream(signfn, fmOpenRead); + st->Position = ofs; + } + try + { + buf_asc_len = st->Read(buf_asc, sizeof(buf_asc) - 1); + } + catch(...) + { + delete st; + throw; + } + delete st; + + buf_asc[buf_asc_len] = 0; + buf_asc_len = strlen(buf_asc); + + AnsiString signmark("-- SIGNATURE - " HASH_METHOD_STRING "/PSS/RSA --"); + if(strncmp(buf_asc, signmark.c_str(), signmark.Length())) + throw Exception("Invalid signature file format"); + + buf_len = sizeof(buf) - 1; + int errnum = base64_decode((const unsigned char*)(buf_asc + signmark.Length()), + buf_asc_len - signmark.Length(), buf, &buf_len); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + + int stat = 0; + try + { + // make target hash + unsigned char hash[HASH_SIZE]; + bool interrupted = MakeFileHash(signfn, hash, ignorestart, ignoreend, + notify); + if(!interrupted) + { + // check signature + errnum = rsa_verify_hash(buf, buf_len, hash, HASH_SIZE, + find_hash(HASH_METHOD_INTERNAL_STRING), HASH_SIZE, + &stat, &key); + if(errnum != CRYPT_OK) throw Exception(error_to_string(errnum)); + } + else + { + stat = 0; + } + } + catch(...) + { + rsa_free(&key); + throw; + } + rsa_free(&key); + + return stat; +} +//--------------------------------------------------------------------------- + + +//--------------------------------------------------------------------------- +extern bool CheckExeHasSignature(AnsiString fn) +{ + // check whether "fn" has executable signature of KIRIKIRI. + return CheckKrkrExecutable(fn, XRELEASE_SIG____) != 0; +} +//--------------------------------------------------------------------------- +extern bool CheckSignature(AnsiString fn, AnsiString publickey, + TSigProgressNotifyEvent notify) +{ + bool result; + + int ignorestart = CheckKrkrExecutable(fn, XOPT_EMBED_AREA_); + int signofs = CheckKrkrExecutable(fn, XRELEASE_SIG____); + int xp3ofs = CheckKrkrExecutable(fn, XP3_SIG); + + if(ignorestart != 0 && signofs != 0) + { + // krkr executable + result = CheckSignatureOfFile(publickey, fn, ignorestart, + xp3ofs?xp3ofs:-1, signofs+ 16+4, notify); + } + else + { + // normal file + result = CheckSignatureOfFile(publickey, fn, -1, -1, -1, notify); + } + + return result; +} +//--------------------------------------------------------------------------- + diff --git a/tools/win32/sigchecker/krkrsiglib/KrkrSignatureUnit.h b/tools/win32/sigchecker/krkrsiglib/KrkrSignatureUnit.h new file mode 100644 index 0000000..e6f20e0 --- /dev/null +++ b/tools/win32/sigchecker/krkrsiglib/KrkrSignatureUnit.h @@ -0,0 +1,11 @@ +//--------------------------------------------------------------------------- +#ifndef KrkrSignatureUnitH +#define KrkrSignatureUnitH +//--------------------------------------------------------------------------- +extern bool CheckExeHasSignature(AnsiString fn); +typedef bool __fastcall (__closure *TSigProgressNotifyEvent)(int percent); +extern bool CheckSignature(AnsiString fn, AnsiString publickey, + TSigProgressNotifyEvent notify); +//--------------------------------------------------------------------------- + +#endif diff --git a/tools/win32/sigchecker/loupe.ico b/tools/win32/sigchecker/loupe.ico new file mode 100644 index 0000000000000000000000000000000000000000..a0575ca1fd5230038e87a81246970bb97ba9af0d GIT binary patch literal 18718 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 literal 0 HcmV?d00001 diff --git a/tools/win32/sigchecker/loupe.svg b/tools/win32/sigchecker/loupe.svg new file mode 100644 index 0000000..6829a22 --- /dev/null +++ b/tools/win32/sigchecker/loupe.svg @@ -0,0 +1,267 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/win32/sigchecker/sigchk.bpr b/tools/win32/sigchecker/sigchk.bpr new file mode 100644 index 0000000..e0288d2 --- /dev/null +++ b/tools/win32/sigchecker/sigchk.bpr @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=1 +MajorVer=1 +MinorVer=0 +Release=3 +Build=5 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1041 +CodePage=932 + +[Version Info Keys] +CompanyName=kikyou.info +FileDescription=Digital signature/file integrity check tool +FileVersion=1.0.3.5 +InternalName=sigchk +LegalCopyright=(C) 2004-2009, W.Dee All rights reserved. +LegalTrademarks= +OriginalFilename=sigchk.exe +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[Excluded Packages] +$(BCB)\Bin\dclite50.bpl=Borland Integrated Translation Environment + +[HistoryLists\hlIncludePath] +Count=3 +Item0=krkrsiglib;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\include\tomcrypt1 +Item1=krkrsiglib;$(BCB)\include;$(BCB)\include\vcl;$(BCB)\include\tomcrypt +Item2=krkrsiglib;$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=krkrsiglib;$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=1 +Item0=_DEBUG + +[HistoryLists\hlFinalOutputDir] +Count=2 +Item0=..\..\..\..\bin\win32\enduser-tools\ +Item1=..\..\..\..\bin\win32\enduser-tools + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication= +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + + \ No newline at end of file diff --git a/tools/win32/sigchecker/sigchk.cpp b/tools/win32/sigchecker/sigchk.cpp new file mode 100644 index 0000000..f86132d --- /dev/null +++ b/tools/win32/sigchecker/sigchk.cpp @@ -0,0 +1,25 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop +USERES("sigchk.res"); +USEFORM("MainUnit.cpp", MainForm); +USEUNIT("krkrsiglib\KrkrExecutableUnit.cpp"); +USEUNIT("krkrsiglib\KrkrSignatureUnit.cpp"); +USELIB("..\..\..\..\..\..\..\Lib\libtomcrypt1.lib"); +//--------------------------------------------------------------------------- +WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ + try + { + Application->Initialize(); + Application->CreateForm(__classid(TMainForm), &MainForm); + Application->Run(); + } + catch (Exception &exception) + { + Application->ShowException(&exception); + } + return 0; +} +//--------------------------------------------------------------------------- diff --git a/tools/win32/sigchecker/sigchk.ini b/tools/win32/sigchecker/sigchk.ini new file mode 100644 index 0000000..72f59ba --- /dev/null +++ b/tools/win32/sigchecker/sigchk.ini @@ -0,0 +1,16 @@ +[message] +; notice には画面上部に表示するメッセージを指定します。 +; notice= で始まる行は一行で(改行をいれずに)記述しなければなりませんが、 +; [cr] を書くとそこに改行を入れることができます。 +notice=このプログラムでは、ファイルの破損をチェックすることができます。[cr]下の「チェック」ボタンを押してください。[cr]一覧の「状態」欄に「破損」と表示された場合はファイルが破損しています。再インストールを試みてください。 + +; caption にはウィンドウのタイトルバーに表示する文字列を指定します。 +caption=ファイル破損チェックツール + +[key] +; ここでは、電子署名の確認に用いる公開鍵を指定します。 +-----BEGIN PUBLIC KEY----- +MIGJAoGBAJYfPysW57qE3J2ddGWEG+RzXUzFkWa0ct3p7qJfuWDB+52DbfS9qSpw +iTHQ54vl7K35x+WDQdn29cfgJxp9UD3fzY4h6E2ReE9vj4h0FCMK8dpCFnQkOD/M +hDSiXfXz7KmfMXppM0CjofvH+IL7BJ3/GcLFcuEw3hEnzoajIm1TAgMBAAE= +-----END PUBLIC KEY----- diff --git a/tools/win32/sigchecker/sigchk.res b/tools/win32/sigchecker/sigchk.res new file mode 100644 index 0000000000000000000000000000000000000000..ec87d203dc337c31a830a4ab617e1c77ce8900e7 GIT binary patch literal 19896 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 X+)NQl=nQgsn&aX5*c&_4LHvIJpPN)h literal 0 HcmV?d00001