Repository: YuriSizuku/Kirikiroid2Yuri Branch: yuri Commit: 6e61ce3b8141 Files: 685 Total size: 8.5 MB Directory structure: gitextract_q549lhv5/ ├── .github/ │ └── workflows/ │ └── build_android.yml ├── .gitignore ├── .vscode/ │ └── c_cpp_properties.json ├── CMakeLists.txt ├── LICENSE ├── project/ │ ├── android/ │ │ ├── .gitignore │ │ ├── .idea/ │ │ │ ├── .gitignore │ │ │ ├── codeStyles/ │ │ │ │ └── Project.xml │ │ │ ├── compiler.xml │ │ │ ├── gradle.xml │ │ │ ├── jarRepositories.xml │ │ │ ├── misc.xml │ │ │ └── vcs.xml │ │ ├── app/ │ │ │ ├── .gitignore │ │ │ ├── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── cpp/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ └── krkr2_android.cpp │ │ │ ├── java/ │ │ │ │ ├── com/ │ │ │ │ │ └── yuri/ │ │ │ │ │ └── kirikiri2/ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── org/ │ │ │ │ └── tvp/ │ │ │ │ └── kirikiri2/ │ │ │ │ ├── KR2Activity.java │ │ │ │ └── MediaStoreHack.java │ │ │ ├── proguard-rules.pro │ │ │ ├── res/ │ │ │ │ └── values/ │ │ │ │ └── strings.xml │ │ │ └── sign.jks │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ └── settings.gradle │ └── ui/ │ ├── .cocos-project.json │ ├── Resources/ │ │ └── res/ │ │ └── locale/ │ │ ├── en_us.xml │ │ ├── ja_jp.xml │ │ ├── zh_cn.xml │ │ └── zh_tw.xml │ ├── cocosstudio/ │ │ └── ui/ │ │ ├── BottomBar.csd │ │ ├── BottomBarTextInput.csd │ │ ├── CheckListDialog.csd │ │ ├── FileItem.csd │ │ ├── FileManageMenu.csd │ │ ├── GameMenu.csd │ │ ├── KeySelect.csd │ │ ├── ListItem.csd │ │ ├── ListView.csd │ │ ├── MainFileSelector.csd │ │ ├── MediaPlayerBody.csd │ │ ├── MediaPlayerFoot.csd │ │ ├── MediaPlayerNavi.csd │ │ ├── MenuList.csd │ │ ├── MessageBox.csd │ │ ├── NaviBar.csd │ │ ├── NaviBarWithMenu.csd │ │ ├── ProgressBox.csd │ │ ├── RecentListItem.csd │ │ ├── SelectList.csd │ │ ├── SelectListItem.csd │ │ ├── TableView.csd │ │ ├── TextPairInput.csd │ │ ├── WinMgrOverlay.csd │ │ ├── comctrl/ │ │ │ ├── CheckBoxItem.csd │ │ │ ├── SelectListItem.csd │ │ │ ├── SeperateItem.csd │ │ │ ├── SliderIconItem.csd │ │ │ ├── SliderTextItem.csd │ │ │ └── SubDirItem.csd │ │ └── help/ │ │ ├── AllTips.csd │ │ ├── MouseModeTips.csd │ │ ├── ScreenModeTips.csd │ │ └── TouchModeTips.csd │ ├── kr2.ccs │ └── kr2.cfg ├── readme.md ├── script/ │ ├── _androida64.sh │ ├── _fetch.sh │ └── cross_androida64.sh ├── src/ │ ├── core/ │ │ ├── Android.mk │ │ ├── CMakeLists.txt │ │ ├── base/ │ │ │ ├── 7zArchive.cpp │ │ │ ├── BinaryStream.cpp │ │ │ ├── BinaryStream.h │ │ │ ├── CharacterSet.cpp │ │ │ ├── CharacterSet.h │ │ │ ├── EventIntf.cpp │ │ │ ├── EventIntf.h │ │ │ ├── PluginIntf.cpp │ │ │ ├── PluginIntf.h │ │ │ ├── ScriptMgnIntf.cpp │ │ │ ├── ScriptMgnIntf.h │ │ │ ├── StorageIntf.cpp │ │ │ ├── StorageIntf.h │ │ │ ├── SysInitIntf.cpp │ │ │ ├── SysInitIntf.h │ │ │ ├── SystemIntf.cpp │ │ │ ├── SystemIntf.h │ │ │ ├── TARArchive.cpp │ │ │ ├── TextStream.cpp │ │ │ ├── TextStream.h │ │ │ ├── UserEvent.h │ │ │ ├── UtilStreams.cpp │ │ │ ├── UtilStreams.h │ │ │ ├── XP3Archive.cpp │ │ │ ├── XP3Archive.h │ │ │ ├── ZIPArchive.cpp │ │ │ ├── common.h │ │ │ ├── tar.h │ │ │ └── win32/ │ │ │ ├── EventImpl.cpp │ │ │ ├── EventImpl.h │ │ │ ├── FileSelector.cpp │ │ │ ├── FileSelector.h │ │ │ ├── FuncStubs.cpp │ │ │ ├── FuncStubs.h │ │ │ ├── NativeEventQueue.cpp │ │ │ ├── NativeEventQueue.h │ │ │ ├── PluginImpl.cpp │ │ │ ├── PluginImpl.h │ │ │ ├── ScriptMgnImpl.cpp │ │ │ ├── ScriptMgnImpl.h │ │ │ ├── StorageImpl.cpp │ │ │ ├── StorageImpl.h │ │ │ ├── SusieArchive.cpp │ │ │ ├── SusieArchive.h │ │ │ ├── SysInitImpl.cpp │ │ │ ├── SysInitImpl.h │ │ │ ├── SystemImpl.cpp │ │ │ ├── SystemImpl.h │ │ │ └── win32io.h │ │ ├── environ/ │ │ │ ├── Application.cpp │ │ │ ├── Application.h │ │ │ ├── ConfigManager/ │ │ │ │ ├── GlobalConfigManager.cpp │ │ │ │ ├── GlobalConfigManager.h │ │ │ │ ├── IndividualConfigManager.cpp │ │ │ │ ├── IndividualConfigManager.h │ │ │ │ ├── LocaleConfigManager.cpp │ │ │ │ └── LocaleConfigManager.h │ │ │ ├── DetectCPU.cpp │ │ │ ├── DetectCPU.h │ │ │ ├── DumpSend.cpp │ │ │ ├── Platform.h │ │ │ ├── XP3ArchiveRepack.cpp │ │ │ ├── XP3ArchiveRepack.h │ │ │ ├── android/ │ │ │ │ ├── AndroidUtils.cpp │ │ │ │ └── AndroidUtils.h │ │ │ ├── cocos2d/ │ │ │ │ ├── AppDelegate.cpp │ │ │ │ ├── AppDelegate.h │ │ │ │ ├── CCKeyCodeConv.cpp │ │ │ │ ├── CCKeyCodeConv.h │ │ │ │ ├── CustomFileUtils.cpp │ │ │ │ ├── CustomFileUtils.h │ │ │ │ ├── CustomFileUtils.mm │ │ │ │ ├── MainScene.cpp │ │ │ │ ├── MainScene.h │ │ │ │ ├── YUVSprite.cpp │ │ │ │ └── YUVSprite.h │ │ │ ├── combase.h │ │ │ ├── cpu_types.h │ │ │ ├── linux/ │ │ │ │ └── Platform.cpp │ │ │ ├── sdl/ │ │ │ │ └── tvpsdl.cpp │ │ │ ├── typedefine.h │ │ │ ├── ui/ │ │ │ │ ├── BaseForm.cpp │ │ │ │ ├── BaseForm.h │ │ │ │ ├── ConsoleWindow.cpp │ │ │ │ ├── ConsoleWindow.h │ │ │ │ ├── DebugViewLayerForm.cpp │ │ │ │ ├── DebugViewLayerForm.h │ │ │ │ ├── FileSelectorForm.cpp │ │ │ │ ├── FileSelectorForm.h │ │ │ │ ├── GameMainMenu.cpp │ │ │ │ ├── GameMainMenu.h │ │ │ │ ├── GlobalPreferenceForm.cpp │ │ │ │ ├── GlobalPreferenceForm.h │ │ │ │ ├── InGameMenuForm.cpp │ │ │ │ ├── InGameMenuForm.h │ │ │ │ ├── IndividualPreferenceForm.cpp │ │ │ │ ├── IndividualPreferenceForm.h │ │ │ │ ├── MainFileSelectorForm.cpp │ │ │ │ ├── MainFileSelectorForm.h │ │ │ │ ├── MessageBox.cpp │ │ │ │ ├── MessageBox.h │ │ │ │ ├── PreferenceConfig.h │ │ │ │ ├── PreferenceForm.cpp │ │ │ │ ├── PreferenceForm.h │ │ │ │ ├── SeletListForm.cpp │ │ │ │ ├── SeletListForm.h │ │ │ │ ├── SimpleMediaFilePlayer.cpp │ │ │ │ ├── SimpleMediaFilePlayer.h │ │ │ │ ├── TipsHelpForm.cpp │ │ │ │ ├── TipsHelpForm.h │ │ │ │ ├── XP3RepackForm.cpp │ │ │ │ ├── XP3RepackForm.h │ │ │ │ └── extension/ │ │ │ │ ├── ActionExtension.cpp │ │ │ │ ├── ActionExtension.h │ │ │ │ ├── UIExtension.cpp │ │ │ │ └── UIExtension.h │ │ │ ├── vkdefine.h │ │ │ ├── win32/ │ │ │ │ ├── ApplicationSpecialPath.h │ │ │ │ ├── CompatibleNativeFuncs.cpp │ │ │ │ ├── CompatibleNativeFuncs.h │ │ │ │ ├── ConfigFormUnit.cpp │ │ │ │ ├── ConfigFormUnit.h │ │ │ │ ├── DetectCPU.cpp │ │ │ │ ├── DetectCPU.h │ │ │ │ ├── EmergencyExit.cpp │ │ │ │ ├── EmergencyExit.h │ │ │ │ ├── HintWindow.cpp │ │ │ │ ├── HintWindow.h │ │ │ │ ├── ImeControl.h │ │ │ │ ├── MainFormUnit.cpp │ │ │ │ ├── MainFormUnit.h │ │ │ │ ├── MouseCursor.cpp │ │ │ │ ├── MouseCursor.h │ │ │ │ ├── Platform.cpp │ │ │ │ ├── SystemControl.cpp │ │ │ │ ├── SystemControl.h │ │ │ │ ├── TVPWindow.cpp │ │ │ │ ├── TVPWindow.h │ │ │ │ ├── TouchPoint.cpp │ │ │ │ ├── TouchPoint.h │ │ │ │ ├── VersionFormUnit.cpp │ │ │ │ ├── VersionFormUnit.h │ │ │ │ ├── WindowFormUnit.cpp │ │ │ │ ├── WindowFormUnit.h │ │ │ │ ├── WindowsUtil.cpp │ │ │ │ ├── WindowsUtil.h │ │ │ │ ├── config.h │ │ │ │ └── my_HintWindow.cpp │ │ │ └── win32type.h │ │ ├── extension/ │ │ │ ├── Extension.cpp │ │ │ └── Extension.h │ │ ├── movie/ │ │ │ ├── ffmpeg/ │ │ │ │ ├── AE.h │ │ │ │ ├── AEAudioFormat.h │ │ │ │ ├── AEChannelData.h │ │ │ │ ├── AEChannelInfo.cpp │ │ │ │ ├── AEChannelInfo.h │ │ │ │ ├── AEFactory.cpp │ │ │ │ ├── AEFactory.h │ │ │ │ ├── AEStream.h │ │ │ │ ├── AEStreamData.h │ │ │ │ ├── AEStreamInfo.cpp │ │ │ │ ├── AEStreamInfo.h │ │ │ │ ├── AEUtil.cpp │ │ │ │ ├── AEUtil.h │ │ │ │ ├── AudioCodec.h │ │ │ │ ├── AudioCodecFFmpeg.cpp │ │ │ │ ├── AudioCodecFFmpeg.h │ │ │ │ ├── AudioCodecPassthrough.cpp │ │ │ │ ├── AudioCodecPassthrough.h │ │ │ │ ├── AudioDevice.cpp │ │ │ │ ├── AudioDevice.h │ │ │ │ ├── BaseRenderer.cpp │ │ │ │ ├── BaseRenderer.h │ │ │ │ ├── BitstreamStats.cpp │ │ │ │ ├── BitstreamStats.h │ │ │ │ ├── Clock.cpp │ │ │ │ ├── Clock.h │ │ │ │ ├── CodecUtils.cpp │ │ │ │ ├── CodecUtils.h │ │ │ │ ├── Codecs.h │ │ │ │ ├── Demux.cpp │ │ │ │ ├── Demux.h │ │ │ │ ├── DemuxFFmpeg.cpp │ │ │ │ ├── DemuxFFmpeg.h │ │ │ │ ├── DemuxPacket.cpp │ │ │ │ ├── DemuxPacket.h │ │ │ │ ├── FactoryCodec.cpp │ │ │ │ ├── FactoryCodec.h │ │ │ │ ├── Geometry.h │ │ │ │ ├── IAudioCallback.h │ │ │ │ ├── IVideoPlayer.h │ │ │ │ ├── InputStream.cpp │ │ │ │ ├── InputStream.h │ │ │ │ ├── KRMovieDef.h │ │ │ │ ├── KRMovieLayer.cpp │ │ │ │ ├── KRMovieLayer.h │ │ │ │ ├── KRMoviePlayer.cpp │ │ │ │ ├── KRMoviePlayer.h │ │ │ │ ├── MathUtils.h │ │ │ │ ├── Message.cpp │ │ │ │ ├── Message.h │ │ │ │ ├── MessageQueue.cpp │ │ │ │ ├── MessageQueue.h │ │ │ │ ├── OptionInfo.h │ │ │ │ ├── ProcessInfo.cpp │ │ │ │ ├── ProcessInfo.h │ │ │ │ ├── Ref.h │ │ │ │ ├── RenderFlags.cpp │ │ │ │ ├── RenderFlags.h │ │ │ │ ├── RenderFormats.h │ │ │ │ ├── StreamInfo.cpp │ │ │ │ ├── StreamInfo.h │ │ │ │ ├── TVPMediaDemux.cpp │ │ │ │ ├── TVPMediaDemux.h │ │ │ │ ├── Thread.cpp │ │ │ │ ├── Thread.h │ │ │ │ ├── TimeUtils.cpp │ │ │ │ ├── TimeUtils.h │ │ │ │ ├── Timer.cpp │ │ │ │ ├── Timer.h │ │ │ │ ├── VideoCodec.cpp │ │ │ │ ├── VideoCodec.h │ │ │ │ ├── VideoCodecFFmpeg.cpp │ │ │ │ ├── VideoCodecFFmpeg.h │ │ │ │ ├── VideoPlayer.cpp │ │ │ │ ├── VideoPlayer.h │ │ │ │ ├── VideoPlayerAudio.cpp │ │ │ │ ├── VideoPlayerAudio.h │ │ │ │ ├── VideoPlayerVideo.cpp │ │ │ │ ├── VideoPlayerVideo.h │ │ │ │ ├── VideoReferenceClock.cpp │ │ │ │ ├── VideoReferenceClock.h │ │ │ │ ├── VideoRenderer.cpp │ │ │ │ ├── VideoRenderer.h │ │ │ │ ├── config.h │ │ │ │ └── krffmpeg.cpp │ │ │ └── krmovie.cpp │ │ ├── msg/ │ │ │ ├── MsgIntf.cpp │ │ │ ├── MsgIntf.h │ │ │ ├── MsgIntfInc.h │ │ │ └── win32/ │ │ │ ├── MsgImpl.cpp │ │ │ ├── MsgImpl.h │ │ │ ├── MsgLoad.cpp │ │ │ ├── OptionsDesc.cpp │ │ │ ├── OptionsDesc.h │ │ │ ├── ReadOptionDesc.cpp │ │ │ └── ReadOptionDesc.h │ │ ├── sound/ │ │ │ ├── ARM/ │ │ │ │ ├── WaveFunctionARM.cpp │ │ │ │ └── wavemix_arm.c │ │ │ ├── CDDAIntf.cpp │ │ │ ├── CDDAIntf.h │ │ │ ├── FFWaveDecoder.cpp │ │ │ ├── FFWaveDecoder.h │ │ │ ├── MIDIIntf.cpp │ │ │ ├── MIDIIntf.h │ │ │ ├── MathAlgorithms.cpp │ │ │ ├── MathAlgorithms.h │ │ │ ├── PhaseVocoderDSP.cpp │ │ │ ├── PhaseVocoderDSP.h │ │ │ ├── PhaseVocoderFilter.cpp │ │ │ ├── PhaseVocoderFilter.h │ │ │ ├── RingBuffer.h │ │ │ ├── SoundBufferBaseIntf.cpp │ │ │ ├── SoundBufferBaseIntf.h │ │ │ ├── VorbisWaveDecoder.cpp │ │ │ ├── VorbisWaveDecoder.h │ │ │ ├── WaveFormatConverter.cpp │ │ │ ├── WaveFormatConverter_SSE.cpp │ │ │ ├── WaveIntf.cpp │ │ │ ├── WaveIntf.h │ │ │ ├── WaveLoopManager.cpp │ │ │ ├── WaveLoopManager.h │ │ │ ├── WaveSegmentQueue.cpp │ │ │ ├── WaveSegmentQueue.h │ │ │ ├── win32/ │ │ │ │ ├── CDDAImpl.cpp │ │ │ │ ├── CDDAImpl.h │ │ │ │ ├── MIDIImpl.cpp │ │ │ │ ├── MIDIImpl.h │ │ │ │ ├── SoundBufferBaseImpl.cpp │ │ │ │ ├── SoundBufferBaseImpl.h │ │ │ │ ├── WaveImpl.cpp │ │ │ │ ├── WaveImpl.h │ │ │ │ ├── WaveMixer.cpp │ │ │ │ ├── WaveMixer.h │ │ │ │ ├── kmp_pi.h │ │ │ │ ├── oldwaveunpacker.h │ │ │ │ ├── tvpsnd.c │ │ │ │ ├── tvpsnd.cpp │ │ │ │ ├── tvpsnd.h │ │ │ │ └── tvpsnd.idl │ │ │ └── xmmlib.h │ │ ├── tjs2/ │ │ │ ├── tjs.cpp │ │ │ ├── tjs.h │ │ │ ├── tjs.tab.cpp │ │ │ ├── tjs.tab.h │ │ │ ├── tjs.tab.hpp │ │ │ ├── tjsArray.cpp │ │ │ ├── tjsArray.h │ │ │ ├── tjsBinarySerializer.cpp │ │ │ ├── tjsBinarySerializer.h │ │ │ ├── tjsByteCodeLoader.cpp │ │ │ ├── tjsByteCodeLoader.h │ │ │ ├── tjsCommHead.h │ │ │ ├── tjsCompileControl.cpp │ │ │ ├── tjsCompileControl.h │ │ │ ├── tjsConfig.cpp │ │ │ ├── tjsConfig.h │ │ │ ├── tjsConstArrayData.cpp │ │ │ ├── tjsConstArrayData.h │ │ │ ├── tjsDate.cpp │ │ │ ├── tjsDate.h │ │ │ ├── tjsDateParser.cpp │ │ │ ├── tjsDateParser.h │ │ │ ├── tjsDateWordMap.cc │ │ │ ├── tjsDebug.cpp │ │ │ ├── tjsDebug.h │ │ │ ├── tjsDictionary.cpp │ │ │ ├── tjsDictionary.h │ │ │ ├── tjsDisassemble.cpp │ │ │ ├── tjsError.cpp │ │ │ ├── tjsError.h │ │ │ ├── tjsErrorDefs.h │ │ │ ├── tjsErrorInc.h │ │ │ ├── tjsError_jp.h │ │ │ ├── tjsException.cpp │ │ │ ├── tjsException.h │ │ │ ├── tjsGlobalStringMap.cpp │ │ │ ├── tjsGlobalStringMap.h │ │ │ ├── tjsHashSearch.h │ │ │ ├── tjsInterCodeExec.cpp │ │ │ ├── tjsInterCodeExec.h │ │ │ ├── tjsInterCodeGen.cpp │ │ │ ├── tjsInterCodeGen.h │ │ │ ├── tjsInterface.cpp │ │ │ ├── tjsInterface.h │ │ │ ├── tjsLex.cpp │ │ │ ├── tjsLex.h │ │ │ ├── tjsMT19937ar-cok.cpp │ │ │ ├── tjsMT19937ar-cok.h │ │ │ ├── tjsMath.cpp │ │ │ ├── tjsMath.h │ │ │ ├── tjsMessage.cpp │ │ │ ├── tjsMessage.h │ │ │ ├── tjsNamespace.cpp │ │ │ ├── tjsNamespace.h │ │ │ ├── tjsNative.cpp │ │ │ ├── tjsNative.h │ │ │ ├── tjsObject.cpp │ │ │ ├── tjsObject.h │ │ │ ├── tjsObjectExtendable.cpp │ │ │ ├── tjsObjectExtendable.h │ │ │ ├── tjsOctPack.cpp │ │ │ ├── tjsOctPack.h │ │ │ ├── tjsRandomGenerator.cpp │ │ │ ├── tjsRandomGenerator.h │ │ │ ├── tjsRegExp.cpp │ │ │ ├── tjsRegExp.h │ │ │ ├── tjsScriptBlock.cpp │ │ │ ├── tjsScriptBlock.h │ │ │ ├── tjsScriptCache.cpp │ │ │ ├── tjsScriptCache.h │ │ │ ├── tjsString.cpp │ │ │ ├── tjsString.h │ │ │ ├── tjsTypes.h │ │ │ ├── tjsUtils.cpp │ │ │ ├── tjsUtils.h │ │ │ ├── tjsVariant.cpp │ │ │ ├── tjsVariant.h │ │ │ ├── tjsVariantString.cpp │ │ │ ├── tjsVariantString.h │ │ │ ├── tjsdate.tab.cpp │ │ │ ├── tjsdate.tab.h │ │ │ ├── tjsdate.tab.hpp │ │ │ ├── tjspp.tab.cpp │ │ │ └── tjspp.tab.hpp │ │ ├── utils/ │ │ │ ├── ClipboardIntf.cpp │ │ │ ├── ClipboardIntf.h │ │ │ ├── DebugIntf.cpp │ │ │ ├── DebugIntf.h │ │ │ ├── Debugger.h │ │ │ ├── Exception.h │ │ │ ├── FilePathUtil.h │ │ │ ├── KAGParser.cpp │ │ │ ├── KAGParser.h │ │ │ ├── MathAlgorithms.h │ │ │ ├── MathAlgorithms_Default.cpp │ │ │ ├── MathAlgorithms_Default.h │ │ │ ├── MiscUtility.cpp │ │ │ ├── ObjectList.h │ │ │ ├── PadIntf.cpp │ │ │ ├── PadIntf.h │ │ │ ├── Random.cpp │ │ │ ├── Random.h │ │ │ ├── RealFFT.h │ │ │ ├── RealFFT_Default.cpp │ │ │ ├── StringUtil.h │ │ │ ├── ThreadIntf.cpp │ │ │ ├── ThreadIntf.h │ │ │ ├── TickCount.cpp │ │ │ ├── TickCount.h │ │ │ ├── TimerIntf.cpp │ │ │ ├── TimerIntf.h │ │ │ ├── VelocityTracker.cpp │ │ │ ├── VelocityTracker.h │ │ │ ├── encoding/ │ │ │ │ ├── gbk2unicode.c │ │ │ │ └── jis2unicode.c │ │ │ ├── iconv/ │ │ │ │ ├── iconv.h │ │ │ │ └── utf8.h │ │ │ ├── md5.c │ │ │ ├── md5.h │ │ │ ├── minizip/ │ │ │ │ ├── crypt.h │ │ │ │ ├── ioapi.cpp │ │ │ │ ├── ioapi.h │ │ │ │ ├── unzip.c │ │ │ │ ├── unzip.h │ │ │ │ ├── zip.c │ │ │ │ └── zip.h │ │ │ └── win32/ │ │ │ ├── ClipboardImpl.cpp │ │ │ ├── ClipboardImpl.h │ │ │ ├── DebugImpl.cpp │ │ │ ├── DebugImpl.h │ │ │ ├── PadImpl.cpp │ │ │ ├── PadImpl.h │ │ │ ├── TVPTimer.cpp │ │ │ ├── TVPTimer.h │ │ │ ├── ThreadImpl.cpp │ │ │ ├── ThreadImpl.h │ │ │ ├── TimerImpl.cpp │ │ │ └── TimerImpl.h │ │ └── visual/ │ │ ├── ARM/ │ │ │ ├── AlphaMovie_mjpeg.h │ │ │ ├── tvpgl_arm.cpp │ │ │ ├── tvpgl_arm_intf.h │ │ │ └── tvpgl_arm_route.h │ │ ├── BitmapIntf.cpp │ │ ├── BitmapIntf.h │ │ ├── BitmapLayerTreeOwner.cpp │ │ ├── BitmapLayerTreeOwner.h │ │ ├── CharacterData.cpp │ │ ├── CharacterData.h │ │ ├── ComplexRect.cpp │ │ ├── ComplexRect.h │ │ ├── FontImpl.cpp │ │ ├── FontImpl.h │ │ ├── FontRasterizer.h │ │ ├── FontSystem.cpp │ │ ├── FontSystem.h │ │ ├── FreeType.cpp │ │ ├── FreeType.h │ │ ├── FreeTypeFace.h │ │ ├── FreeTypeFontRasterizer.cpp │ │ ├── FreeTypeFontRasterizer.h │ │ ├── GraphicsLoadThread.cpp │ │ ├── GraphicsLoadThread.h │ │ ├── GraphicsLoaderIntf.cpp │ │ ├── GraphicsLoaderIntf.h │ │ ├── ImageFunction.cpp │ │ ├── ImageFunction.h │ │ ├── LayerBitmapIntf.cpp │ │ ├── LayerBitmapIntf.h │ │ ├── LayerIntf.cpp │ │ ├── LayerIntf.h │ │ ├── LayerManager.cpp │ │ ├── LayerManager.h │ │ ├── LayerTreeOwner.h │ │ ├── LayerTreeOwnerImpl.cpp │ │ ├── LayerTreeOwnerImpl.h │ │ ├── LoadBPG.cpp │ │ ├── LoadJPEG.cpp │ │ ├── LoadJXR.cpp │ │ ├── LoadPNG.cpp │ │ ├── LoadPVRv3.cpp │ │ ├── LoadTLG.cpp │ │ ├── LoadTLG.h │ │ ├── LoadWEBP.cpp │ │ ├── MenuItemIntf.cpp │ │ ├── MenuItemIntf.h │ │ ├── PrerenderedFont.cpp │ │ ├── PrerenderedFont.h │ │ ├── RectItf.cpp │ │ ├── RectItf.h │ │ ├── RenderManager.cpp │ │ ├── RenderManager.h │ │ ├── RenderManager_software.h │ │ ├── SaveTLG.h │ │ ├── SaveTLG5.cpp │ │ ├── SaveTLG6.cpp │ │ ├── TransIntf.cpp │ │ ├── TransIntf.h │ │ ├── VideoOvlIntf.cpp │ │ ├── VideoOvlIntf.h │ │ ├── WindowIntf.cpp │ │ ├── WindowIntf.h │ │ ├── argb.cpp │ │ ├── argb.h │ │ ├── drawable.h │ │ ├── gl/ │ │ │ ├── ResampleImage.cpp │ │ │ ├── ResampleImage.h │ │ │ ├── ResampleImageInternal.h │ │ │ ├── WeightFunctor.cpp │ │ │ ├── WeightFunctor.h │ │ │ ├── aligned_allocator.h │ │ │ ├── blend_function.cpp │ │ │ ├── blend_functor_c.h │ │ │ ├── blend_util_func.h │ │ │ ├── blend_variation.h │ │ │ └── tvpgl_mathutil.h │ │ ├── ogl/ │ │ │ ├── RenderManager_ogl.cpp │ │ │ ├── RenderManager_ogl_test.hpp │ │ │ ├── astcrt.cpp │ │ │ ├── astcrt.h │ │ │ ├── etcpak.cpp │ │ │ ├── etcpak.h │ │ │ ├── imagepacker.cpp │ │ │ ├── imagepacker.h │ │ │ ├── ogl_common.h │ │ │ ├── pvr.h │ │ │ ├── pvrtc.cpp │ │ │ └── pvrtc.h │ │ ├── transhandler.h │ │ ├── tvpfontstruc.h │ │ ├── tvpgl.cpp │ │ ├── tvpgl.h │ │ ├── tvpgl_asm_init.h │ │ ├── tvpgl_route.h │ │ ├── tvphal.h │ │ ├── tvpinputdefs.h │ │ ├── tvpps.inc │ │ ├── voMode.h │ │ └── win32/ │ │ ├── BasicDrawDevice.cpp │ │ ├── BasicDrawDevice.h │ │ ├── BitmapBitsAlloc.cpp │ │ ├── BitmapBitsAlloc.h │ │ ├── BitmapInfomation.cpp │ │ ├── BitmapInfomation.h │ │ ├── DInputMgn.cpp │ │ ├── DInputMgn.h │ │ ├── DrawDevice.cpp │ │ ├── DrawDevice.h │ │ ├── GDIFontRasterizer.cpp │ │ ├── GDIFontRasterizer.h │ │ ├── GraphicsLoaderImpl.cpp │ │ ├── GraphicsLoaderImpl.h │ │ ├── LayerBitmapImpl.cpp │ │ ├── LayerBitmapImpl.h │ │ ├── LayerImpl.cpp │ │ ├── LayerImpl.h │ │ ├── MenuItemImpl.cpp │ │ ├── MenuItemImpl.h │ │ ├── NativeFreeTypeFace.cpp │ │ ├── NativeFreeTypeFace.h │ │ ├── PassThroughDrawDevice.cpp │ │ ├── PassThroughDrawDevice.h │ │ ├── TVPColor.h │ │ ├── TVPScreen.cpp │ │ ├── TVPScreen.h │ │ ├── TVPSysFont.cpp │ │ ├── TVPSysFont.h │ │ ├── VSyncTimingThread.cpp │ │ ├── VSyncTimingThread.h │ │ ├── VideoOvlImpl.cpp │ │ ├── VideoOvlImpl.h │ │ ├── WindowImpl.cpp │ │ ├── WindowImpl.h │ │ └── krmovie.h │ └── plugins/ │ ├── Android.mk │ ├── CMakeLists.txt │ ├── InternalPlugins.cpp │ ├── LayerExBase.cpp │ ├── LayerExBase.h │ ├── PluginStub.h │ ├── addFont.cpp │ ├── csvParser.cpp │ ├── dirlist.cpp │ ├── fftgraph.cpp │ ├── getSample.cpp │ ├── getabout.cpp │ ├── layerExBase.hpp │ ├── layerExMovie.cpp │ ├── layerExPerspective.cpp │ ├── ncbind/ │ │ ├── ncb_foreach.h │ │ ├── ncb_invoke.hpp │ │ ├── ncbind.cpp │ │ └── ncbind.hpp │ ├── saveStruct.cpp │ ├── tp_stub.h │ ├── varfile.cpp │ ├── win32dialog.cpp │ ├── wutcwf.cpp │ ├── xp3filter.cpp │ └── xp3filter.h └── thirdparty/ └── patch/ ├── cocos2d-x/ │ ├── android_CCFileUtils-android.cpp │ ├── android_CCFileUtils-android.h │ ├── android_Java_org_cocos2dx_lib_Cocos2dxHelper.cpp │ ├── android_Java_org_cocos2dx_lib_Cocos2dxHelper.h │ └── android_cocos2dx.cmake ├── ffmpeg/ │ └── android_ffmpeg.diff ├── oniguruma/ │ └── oniguruma.cmake ├── opus/ │ └── opusfile.h ├── p7zip/ │ ├── 7z.h │ ├── 7zArcIn.c │ ├── 7zBuf.c │ ├── 7zDec.c │ ├── 7zFile.h │ └── android_p7zip.cmake ├── sdl2/ │ ├── android_SDL_android.c │ └── android_android_lf.h └── unrar/ └── android_ulinks.cpp ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/workflows/build_android.yml ================================================ name: build android on: push: {tags: ['v*']} # Push events to matching v*, i.e. v1.0, v20.15.10 permissions: contents: write env: BUILD_NAME: krk2yuri_android jobs: fetch_thirdparty_build: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - name: check thirdparty build id: check_thirdparty_build uses: actions/cache@v3 with: path: ./thirdparty/build key: thirdparty_build - name: fetch thirdparty build if: steps.check_thirdparty_build.outputs.cache-hit != 'true' run: | wget https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/deps/thirdparty_build.tar.gz tar xvzf thirdparty_build.tar.gz fetch_thirdparty_port: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - name: check thirdparty port id: check_thirdparty_port uses: actions/cache@v3 with: path: ./thirdparty/port key: thirdparty_port - name: fetch thirdparty port if: steps.check_thirdparty_port.outputs.cache-hit != 'true' run: | wget https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/deps/thirdparty_port.tar.gz tar xvzf thirdparty_port.tar.gz build_android: runs-on: ubuntu-20.04 needs: - fetch_thirdparty_build - fetch_thirdparty_port steps: - uses: actions/checkout@v3 - name: get thirdparty build cache uses: actions/cache@v3 with: key: thirdparty_build path: ./thirdparty/build - name: get thirdparty port cache uses: actions/cache@v3 with: key: thirdparty_port path: ./thirdparty/port - uses: actions/setup-java@v3 with: java-version: | 8 11 distribution: 'temurin' cache: gradle - name: build krkr2yuri android env: SIGN_KEY_ALIAS: ${{ secrets.SIGN_KEY_ALIAS }} SIGN_KEY_PASS: ${{ secrets.SIGN_KEY_PASS }} SIGN_STORE_PASS: ${{ secrets.SIGN_STORE_PASS }} run: | wget https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/1.3.9_yuri/Kirikiroid2_yuri_1.3.9.apk 7z x Kirikiroid2_yuri_1.3.9.apk assets sudo mkdir /build_android && sudo chmod 777 /build_android cd project/android chmod +x ./gradlew ./gradlew assembleDebug --no-daemon - name: create release uses: ncipollo/release-action@v1 with: artifacts: "./build_android/outputs/apk/debug/*.apk" allowUpdates: "true" prerelease: "true" token: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .gitignore ================================================ # general assets/** build/** build_*/** thirdparty/build/** thirdparty/port/** .vscode/settings.json # android local.properties sign.properties project/onsyuri_android/.gradle project/android/local.properties project/android/.idea/caches/** project/android/.idea/modules/** project/android/.idea/libraries/** project/android/.idea/modules.xml project/android/.idea/workspace.xml project/android/.idea/navEditor.xml project/android/.idea/assetWizardSettings.xml project/android/.idea/deploymentTargetDropDown.xml project/android/.idea/inspectionProfiles project/android/app/.cxx/** project/android/app/debug/** project/android/app/release/** ================================================ FILE: .vscode/c_cpp_properties.json ================================================ { "env": { // edit your env here "androidsdk": "D:/Software/env/sdk/androidsdk", "androidndk": "${androidsdk}/ndk/25.2.9519653" }, "configurations": [ { "name": "Android (win)", "includePath": [ "${workspaceFolder}/src/core/**", "${workspaceFolder}/src/core/sound/**", "${workspaceFolder}/thirdparty/build/arch_androida64/include/**", "${workspaceFolder}/thirdparty/build/arch_androida64/sdk/native/jni/include/**", "${workspaceFolder}/thirdparty/port/cocos2d-x/**", "${workspaceFolder}/thirdparty/port/cocos2d-x/external/**", "${workspaceFolder}/thirdparty/port/cocos2d-x/cocos/**", "${env:androidndk}/sources/android/cpufeatures" ], "defines": [ "__linux__" ], "compilerPath": "${androidndk}/toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe", "intelliSenseMode": "linux-clang-arm64", "compilerArgs": ["--target=aarch64-linux-android21"] } ], "version": 4 } ================================================ FILE: CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.6) project(krkr2yuri) set(CMAKE_CXX_STANDARD 11) set(KRKR2CORE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/core) set(KRKR2PLUGIN_PATH ${CMAKE_CURRENT_SOURCE_DIR}/src/plugins) set(COCOS2DX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/port/cocos2d-x) # build library add_subdirectory(${KRKR2CORE_PATH}) add_subdirectory(${KRKR2PLUGIN_PATH}) # build main if(CMAKE_SYSTEM_NAME MATCHES "Android") add_library(${PROJECT_NAME} SHARED project/android/app/cpp/krkr2_android.cpp ) elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") message("${CMAKE_SYSTEM_NAME} not support yet") elseif(CMAKE_SYSTEM_NAME MATCHES "Windows") message("${CMAKE_SYSTEM_NAME} not support yet") else() message("${CMAKE_SYSTEM_NAME} not support yet") endif() target_compile_options(${PROJECT_NAME} PUBLIC -fPIE ) target_include_directories(${PROJECT_NAME} PUBLIC src/cocos ${KRKR2CORE_PATH}/environ/cocos2d ${PORTBUILD_PATH}/include ${PORTBUILD_PATH}/include/breakpad ${COCOS2DX_PATH}/cocos ${COCOS2DX_PATH}/cocos/audio/include ) target_link_directories(${PROJECT_NAME} PUBLIC ${PORTBUILD_PATH}/lib ) target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,-Bstatic -Wl,--whole-archive # cpp_android_spec for jni function, this is important to add whole libraries ! cpp_android_spec krkr2plugin -Wl,--no-whole-archive krkr2core ) ================================================ FILE: LICENSE ================================================ Copyright (c), W.Dee and contributors All rights reserved. Contributors Go Watanabe, Kenjo, Kiyobee, Kouhei Yanagita, mey, MIK, Takenori Imoto, yun Kirikiri Z Project Contributors W.Dee, casper, 有限会社MCF, Biscrat, 青猫, nagai, ルー, 高際 雅之, 永劫, ゆんゆん探偵, りょうご(今は無きあの星), AZ-UME, 京 秋人, Katsumasa Tsuneyoshi, 小池潤, miahmie, サークル獏, アザナシ, はっしぃ, 棚中製作所, わっふる/waffle, ワムソフト, TYPE-MOON, 有限会社エムツー, Takenori Imoto Kirikiri Z 64bit Project Contributors 合資会社ワムソフト, Takenori Imoto, 他 ---------------------------------------------------------------------------- ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満 たす場合に限り、再頒布および使用が許可されます。 ・ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責 条項を含めること。 ・バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の 著作権表示、本条件一覧、および下記免責条項を含めること。 ・書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売 促進に、組織の名前またはコントリビューターの名前を使用してはならない。 本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供 されており、明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適 合性に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もありませ ん。著作権者もコントリビューターも、事由のいかんを問わず、損害発生の原因いか んを問わず、かつ責任の根拠が契約であるか厳格責任であるか(過失その他の)不法 行為であるかを問わず、仮にそのような損害が発生する可能性を知らされていたとし ても、本ソフトウェアの使用によって発生した(代替品または代用サービスの調達、 使用の喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定されな い)直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害に ついて、一切責任を負わないものとします。 ------------------------------------------------------------------------------ Thanks for many libraries to contributors and other supporters that were not listed here. This software is based in part on the work of Independent JPEG Group. ------------------------------------------------------------------------------ libjpeg-turbo Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: ? Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. ? Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. ? Neither the name of the libjpeg-turbo Project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ Using "A C-program for MT19937" Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------------ libpng LICENSE This copy of the libpng notices is provided for your convenience. In case of any discrepancy between this copy and the notices in the file png.h that is included in the libpng distribution, the latter shall prevail. COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: If you modify libpng you may insert additional notices immediately following this sentence. This code is released under the libpng license. libpng versions 1.2.6, August 15, 2004, through 1.6.1, March 28, 2013, are Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-1.2.5 with the following individual added to the list of Contributing Authors Cosmin Truta libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors Simon-Pierre Cadieux Eric S. Raymond Gilles Vollant and with the following additions to the disclaimer: There is no warranty against interference with your enjoyment of the library or against infringement. There is no warranty that our efforts or the library will fulfill any of your particular purposes or needs. This library is provided with all faults, and the entire risk of satisfactory quality, performance, accuracy, and effort is with the user. libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-0.96, with the following individuals added to the list of Contributing Authors: Tom Lane Glenn Randers-Pehrson Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are Copyright (c) 1996, 1997 Andreas Dilger Distributed according to the same disclaimer and license as libpng-0.88, with the following individuals added to the list of Contributing Authors: John Bowler Kevin Bracey Sam Bushell Magnus Holmgren Greg Roelofs Tom Tanner libpng versions 0.5, May 1995, through 0.88, January 1996, are Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: Andreas Dilger Dave Martindale Guy Eric Schalnat Paul Schmidt Tim Wegner The PNG Reference Library is supplied "AS IS". The Contributing Authors and Group 42, Inc. disclaim all warranties, expressed or implied, including, without limitation, the warranties of merchantability and of fitness for any purpose. The Contributing Authors and Group 42, Inc. assume no liability for direct, indirect, incidental, special, exemplary, or consequential damages, which may result from the use of the PNG Reference Library, even if advised of the possibility of such damage. Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: 1. The origin of this source code must not be misrepresented. 2. Altered versions must be plainly marked as such and must not be misrepresented as being the original source. 3. This Copyright notice may not be removed or altered from any source or altered source distribution. The Contributing Authors and Group 42, Inc. specifically permit, without fee, and encourage the use of this source code as a component to supporting the PNG file format in commercial products. If you use this source code in a product, acknowledgment is not required but would be appreciated. A "png_get_copyright" function is available, for convenient use in "about" boxes and the like: printf("%s",png_get_copyright(NULL)); Also, the PNG logo (in PNG format, of course) is supplied in the files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a certification mark of the Open Source Initiative. Glenn Randers-Pehrson glennrp at users.sourceforge.net March 28, 2013 ------------------------------------------------------------------------------ zlib LICENSE The deflate format used by zlib was defined by Phil Katz. The deflate and zlib specifications were written by L. Peter Deutsch. Thanks to all the people who reported problems and suggested various improvements in zlib; they are too numerous to cite here. Copyright notice: (C) 1995-2012 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu If you use the zlib library in a product, we would appreciate *not* receiving lengthy legal documents to sign. The sources are provided for free but without warranty of any kind. The library has been entirely written by Jean-loup Gailly and Mark Adler; it does not include third-party code. If you redistribute modified sources, we would appreciate that you include in the file ChangeLog history information documenting your changes. Please read the FAQ for more information on the distribution of modified source versions. ------------------------------------------------------------------------------ Oniguruma LICENSE ----------------- /*- * Copyright (c) 2002-2007 K.Kosako * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ ------------------------------------------------------------------------------ The FreeType Project LICENSE ---------------------------- 2006-Jan-27 Copyright 1996-2002, 2006 by David Turner, Robert Wilhelm, and Werner Lemberg Introduction ============ The FreeType Project is distributed in several archive packages; some of them may contain, in addition to the FreeType font engine, various tools and contributions which rely on, or relate to, the FreeType Project. This license applies to all files found in such packages, and which do not fall under their own explicit license. The license affects thus the FreeType font engine, the test programs, documentation and makefiles, at the very least. This license was inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses, which all encourage inclusion and use of free software in commercial and freeware products alike. As a consequence, its main points are that: o We don't promise that this software works. However, we will be interested in any kind of bug reports. (`as is' distribution) o You can use this software for whatever you want, in parts or full form, without having to pay us. (`royalty-free' usage) o You may not pretend that you wrote this software. If you use it, or only parts of it, in a program, you must acknowledge somewhere in your documentation that you have used the FreeType code. (`credits') We specifically permit and encourage the inclusion of this software, with or without modifications, in commercial products. We disclaim all warranties covering The FreeType Project and assume no liability related to The FreeType Project. Finally, many people asked us for a preferred form for a credit/disclaimer to use in compliance with this license. We thus encourage you to use the following text: """ Portions of this software are copyright ゥ The FreeType Project (www.freetype.org). All rights reserved. """ Please replace with the value from the FreeType version you actually use. Legal Terms =========== 0. Definitions -------------- Throughout this license, the terms `package', `FreeType Project', and `FreeType archive' refer to the set of files originally distributed by the authors (David Turner, Robert Wilhelm, and Werner Lemberg) as the `FreeType Project', be they named as alpha, beta or final release. `You' refers to the licensee, or person using the project, where `using' is a generic term including compiling the project's source code as well as linking it to form a `program' or `executable'. This program is referred to as `a program using the FreeType engine'. This license applies to all files distributed in the original FreeType Project, including all source code, binaries and documentation, unless otherwise stated in the file in its original, unmodified form as distributed in the original archive. If you are unsure whether or not a particular file is covered by this license, you must contact us to verify this. The FreeType Project is copyright (C) 1996-2000 by David Turner, Robert Wilhelm, and Werner Lemberg. All rights reserved except as specified below. 1. No Warranty -------------- THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO USE, OF THE FREETYPE PROJECT. 2. Redistribution ----------------- This license grants a worldwide, royalty-free, perpetual and irrevocable right and license to use, execute, perform, compile, display, copy, create derivative works of, distribute and sublicense the FreeType Project (in both source and object code forms) and derivative works thereof for any purpose; and to authorize others to exercise some or all of the rights granted herein, subject to the following conditions: o Redistribution of source code must retain this license file (`FTL.TXT') unaltered; any additions, deletions or changes to the original files must be clearly indicated in accompanying documentation. The copyright notices of the unaltered, original files must be preserved in all copies of source files. o Redistribution in binary form must provide a disclaimer that states that the software is based in part of the work of the FreeType Team, in the distribution documentation. We also encourage you to put an URL to the FreeType web page in your documentation, though this isn't mandatory. These conditions apply to any software derived from or based on the FreeType Project, not just the unmodified files. If you use our work, you must acknowledge us. However, no fee need be paid to us. 3. Advertising -------------- Neither the FreeType authors and contributors nor you shall use the name of the other for commercial, advertising, or promotional purposes without specific prior written permission. We suggest, but do not require, that you use one or more of the following phrases to refer to this software in your documentation or advertising materials: `FreeType Project', `FreeType Engine', `FreeType library', or `FreeType Distribution'. As you have not signed this license, you are not required to accept it. However, as the FreeType Project is copyrighted material, only this license, or another one contracted with the authors, grants you the right to use, distribute, and modify it. Therefore, by using, distributing, or modifying the FreeType Project, you indicate that you understand and accept all the terms of this license. 4. Contacts ----------- There are two mailing lists related to FreeType: o freetype@nongnu.org Discusses general use and applications of FreeType, as well as future and wanted additions to the library and distribution. If you are looking for support, start in this list if you haven't found anything to help you in the documentation. o freetype-devel@nongnu.org Discusses bugs, as well as engine internals, design issues, specific licenses, porting, etc. Our home page can be found at http://www.freetype.org ------------------------------------------------------------------------------ picojson LICENSE /* Copyright 2009 Cybozu Labs, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY CYBOZU LABS, INC. ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL CYBOZU LABS, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of Cybozu Labs, Inc. * */ ------------------------------------------------------------------------------ Copyright (c) 2012, The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ------------------------------------------------------------------------------ Microsoft Corporation Technical Documentation License Agreement for the specification “JPEG XR Device Porting Kit” Copyright (c) 2013 Microsoft Corp. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BELIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESSINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF SUCH DAMAGE.. ------------------------------------------------------------------------------ ------------------------------------------------------------------------ *** vorbis *** ogg Copyright (c) 1994-2004 Xiph.org Foundation Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------ *** theora Copyright (C) 2002-2008 Xiph.org Foundation and contributors. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------ *** libfishsound *** dsfSeeking Copyright (C) 2003, 2004 Commonwealth Scientific and Industrial Research Organisation (CSIRO) Australia Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of the CSIRO Australia nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------ *** libCMMLParse *** libCMMLTags *** libCMMLTagsDotNET *** libOOOggChef *** libTemporalURI *** libWinCMMLParse *** dsfCMMLDecoder *** dsfAnxDemux *** AnxCutter *** CMMLDump *** mod_oggchef Copyright (C) 2003-2005 Zentaro Kavanagh Copyright (C) 2003-2005 Commonwealth Scientific and Industrial Research Organisation (CSIRO) Australia Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of CSIRO Australia nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------ *** dsfOggDemux *** dsfOggMux *** dsfSpeexDecoder *** dsfSpeexEncoder *** dsfVorbisDecoder *** dsfVorbisEncoder *** dsfFLACDecoder *** dsfFLACEncoder *** dsfTheoraDecoder *** dsfTheoraEncoder *** dsfAbstractAudioDecoder *** dsfAbstractAudioEncoder *** dsfAbstractVideoDecoder *** dsfAbstractVideoEncoder *** dsfSubtitleVMR9 *** libiWrapper *** libilliCore *** libOOTheora *** libOOOgg *** libOOOggSeek *** libVorbisComment *** libVorbisCommentDotNET *** OOOggDump *** OOOggStat *** OOOggCommentDump *** CLOgg *** DNPlay *** iOCE Copyright (C) 2008-2010 Cristian Adam Copyright (C) 2003-2005 Zentaro Kavanagh Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of Zentaro Kavanagh nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ------------------------------------------------------------------------ ================================================ FILE: project/android/.gitignore ================================================ .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures /.externalNativeBuild ================================================ FILE: project/android/.idea/.gitignore ================================================ # Default ignored files /shelf/ /workspace.xml ================================================ FILE: project/android/.idea/codeStyles/Project.xml ================================================
xmlns:android ^$
xmlns:.* ^$ BY_NAME
.*:id http://schemas.android.com/apk/res/android
.*:name http://schemas.android.com/apk/res/android
name ^$
style ^$
.* ^$ BY_NAME
.* http://schemas.android.com/apk/res/android ANDROID_ATTRIBUTE_ORDER
.* .* BY_NAME
================================================ FILE: project/android/.idea/compiler.xml ================================================ ================================================ FILE: project/android/.idea/gradle.xml ================================================ ================================================ FILE: project/android/.idea/jarRepositories.xml ================================================ ================================================ FILE: project/android/.idea/misc.xml ================================================ ================================================ FILE: project/android/.idea/vcs.xml ================================================ ================================================ FILE: project/android/app/.gitignore ================================================ /.externalNativeBuild /.cxx /build /release ================================================ FILE: project/android/app/AndroidManifest.xml ================================================ ================================================ FILE: project/android/app/build.gradle ================================================ plugins { id 'com.android.application' } android { // compileSdkVersion PROP_TARGET_SDK_VERSION ndkVersion '25.2.9519653' buildToolsVersion '33.0.2' compileSdkVersion PROP_TARGET_SDK_VERSION.toInteger() compileOptions { // sourceCompatibility JavaVersion.VERSION_11 // targetCompatibility JavaVersion.VERSION_11 } defaultConfig { applicationId "com.yuri.kirikiri2" targetSdkVersion PROP_TARGET_SDK_VERSION minSdkVersion PROP_MIN_SDK_VERSION ndk { abiFilters = [] abiFilters.addAll(PROP_APP_ABI.split(':').collect{it as String}) } externalNativeBuild { if (PROP_BUILD_TYPE == 'cmake') { cmake { version '3.22.1' targets 'krkr2yuri' arguments "-DCMAKE_FIND_ROOT_PATH=", "-DANDROID_STL=c++_static", "-DANDROID_TOOLCHAIN=clang", "-DANDROID_ARM_NEON=TRUE" cppFlags "-frtti -fexceptions -fsigned-char" } } } versionCode 1 versionName "1.4.0beta" } signingConfigs { release { storeFile file('sign.jks') def signPropsFile = file('sign.properties') if (signPropsFile.exists()) { Properties signProps = new Properties() signProps.load(new FileInputStream(signPropsFile)) keyAlias signProps['SIGN_KEY_ALIAS'] keyPassword signProps['SIGN_KEY_PASS'] storePassword signProps['SIGN_STORE_PASS'] } else { keyAlias System.getenv("SIGN_KEY_ALIAS") keyPassword System.getenv("SIGN_KEY_PASS") storePassword System.getenv("SIGN_STORE_PASS") } } } buildTypes { release { debuggable false renderscriptDebuggable false minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.release } debug { debuggable true jniDebuggable true jniDebuggable true renderscriptDebuggable true signingConfig signingConfigs.release } } sourceSets{ main{ manifest.srcFile "AndroidManifest.xml" java.srcDirs = ["java"] res.srcDirs = ["res"] assets.srcDirs =["../../../assets"] } } externalNativeBuild { cmake { version '3.22.1' path "cpp/CMakeLists.txt" } } android.applicationVariants.all { variant -> variant.outputs.all { outputFileName = "krkr2yuri_v${defaultConfig.versionName}.apk" } } } dependencies { //implementation fileTree(dir: 'libs', include: ['*.jar']) implementation project(':cocos2dx') implementation "androidx.documentfile:documentfile:1.0.1" //noinspection GradleDependency implementation "androidx.activity:activity:1.2.3" //noinspection GradleDependency implementation "androidx.fragment:fragment:1.3.4" } ================================================ FILE: project/android/app/cpp/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.7) project(krkr2yuri_android) set(KRKR2YURI_DIR ${CMAKE_SOURCE_DIR}/../../../..) if(${ANDROID_ABI} MATCHES "arm64-v8a") set(PORTBUILD_PATH ${KRKR2YURI_DIR}/thirdparty/build/arch_androida64) else() set(PORTBUILD_PATH ${KRKR2YURI_DIR}/thirdparty/build/arch_androida64) endif() if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -g") endif() add_subdirectory(${KRKR2YURI_DIR} ${KRKR2YURI_DIR}/build_android) ================================================ FILE: project/android/app/cpp/krkr2_android.cpp ================================================ /* Include the SDL main definition header */ #include #include "platform/android/jni/JniHelper.h" #include "cocos2d/AppDelegate.h" #include "cocos2d/MainScene.h" #include "ConfigManager/GlobalConfigManager.h" #include "Application.h" /******************************************************************************* Functions called by JNI *******************************************************************************/ #include #include #include #include #include "breakpad/client/linux/handler/exception_handler.h" #include "breakpad/client/linux/handler/minidump_descriptor.h" //std::string Android_GetDumpStoragePath(); static bool __DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, void* context, bool succeeded) { return succeeded; } extern bool TVPSystemUninitCalled; static bool __DumpFilter(void *data) { if(TVPSystemUninitCalled) return false; // if trying exit system, ignore all exception return true; } //static void __InitAndroidDump() { // static google_breakpad::MinidumpDescriptor descriptor(Android_GetDumpStoragePath()); // static google_breakpad::ExceptionHandler eh(descriptor, __DumpFilter, __DumpCallback, // NULL, true, -1); //} void cocos_android_app_init (JNIEnv* env) { // for cocos3.10+ // __InitAndroidDump(); __android_log_print(ANDROID_LOG_INFO,"## krkr2yuri","in cocos_android_app_init"); static TVPAppDelegate *pAppDelegate = new TVPAppDelegate(); } namespace kr2android { extern std::condition_variable MessageBoxCond; extern std::mutex MessageBoxLock; extern int MsgBoxRet; extern std::string MessageBoxRetText; } void Android_PushEvents(const std::function &func); using namespace kr2android; extern "C" { JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_initDump(JNIEnv* env, jclass cls, jstring path) { const char* pszPath = env->GetStringUTFChars(path, NULL); if (pszPath && *pszPath) { static google_breakpad::MinidumpDescriptor descriptor(pszPath); static google_breakpad::ExceptionHandler eh(descriptor, __DumpFilter, __DumpCallback, NULL, true, -1); } env->ReleaseStringUTFChars(path, pszPath); } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_onMessageBoxOK(JNIEnv* env, jclass cls, jint nButton) { MsgBoxRet = nButton; MessageBoxCond.notify_one(); } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_onMessageBoxText(JNIEnv* env, jclass cls, jstring text) { const char* pszText = env->GetStringUTFChars(text, NULL); if (pszText && *pszText) { MessageBoxRetText = pszText; } env->ReleaseStringUTFChars(text, pszText); } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesBegin(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) { intptr_t idlong = id; Android_PushEvents([idlong, x, y](){ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, (intptr_t*)&idlong, (float*)&x, (float*)&y); }); } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesEnd(JNIEnv * env, jobject thiz, jint id, jfloat x, jfloat y) { intptr_t idlong = id; Android_PushEvents([idlong, x, y](){ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, (intptr_t*)&idlong, (float*)&x, (float*)&y); }); } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesMove(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) { int size = env->GetArrayLength(ids); if (size == 1) { intptr_t idlong; jint id; jfloat x; jfloat y; env->GetIntArrayRegion(ids, 0, size, &id); env->GetFloatArrayRegion(xs, 0, size, &x); env->GetFloatArrayRegion(ys, 0, size, &y); idlong = id; Android_PushEvents([idlong, x, y](){ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(1, (intptr_t*)&idlong, (float*)&x, (float*)&y); }); return; } jint id[size]; std::vector x; x.resize(size); std::vector y; y.resize(size); env->GetIntArrayRegion(ids, 0, size, id); env->GetFloatArrayRegion(xs, 0, size, &x[0]); env->GetFloatArrayRegion(ys, 0, size, &y[0]); std::vector idlong; idlong.resize(size); for (int i = 0; i < size; i++) idlong[i] = id[i]; Android_PushEvents([idlong, x, y](){ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(idlong.size(), (intptr_t*)&idlong[0], (float*)&x[0], (float*)&y[0]); }); } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeTouchesCancel(JNIEnv * env, jobject thiz, jintArray ids, jfloatArray xs, jfloatArray ys) { int size = env->GetArrayLength(ids); if (size == 1) { intptr_t idlong; jint id; jfloat x; jfloat y; env->GetIntArrayRegion(ids, 0, size, &id); env->GetFloatArrayRegion(xs, 0, size, &x); env->GetFloatArrayRegion(ys, 0, size, &y); idlong = id; Android_PushEvents([idlong, x, y](){ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(1, (intptr_t*)&idlong, (float*)&x, (float*)&y); }); return; } jint id[size]; std::vector x; x.resize(size); std::vector y; y.resize(size); env->GetIntArrayRegion(ids, 0, size, id); env->GetFloatArrayRegion(xs, 0, size, &x[0]); env->GetFloatArrayRegion(ys, 0, size, &y[0]); std::vector idlong; idlong.resize(size); for (int i = 0; i < size; i++) idlong[i] = id[i]; Android_PushEvents([idlong, x, y](){ cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(idlong.size(), (intptr_t*)&idlong[0], (float*)&x[0], (float*)&y[0]); }); } #define KEYCODE_BACK 0x04 #define KEYCODE_MENU 0x52 #define KEYCODE_DPAD_UP 0x13 #define KEYCODE_DPAD_DOWN 0x14 #define KEYCODE_DPAD_LEFT 0x15 #define KEYCODE_DPAD_RIGHT 0x16 #define KEYCODE_ENTER 0x42 #define KEYCODE_PLAY 0x7e #define KEYCODE_DPAD_CENTER 0x17 #define KEYCODE_DEL 0x43 JNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeKeyAction(JNIEnv * env, jclass cls, jint keyCode, jboolean isPress) { cocos2d::EventKeyboard::KeyCode pKeyCode; switch (keyCode) { case KEYCODE_BACK : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_ESCAPE ; break; case KEYCODE_MENU : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_MENU ; break; case KEYCODE_DPAD_UP : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_UP ; break; case KEYCODE_DPAD_DOWN : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_DOWN ; break; case KEYCODE_DPAD_LEFT : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_LEFT ; break; case KEYCODE_DPAD_RIGHT : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_RIGHT; break; case KEYCODE_ENTER : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_ENTER ; break; case KEYCODE_PLAY : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_PLAY ; break; case KEYCODE_DPAD_CENTER: pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_DPAD_CENTER; break; case KEYCODE_DEL : pKeyCode = cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE; break; default: return JNI_FALSE; } Android_PushEvents([pKeyCode, isPress](){ cocos2d::EventKeyboard event(pKeyCode, isPress); cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event); }); return JNI_TRUE; } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeInsertText(JNIEnv* env, jclass cls, jstring text) { const char* pszText = env->GetStringUTFChars(text, NULL); if (pszText && *pszText) { std::string str = pszText; Android_PushEvents([str](){ cocos2d::IMEDispatcher::sharedDispatcher()->dispatchInsertText(str.c_str(), str.length()); }); } env->ReleaseStringUTFChars(text, pszText); } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeDeleteBackward(JNIEnv* env, jclass cls) { Android_PushEvents(std::bind(&cocos2d::IMEDispatcher::dispatchDeleteBackward, cocos2d::IMEDispatcher::sharedDispatcher())); } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeCharInput(JNIEnv* env, jclass cls, jint keyCode) { TVPMainScene *pScene = TVPMainScene::GetInstance(); if (!pScene) return; pScene->getScheduler()->performFunctionInCocosThread(std::bind(&TVPMainScene::onCharInput, keyCode)); } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeCommitText( JNIEnv* env, jclass cls, jstring text, jint newCursorPosition) { TVPMainScene *pScene = TVPMainScene::GetInstance(); if (!pScene) return; const char *utftext = env->GetStringUTFChars(text, NULL); std::string str(utftext); pScene->getScheduler()->performFunctionInCocosThread(std::bind(&TVPMainScene::onTextInput, str)); env->ReleaseStringUTFChars(text, utftext); } JNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeGetHideSystemButton(JNIEnv* env, jclass cls) { return GlobalConfigManager::GetInstance()->GetValue("hide_android_sys_btn", false); } static float _mouseX, _mouseY; JNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeHoverMoved(JNIEnv* env, jclass cls, jfloat x, jfloat y) { Android_PushEvents([x, y]() { cocos2d::GLView *glview = cocos2d::Director::getInstance()->getOpenGLView(); float _scaleX = glview->getScaleX(), _scaleY = glview->getScaleY(); _mouseX = x; _mouseY = y; const cocos2d::Rect _viewPortRect = glview->getViewPortRect(); float cursorX = (_mouseX - _viewPortRect.origin.x) / _scaleX; float cursorY = (_viewPortRect.origin.y + _viewPortRect.size.height - _mouseY) / _scaleY; cocos2d::EventMouse event(cocos2d::EventMouse::MouseEventType::MOUSE_MOVE); event.setCursorPosition(cursorX, cursorY); cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event); }); return true; } JNIEXPORT jboolean JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeMouseScrolled(JNIEnv* env, jclass cls, jfloat v) { Android_PushEvents([v]() { cocos2d::GLView *glview = cocos2d::Director::getInstance()->getOpenGLView(); float _scaleX = glview->getScaleX(), _scaleY = glview->getScaleY(); const cocos2d::Rect _viewPortRect = glview->getViewPortRect(); float cursorX = (_mouseX - _viewPortRect.origin.x) / _scaleX; float cursorY = (_viewPortRect.origin.y + _viewPortRect.size.height - _mouseY) / _scaleY; cocos2d::EventMouse event(cocos2d::EventMouse::MouseEventType::MOUSE_SCROLL); event.setScrollData(0, v); event.setCursorPosition(cursorX, cursorY); cocos2d::Director::getInstance()->getEventDispatcher()->dispatchEvent(&event); }); return true; } JNIEXPORT void JNICALL Java_org_tvp_kirikiri2_KR2Activity_nativeOnLowMemory(JNIEnv* env, jclass cls) { Android_PushEvents([]() { ::Application->OnLowMemory(); }); } } ================================================ FILE: project/android/app/java/com/yuri/kirikiri2/MainActivity.java ================================================ package com.yuri.kirikiri2; import org.tvp.kirikiri2.KR2Activity; public class MainActivity extends KR2Activity { static { // System.loadLibrary("krkr2yuri"); } @Override public int get_res_sd_operate_step() { return R.drawable.sd_operate_step; } } ================================================ FILE: project/android/app/java/org/tvp/kirikiri2/KR2Activity.java ================================================ package org.tvp.kirikiri2; import android.Manifest; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; import android.app.ActivityManager; import android.app.AlertDialog; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Debug; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.os.storage.StorageManager; import android.preference.PreferenceManager; import android.provider.BaseColumns; import android.provider.MediaStore; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.inputmethod.BaseInputConnection; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.documentfile.provider.DocumentFile; import org.cocos2dx.lib.Cocos2dxActivity; import org.cocos2dx.lib.Cocos2dxGLSurfaceView; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Locale; /** * Utility class for handling the media store. */ @SuppressWarnings("ALL") abstract class MediaStoreUtil { public static Uri getUriFromFile(final String path,Context context) { ContentResolver resolver = context.getContentResolver(); Cursor filecursor = resolver.query(MediaStore.Files.getContentUri("external"), new String[] { BaseColumns._ID }, MediaStore.MediaColumns.DATA + " = ?", new String[] { path }, MediaStore.MediaColumns.DATE_ADDED + " desc"); filecursor.moveToFirst(); if (filecursor.isAfterLast()) { filecursor.close(); ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, path); return resolver.insert(MediaStore.Files.getContentUri("external"), values); } else { int imageId = filecursor.getInt(filecursor.getColumnIndex(BaseColumns._ID)); Uri uri = MediaStore.Files.getContentUri("external").buildUpon().appendPath( Integer.toString(imageId)).build(); filecursor.close(); return uri; } } public static void addFileToMediaStore(final String path, Context context) { Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); File file = new File(path); Uri contentUri = Uri.fromFile(file); mediaScanIntent.setData(contentUri); context.sendBroadcast(mediaScanIntent); } } /* This is a fake invisible editor view that receives the input and defines the * pan&scan region */ class DummyEdit extends View implements View.OnKeyListener { InputConnection ic; public DummyEdit(Context context) { super(context); setFocusableInTouchMode(true); setFocusable(true); setOnKeyListener(this); } @Override public boolean onCheckIsTextEditor() { return true; } @Override public boolean onKey(View v, int keyCode, KeyEvent event) { // This handles the hardware keyboard input if (event.isPrintingKey()) { if (event.getAction() == KeyEvent.ACTION_DOWN) { ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1); } return true; } return false; } // @Override public boolean onKeyPreIme (int keyCode, KeyEvent event) { // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639 // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not // FIXME: A more effective solution would be to change our Layout from AbsoluteLayout to Relative or Linear // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :) if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) { if (KR2Activity.mTextEdit != null && KR2Activity.mTextEdit.getVisibility() == View.VISIBLE) { KR2Activity.hideTextInput(); //KR2Activity.nativeKeyboardFocusLost(); } } return super.onKeyPreIme(keyCode, event); } @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { ic = new SDLInputConnection(this, true); outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI | 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */; return ic; } } class SDLInputConnection extends BaseInputConnection { public SDLInputConnection(View targetView, boolean fullEditor) { super(targetView, fullEditor); } @Override public boolean sendKeyEvent(KeyEvent event) { /* * This handles the keycodes from soft keyboard (and IME-translated * input from hardkeyboard) */ int keyCode = event.getKeyCode(); if (event.getAction() == KeyEvent.ACTION_DOWN) { if (event.isPrintingKey()) { commitText(String.valueOf((char) event.getUnicodeChar()), 1); KR2Activity.nativeCharInput(keyCode); } else if(keyCode == KeyEvent.KEYCODE_DEL) { KR2Activity.nativeKeyAction(keyCode, true); } return true; } else if (event.getAction() == KeyEvent.ACTION_UP) { if(keyCode == KeyEvent.KEYCODE_DEL) { KR2Activity.nativeKeyAction(keyCode, false); } //KR2Activity.nativeKeyAction(keyCode, false); return true; } return super.sendKeyEvent(event); } @Override public boolean commitText(CharSequence text, int newCursorPosition) { KR2Activity.nativeCommitText(text.toString(), newCursorPosition); return super.commitText(text, newCursorPosition); } @Override public boolean setComposingText(CharSequence text, int newCursorPosition) { //nativeSetComposingText(text.toString(), newCursorPosition); return super.setComposingText(text, newCursorPosition); } //public native void nativeSetComposingText(String text, int newCursorPosition); @Override public boolean deleteSurroundingText(int beforeLength, int afterLength) { // Workaround to capture backspace key. Ref: http://stackoverflow.com/questions/14560344/android-backspace-in-webview-baseinputconnection if (beforeLength == 1 && afterLength == 0) { // backspace return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL)) && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL)); } return super.deleteSurroundingText(beforeLength, afterLength); } } @SuppressWarnings("ALL") public class KR2Activity extends Cocos2dxActivity implements ActivityCompat.OnRequestPermissionsResultCallback { public static final int RC_WRITE_EXTERNAL = 1; public static final int RC_PHONE_STATE = 2; static ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); static ActivityManager mAcitivityManager = null; static Debug.MemoryInfo mDbgMemoryInfo = new Debug.MemoryInfo(); public static void updateMemoryInfo() { if(mAcitivityManager == null) { mAcitivityManager =(ActivityManager)sInstance.getSystemService(Activity.ACTIVITY_SERVICE); } mAcitivityManager.getMemoryInfo(memoryInfo); Debug.getMemoryInfo(mDbgMemoryInfo); } public static long getAvailMemory() { return memoryInfo.availMem; } public static long getUsedMemory() { return mDbgMemoryInfo.getTotalPss(); // in kB } private static void requestPhoneState() { // Permission has not been granted and must be requested. if (ActivityCompat.shouldShowRequestPermissionRationale(sInstance, Manifest.permission.READ_PHONE_STATE)) { // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. // Display a SnackBar with cda button to request the missing permission. ActivityCompat.requestPermissions(sInstance, new String[]{Manifest.permission.READ_PHONE_STATE}, RC_PHONE_STATE); } else { // Request the permission. The result will be received in onRequestPermissionResult(). ActivityCompat.requestPermissions(sInstance, new String[]{Manifest.permission.READ_PHONE_STATE}, RC_PHONE_STATE); } } private static void requestExternalWrite() { // Permission has not been granted and must be requested. if (ActivityCompat.shouldShowRequestPermissionRationale(sInstance, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { // Provide an additional rationale to the user if the permission was not granted // and the user would benefit from additional context for the use of the permission. // Display a SnackBar with cda button to request the missing permission. ActivityCompat.requestPermissions(sInstance, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_WRITE_EXTERNAL); } else { // Request the permission. The result will be received in onRequestPermissionResult(). ActivityCompat.requestPermissions(sInstance, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_WRITE_EXTERNAL); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case RC_PHONE_STATE: Log.d("Krkr2", "onRequestPermissionsResult: PHONE STATE"); break; case RC_WRITE_EXTERNAL: Log.d("Krkr2", "onRequestPermissionsResult: WRITE EXTERNAL"); break; } } static public String getDeviceId() { // ## fix android.permission.READ_PRIVILEGED_PHONE_STATE return ""; } static public KR2Activity sInstance; static public KR2Activity GetInstance() {return sInstance;} @Override public void onCreate(Bundle savedInstanceState) { sInstance = this; Sp = PreferenceManager.getDefaultSharedPreferences(this); super.onCreate(savedInstanceState); if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) { for(String path : getExtSdCardPaths(this)) { if (!isWritableNormalOrSaf(path)) { guideDialogForLEXA(path); } } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestExternalWrite(); } initDump(this.getFilesDir().getAbsolutePath() + "/dump"); } @Override public void onDestroy() { super.onDestroy(); System.exit(0); } @Override public void onLowMemory() { nativeOnLowMemory(); } static class DialogMessage { public String Title; public String Text; public String[] Buttons; public EditText TextEditor = null; public DialogMessage() { } public void Init(final String title, final String text, final String[] buttons) { this.Title = title; this.Text = text; this.Buttons = buttons; } void onButtonClick(int n) { if(TextEditor != null) { onMessageBoxText(TextEditor.getText().toString()); } onMessageBoxOK(n); } public AlertDialog.Builder CreateBuilder() { /* TextView showText = new TextView(sInstance); showText.setText(Text); if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) showText.setTextIsSelectable(true);*/ AlertDialog.Builder builder = new AlertDialog.Builder(sInstance). setTitle(Title). setMessage(Text). //setView(showText). setCancelable(false); if(Buttons.length >= 1) { builder = builder.setPositiveButton(Buttons[0], new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { onButtonClick(0); } }); } if(Buttons.length >= 2) { builder = builder.setNeutralButton(Buttons[1], new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { onButtonClick(1); } }); } if(Buttons.length >= 3) { builder = builder.setNegativeButton(Buttons[2], new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { onButtonClick(2); } }); } return builder; } public void ShowMessageBox() { CreateBuilder().create().show(); } public void ShowInputBox(final String text) { AlertDialog.Builder builder = CreateBuilder(); TextEditor = new EditText(sInstance); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT); TextEditor.setLayoutParams(lp); TextEditor.setText(text); builder.setView(TextEditor); AlertDialog ad = builder.create(); ad.show(); TextEditor.requestFocus(); InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(TextEditor, 0); } } static DialogMessage mDialogMessage = new DialogMessage(); protected static View mTextEdit = null; SharedPreferences Sp; static Handler msgHandler = new Handler() { @Override public void handleMessage(Message msg) { sInstance.handleMessage(msg); } }; public void handleMessage(Message msg) { } static public void ShowMessageBox(final String title, final String text, final String[] Buttons) { mDialogMessage.Init(title, text, Buttons); msgHandler.post(new Runnable() { @Override public void run() { mDialogMessage.ShowMessageBox(); } }); } static public void ShowInputBox(final String title, final String prompt, final String text, final String[] Buttons) { mDialogMessage.Init(title, prompt, Buttons); msgHandler.post(new Runnable() { @Override public void run() { mDialogMessage.ShowInputBox(text); } }); } static class ShowTextInputTask implements Runnable { /* * This is used to regulate the pan&scan method to have some offset from * the bottom edge of the input region and the top edge of an input * method (soft keyboard) */ static final int HEIGHT_PADDING = 15; public int x, y, w, h; public ShowTextInputTask(int x, int y, int w, int h) { this.x = x; this.y = y; this.w = w; this.h = h; } @Override public void run() { FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(w, h + HEIGHT_PADDING); params.leftMargin = x; params.topMargin = y; if (mTextEdit == null) { mTextEdit = new DummyEdit(getContext()); sInstance.mFrameLayout.addView(mTextEdit, params); } else { mTextEdit.setLayoutParams(params); } mTextEdit.setVisibility(View.VISIBLE); mTextEdit.requestFocus(); InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(mTextEdit, 0); } } static public void showTextInput(int x, int y, int w, int h) { msgHandler.post(new ShowTextInputTask(x, y, w, h)); } static public void hideTextInput() { msgHandler.post(new Runnable() { @Override public void run() { if (mTextEdit != null) { mTextEdit.setVisibility(View.GONE); InputMethodManager imm = (InputMethodManager) sInstance.getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0); } } }); } static private native void onMessageBoxOK(int nButton); static private native void onMessageBoxText(String text); static private native void onNativeExit(); static public native void onNativeInit(); static public native void onBannerSizeChanged(int w, int h); static private native void initDump(String path); static private native void nativeOnLowMemory(); static public void MessageController(int what, int arg1, int arg2) { Message msg = msgHandler.obtainMessage(); msg.what = what; msg.arg1 = arg1; msg.arg2 = arg2; msgHandler.sendMessage(msg); } static public String GetVersion() { String verstr = null; try { verstr = sInstance.getPackageManager().getPackageInfo(sInstance.getPackageName(), 0).versionName; } catch (NameNotFoundException e1) { } return verstr; } StorageManager mStorageManager = null; Method mMethodGetPaths = null; Method mGetVolumeState = null; public String[] getStoragePath() { String[] ret = new String[0]; if(mStorageManager == null) { mStorageManager = (StorageManager)getSystemService(STORAGE_SERVICE); try { mMethodGetPaths = StorageManager.class.getMethod("getVolumePaths"); mGetVolumeState = StorageManager.class.getMethod("getVolumeState", String.class); } catch (NoSuchMethodException e) { e.printStackTrace(); } } if(mMethodGetPaths != null) { try { ret = (String[])mMethodGetPaths.invoke(mStorageManager); } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } catch (Exception e) { } } if(mGetVolumeState != null) { try { for(int i = 0; i < ret.length; ++i) { String status = (String)mGetVolumeState.invoke(mStorageManager, ret[i]); if(Environment.MEDIA_MOUNTED.equals(status) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(status)) { ; } else { ret[i] = null; } } } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } catch (Exception e) { } } return ret; } private static native void nativeTouchesBegin(final int id, final float x, final float y); private static native void nativeTouchesEnd(final int id, final float x, final float y); private static native void nativeTouchesMove(final int[] ids, final float[] xs, final float[] ys); private static native void nativeTouchesCancel(final int[] ids, final float[] xs, final float[] ys); public static native boolean nativeKeyAction(final int keyCode, final boolean isPress); public static native void nativeCharInput(final int keyCode); public static native void nativeCommitText(String text, int newCursorPosition); private static native void nativeInsertText(final String text); public static native void nativeDeleteBackward(); private static native String nativeGetContentText(); private static native void nativeHoverMoved(final float x, final float y); private static native void nativeMouseScrolled(final float scroll); class KR2GLSurfaceView extends Cocos2dxGLSurfaceView { public KR2GLSurfaceView(final Context context) { super(context); } public KR2GLSurfaceView(final Context context, final AttributeSet attrs) { super(context, attrs); } @Override public void insertText(final String pText) { nativeInsertText(pText); } @Override public void deleteBackward() { nativeDeleteBackward(); } @Override public boolean onKeyDown(final int pKeyCode, final KeyEvent pKeyEvent) { switch (pKeyCode) { case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_MENU: case KeyEvent.KEYCODE_DPAD_LEFT: case KeyEvent.KEYCODE_DPAD_RIGHT: case KeyEvent.KEYCODE_DPAD_UP: case KeyEvent.KEYCODE_DPAD_DOWN: case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: case KeyEvent.KEYCODE_DPAD_CENTER: nativeKeyAction(pKeyCode, true); return true; default: return super.onKeyDown(pKeyCode, pKeyEvent); } } @Override public boolean onKeyUp(final int pKeyCode, final KeyEvent pKeyEvent) { switch (pKeyCode) { case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_MENU: case KeyEvent.KEYCODE_DPAD_LEFT: case KeyEvent.KEYCODE_DPAD_RIGHT: case KeyEvent.KEYCODE_DPAD_UP: case KeyEvent.KEYCODE_DPAD_DOWN: case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: case KeyEvent.KEYCODE_DPAD_CENTER: nativeKeyAction(pKeyCode, false); return true; default: return super.onKeyUp(pKeyCode, pKeyEvent); } } @Override public boolean onHoverEvent(final MotionEvent pMotionEvent) { final int pointerNumber = pMotionEvent.getPointerCount(); final float[] xs = new float[pointerNumber]; final float[] ys = new float[pointerNumber]; for (int i = 0; i < pointerNumber; i++) { xs[i] = pMotionEvent.getX(i); ys[i] = pMotionEvent.getY(i); } switch(pMotionEvent.getActionMasked()) { case MotionEvent.ACTION_HOVER_MOVE: nativeHoverMoved(xs[0], ys[0]); break; } return true; } @Override public boolean onTouchEvent(final MotionEvent pMotionEvent) { // these data are used in ACTION_MOVE and ACTION_CANCEL final int pointerNumber = pMotionEvent.getPointerCount(); final int[] ids = new int[pointerNumber]; final float[] xs = new float[pointerNumber]; final float[] ys = new float[pointerNumber]; for (int i = 0; i < pointerNumber; i++) { ids[i] = pMotionEvent.getPointerId(i); xs[i] = pMotionEvent.getX(i); ys[i] = pMotionEvent.getY(i); } switch (pMotionEvent.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_POINTER_DOWN: final int indexPointerDown = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int idPointerDown = pMotionEvent.getPointerId(indexPointerDown); final float xPointerDown = pMotionEvent.getX(indexPointerDown); final float yPointerDown = pMotionEvent.getY(indexPointerDown); nativeTouchesBegin(idPointerDown, xPointerDown, yPointerDown); break; case MotionEvent.ACTION_DOWN: // there are only one finger on the screen final int idDown = pMotionEvent.getPointerId(0); final float xDown = xs[0]; final float yDown = ys[0]; nativeTouchesBegin(idDown, xDown, yDown); break; case MotionEvent.ACTION_MOVE: nativeTouchesMove(ids, xs, ys); break; case MotionEvent.ACTION_POINTER_UP: final int indexPointUp = pMotionEvent.getAction() >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; final int idPointerUp = pMotionEvent.getPointerId(indexPointUp); final float xPointerUp = pMotionEvent.getX(indexPointUp); final float yPointerUp = pMotionEvent.getY(indexPointUp); nativeTouchesEnd(idPointerUp, xPointerUp, yPointerUp); break; case MotionEvent.ACTION_UP: // there are only one finger on the screen final int idUp = pMotionEvent.getPointerId(0); final float xUp = xs[0]; final float yUp = ys[0]; nativeTouchesEnd(idUp, xUp, yUp); break; case MotionEvent.ACTION_CANCEL: nativeTouchesCancel(ids, xs, ys); break; } /* if (BuildConfig.DEBUG) { Cocos2dxGLSurfaceView.dumpMotionEvent(pMotionEvent); } */ return true; } @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1) @Override public boolean onGenericMotionEvent(MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_SCROLL: float v = event.getAxisValue(MotionEvent.AXIS_VSCROLL); nativeMouseScrolled(-v); return true; default: break; } return super.onGenericMotionEvent(event); } } //@Override // ## fix private function // public Cocos2dxGLSurfaceView onCreateView() { // Cocos2dxGLSurfaceView glSurfaceView = new KR2GLSurfaceView(this); // hideSystemUI(); // // // this line is need on some device if we specify an alpha bits // if(this.mGLContextAttrs[3] > 0) glSurfaceView.getHolder().setFormat(PixelFormat.TRANSLUCENT); // // Cocos2dxEGLConfigChooser chooser = new Cocos2dxEGLConfigChooser(this.mGLContextAttrs); // glSurfaceView.setEGLConfigChooser(chooser); // // return glSurfaceView; // } public int get_res_sd_operate_step() { return -1; } static void requireLEXA(final String path) { msgHandler.post(new Runnable() { @Override public void run() { guideDialogForLEXA(path); } }); } static void guideDialogForLEXA(final String path) { AlertDialog.Builder builder = new AlertDialog.Builder(sInstance); ImageView image = new ImageView(sInstance); image.setImageResource(sInstance.get_res_sd_operate_step()); builder .setView(image) .setTitle(path) .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { triggerStorageAccessFramework(); } }) .setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // nothing to do } }) .show(); } static final boolean isWritable(final File file) { if(file==null) return false; boolean isExisting = file.exists(); try { FileOutputStream output = new FileOutputStream(file, true); try { output.close(); } catch (IOException e) { // do nothing. } } catch (FileNotFoundException e) { return false; } boolean result = file.canWrite(); // Ensure that file is not created during this process. if (!isExisting) { file.delete(); } return result; } static final boolean isWritableNormal(final String path) { boolean ret = isWritableNormalOrSaf(path); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { requestExternalWrite(); return isWritableNormalOrSaf(path); } return ret; } static final boolean isWritableNormalOrSaf(final String path) { Log.i("kr2activaty","check path " + path + "permision"); Context c = sInstance; File folder = new File(path); folder.mkdir(); // Log.d("ke2activate", String.format("%b and %b", folder.exists(), folder.isDirectory())); if (!folder.exists() || !folder.isDirectory()) { return false; } // Find a non-existing file in this directory. int i = 0; File file; do { String fileName = "AugendiagnoseDummyFile" + (++i); file = new File(folder, fileName); } while (file.exists()); // First check regular writability Log.d("ke2activate", String.format("%b ", isWritable(file))); if (isWritable(file)) { return true; } // Next check SAF writability. DocumentFile document = getDocumentFile(file, false,c); if (document == null) { return false; } // This should have created the file - otherwise something is wrong with access URL. boolean result = document.canWrite() && file.exists(); // Ensure that the dummy file is not remaining. document.delete(); DocumentFile.fromFile(folder).delete(); return result; } @TargetApi(Build.VERSION_CODES.KITKAT) private static String[] getExtSdCardPaths(Context context) { List paths = new ArrayList(); for (File file : context.getExternalFilesDirs("external")) { if (file != null && !file.equals(context.getExternalFilesDir("external"))) { int index = file.getAbsolutePath().lastIndexOf("/Android/data"); if (index < 0) { Log.w("FileUtils", "Unexpected external file dir: " + file.getAbsolutePath()); } else { String path = file.getAbsolutePath().substring(0, index); try { path = new File(path).getCanonicalPath(); } catch (IOException e) { // Keep non-canonical path. } paths.add(path); } } } //if(paths.isEmpty())paths.add("/storage/sdcard1"); return paths.toArray(new String[0]); } static String[] _extSdPaths; public static String getExtSdCardFolder(final File file,Context context) { if(_extSdPaths == null) _extSdPaths = getExtSdCardPaths(context); try { for (int i = 0; i < _extSdPaths.length; i++) { if (file.getCanonicalPath().startsWith(_extSdPaths[i])) { return _extSdPaths[i]; } } } catch (IOException e) { return null; } return null; } public static boolean isOnExtSdCard(final File file,Context c) { return getExtSdCardFolder(file,c) != null; } public static DocumentFile getDocumentFile(final File file, final boolean isDirectory,Context context) { String baseFolder = getExtSdCardFolder(file,context); boolean originalDirectory=false; if (baseFolder == null) { return null; } String relativePath = null; try { String fullPath = file.getCanonicalPath(); if(!baseFolder.equals(fullPath)) relativePath = fullPath.substring(baseFolder.length() + 1); else originalDirectory=true; } catch (IOException e) { return null; } catch (Exception f){ originalDirectory=true; //continue } String as=PreferenceManager.getDefaultSharedPreferences(context).getString("URI",null); Uri treeUri =null; if(as!=null)treeUri=Uri.parse(as); if (treeUri == null) { return null; } // start with root of SD card and then parse through document tree. DocumentFile document = DocumentFile.fromTreeUri(context, treeUri); if(originalDirectory)return document; String[] parts = relativePath.split("\\/"); for (int i = 0; i < parts.length; i++) { DocumentFile nextDocument = document.findFile(parts[i]); if (nextDocument == null) { try { if ((i < parts.length - 1) || isDirectory) { nextDocument = document.createDirectory(parts[i]); } else { nextDocument = document.createFile("image", parts[i]); } } catch (Exception e) { return null; } } document = nextDocument; } return document; } static public boolean RenameFile(String from, String to) { File file = new File(from); File target = new File(to); if(!file.exists()) return false; if(target.exists()) { if(!DeleteFile(target.getAbsolutePath())) return false; } File parent = target.getParentFile(); if(!parent.exists()) { if(!CreateFolders(parent.getAbsolutePath())) return false; } // Try the normal way if(file.renameTo(target)) return true; // Try with Storage Access Framework. if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP /*&& isOnExtSdCard(file, sInstance)*/) { DocumentFile document = getDocumentFile(file, false, sInstance); if(document.renameTo(to)) return true; } // Try Media Store Hack if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) { try { FileInputStream input = new FileInputStream(file); int filesize = (int) file.length(); byte []buffer = new byte[filesize]; input.read(buffer); input.close(); OutputStream out = MediaStoreHack.getOutputStream(sInstance, target.getAbsolutePath()); out.write(buffer); out.close(); return MediaStoreHack.delete(sInstance, file); } catch (IOException e) { // TODO Auto-generated catch block return false; //e.printStackTrace(); } } return false; } public static final boolean deleteFilesInFolder(final File folder,Context context) { boolean totalSuccess = true; if(folder==null) return false; if (folder.isDirectory()) { for (File child : folder.listFiles()) { deleteFilesInFolder(child, context); } if (!folder.delete()) totalSuccess = false; } else { if (!folder.delete()) totalSuccess = false; } return totalSuccess; } static public boolean DeleteFile(String path) { File file = new File(path); // First try the normal deletion. boolean fileDelete = deleteFilesInFolder(file, sInstance); if (file.delete() || fileDelete) return true; // Try with Storage Access Framework. if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP && isOnExtSdCard(file, sInstance)) { DocumentFile document = getDocumentFile(file, false,sInstance); return document.delete(); } // Try the Kitkat workaround. if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) { ContentResolver resolver = sInstance.getContentResolver(); try { Uri uri = MediaStoreHack.getUriFromFile(file.getAbsolutePath(),sInstance); resolver.delete(uri, null, null); return !file.exists(); } catch (Exception e) { Log.e("FileUtils", "Error when deleting file " + file.getAbsolutePath(), e); return false; } } return !file.exists(); } public static OutputStream getOutputStream(@NonNull final File target,Context context,long s)throws Exception { OutputStream outStream = null; try { // First try the normal way if (isWritable(target)) { // standard way outStream = new FileOutputStream(target); } else { if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP) { // Storage Access Framework DocumentFile targetDocument = getDocumentFile(target, false,context); outStream = context.getContentResolver().openOutputStream(targetDocument.getUri()); } else if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) { // Workaround for Kitkat ext SD card return MediaStoreHack.getOutputStream(context,target.getPath()); } } } catch (Exception e) { Log.e("FileUtils", "Error when copying file from " + target.getAbsolutePath(), e); } return outStream; } static public boolean WriteFile(String path, byte data[]) { File target = new File(path); if(target.exists()) { DeleteFile(target.getAbsolutePath()); // to avoid number suffix name } else { File parent = target.getParentFile(); if(!parent.exists()) CreateFolders(parent.getAbsolutePath()); } OutputStream out = null; // Try the normal way try { if(isWritable(target)) { OutputStream os = new FileOutputStream(target); os.write(data); os.close(); return true; } // Try with Storage Access Framework. if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP /*&& isOnExtSdCard(file, sInstance)*/) { DocumentFile document = getDocumentFile(target, false, sInstance); try { Uri docUri = document.getUri(); out = sInstance.getContentResolver().openOutputStream(docUri); } //catch (FileNotFoundException e) { // e.printStackTrace();} catch (IOException e) { // e.printStackTrace(); } } else if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) { // Workaround for Kitkat ext SD card Uri uri = MediaStoreHack.getUriFromFile(target.getAbsolutePath(),sInstance); out = sInstance.getContentResolver().openOutputStream(uri); } else { return false; } if (out != null) { out.write(data); out.close(); return true; } } catch (FileNotFoundException e) { //return false; } catch (IOException e) { //return false; } return false; } static public boolean CreateFolders(String path) { File file = new File(path); // Try the normal way if(file.mkdirs()) { return true; } // Try with Storage Access Framework. if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.LOLLIPOP /*&& FileUtil.isOnExtSdCard(file, context)*/) { DocumentFile document = getDocumentFile(file, true,sInstance); // getDocumentFile implicitly creates the directory. return document.exists(); } // Try the Kitkat workaround. if (Build.VERSION.SDK_INT==Build.VERSION_CODES.KITKAT) { try { return MediaStoreHack.mkdir(sInstance,file); } catch (IOException e) { //return false; } } return false; } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); //SDLActivity.mHasFocus = hasFocus; if (hasFocus) { hideSystemUI(); } } @TargetApi(Build.VERSION_CODES.HONEYCOMB) void doSetSystemUiVisibility() { int uiOpts = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; getWindow().getDecorView().setSystemUiVisibility(uiOpts); } private static native boolean nativeGetHideSystemButton(); void hideSystemUI() { if(nativeGetHideSystemButton() && android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { doSetSystemUiVisibility(); } } static public String getLocaleName() { Locale defloc = Locale.getDefault(); String lang = defloc.getLanguage(); String country = defloc.getCountry(); if(!country.isEmpty()) { lang += "_"; lang += country.toLowerCase(); } return lang; } static public void exit() { System.exit(0); } static final int ORIENT_VERTICAL = 1; static final int ORIENT_HORIZONTAL = 2; static public void setOrientation(int orient) { if(orient == ORIENT_VERTICAL) { sInstance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else if(orient == ORIENT_HORIZONTAL) { sInstance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } } @TargetApi(Build.VERSION_CODES.LOLLIPOP) static public void triggerStorageAccessFramework() { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); sInstance.startActivityForResult(intent, 3); } @SuppressLint("WrongConstant") @TargetApi(Build.VERSION_CODES.KITKAT) protected void onActivityResult(int requestCode, int responseCode, Intent intent) { if (requestCode == 3) { String p = Sp.getString("URI", null); Uri oldUri = null; if (p != null) oldUri = Uri.parse(p); Uri treeUri = null; if (responseCode == Activity.RESULT_OK) { // Get Uri from Storage Access Framework. treeUri = intent.getData(); // Persist URI - this is required for verification of writability. if (treeUri != null) Sp.edit().putString("URI", treeUri.toString()).commit(); } // If not confirmed SAF, or if still not writable, then revert settings. if (responseCode != Activity.RESULT_OK) { /* DialogUtil.displayError(getActivity(), R.string.message_dialog_cannot_write_to_folder_saf, false, currentFolder);||!FileUtil.isWritableNormalOrSaf(currentFolder) */ if (treeUri != null) Sp.edit().putString("URI", oldUri.toString()).commit(); return; } // After confirmation, update stored value of folder. // Persist access permissions. final int takeFlags = intent.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); getContentResolver().takePersistableUriPermission(treeUri, takeFlags); } } } ================================================ FILE: project/android/app/java/org/tvp/kirikiri2/MediaStoreHack.java ================================================ package org.tvp.kirikiri2; /** * Created by Arpit on 29-06-2015. */ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Locale; import android.annotation.SuppressLint; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.ParcelFileDescriptor; import android.provider.BaseColumns; import android.provider.MediaStore; import android.util.Log; /** * Wrapper for manipulating files via the Android Media Content Provider. As of Android 4.4 KitKat, * applications can no longer write to the "secondary storage" of a device. Write operations using * the java.io.File API will thus fail. This class restores access to those write operations by way * of the Media Content Provider.

* * Note that this class relies on the internal operational characteristics of the media content * provider API, and as such is not guaranteed to be future-proof. Then again, we did all think the * java.io.File API was going to be future-proof for media card access, so all bets are off.

* * If you're forced to use this class, it's because Google/AOSP made a very poor API decision in * Android 4.4 KitKat. Read more at https://plus.google.com/+TodLiebeck/posts/gjnmuaDM8sn

* * Your application must declare the permission "android.permission.WRITE_EXTERNAL_STORAGE".

* * Adapted from: http://forum.xda-developers.com/showpost.php?p=52151865&postcount=20

* * @author Jared Rummler */ public class MediaStoreHack { private static final String ALBUM_ART_URI = "content://media/external/audio/albumart"; private static final String[] ALBUM_PROJECTION = { BaseColumns._ID, MediaStore.Audio.AlbumColumns.ALBUM_ID, "media_type" }; /** * Deletes the file. Returns true if the file has been successfully deleted or otherwise does * not exist. This operation is not recursive. */ public static boolean delete(final Context context, final File file) { final String where = MediaStore.MediaColumns.DATA + "=?"; final String[] selectionArgs = new String[] { file.getAbsolutePath() }; final ContentResolver contentResolver = context.getContentResolver(); final Uri filesUri = MediaStore.Files.getContentUri("external"); // Delete the entry from the media database. This will actually delete media files. contentResolver.delete(filesUri, where, selectionArgs); // If the file is not a media file, create a new entry. if (file.exists()) { final ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath()); contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); // Delete the created entry, such that content provider will delete the file. contentResolver.delete(filesUri, where, selectionArgs); } return !file.exists(); } private static File getExternalFilesDir(final Context context) { return context.getExternalFilesDir(null); } public static InputStream getInputStream(final Context context, final File file, final long size) { try { final String where = MediaStore.MediaColumns.DATA + "=?"; final String[] selectionArgs = new String[] { file.getAbsolutePath() }; final ContentResolver contentResolver = context.getContentResolver(); final Uri filesUri = MediaStore.Files.getContentUri("external"); contentResolver.delete(filesUri, where, selectionArgs); final ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath()); values.put(MediaStore.MediaColumns.SIZE, size); final Uri uri = contentResolver.insert(filesUri, values); return contentResolver.openInputStream(uri); } catch (final Throwable t) { return null; } } public static OutputStream getOutputStream(Context context,String str) { OutputStream outputStream = null; Uri fileUri = getUriFromFile(str,context); if (fileUri != null) { try { outputStream = context.getContentResolver().openOutputStream(fileUri); } catch (Throwable th) { } } return outputStream; } public static Uri getUriFromFile(final String path,Context context) { ContentResolver resolver = context.getContentResolver(); Cursor filecursor = resolver.query(MediaStore.Files.getContentUri("external"), new String[] { BaseColumns._ID }, MediaStore.MediaColumns.DATA + " = ?", new String[] { path }, MediaStore.MediaColumns.DATE_ADDED + " desc"); filecursor.moveToFirst(); if (filecursor.isAfterLast()) { filecursor.close(); ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, path); return resolver.insert(MediaStore.Files.getContentUri("external"), values); } else { @SuppressLint("Range") int imageId = filecursor.getInt(filecursor.getColumnIndex(BaseColumns._ID)); Uri uri = MediaStore.Files.getContentUri("external").buildUpon().appendPath( Integer.toString(imageId)).build(); filecursor.close(); return uri; } } /** * Returns an OutputStream to write to the file. The file will be truncated immediately. */ private static int getTemporaryAlbumId(final Context context) { final File temporaryTrack; try { temporaryTrack = installTemporaryTrack(context); } catch (final IOException ex) { Log.w("MediaFile", "Error installing tempory track.", ex); return 0; } final Uri filesUri = MediaStore.Files.getContentUri("external"); final String[] selectionArgs = { temporaryTrack.getAbsolutePath() }; final ContentResolver contentResolver = context.getContentResolver(); Cursor cursor = contentResolver.query(filesUri, ALBUM_PROJECTION, MediaStore.MediaColumns.DATA + "=?", selectionArgs, null); if (cursor == null || !cursor.moveToFirst()) { if (cursor != null) { cursor.close(); cursor = null; } final ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, temporaryTrack.getAbsolutePath()); values.put(MediaStore.MediaColumns.TITLE, "{MediaWrite Workaround}"); values.put(MediaStore.MediaColumns.SIZE, temporaryTrack.length()); values.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mpeg"); values.put(MediaStore.Audio.AudioColumns.IS_MUSIC, true); contentResolver.insert(filesUri, values); } cursor = contentResolver.query(filesUri, ALBUM_PROJECTION, MediaStore.MediaColumns.DATA + "=?", selectionArgs, null); if (cursor == null) { return 0; } if (!cursor.moveToFirst()) { cursor.close(); return 0; } final int id = cursor.getInt(0); final int albumId = cursor.getInt(1); final int mediaType = cursor.getInt(2); cursor.close(); final ContentValues values = new ContentValues(); boolean updateRequired = false; if (albumId == 0) { values.put(MediaStore.Audio.AlbumColumns.ALBUM_ID, 13371337); updateRequired = true; } if (mediaType != 2) { values.put("media_type", 2); updateRequired = true; } if (updateRequired) { contentResolver.update(filesUri, values, BaseColumns._ID + "=" + id, null); } cursor = contentResolver.query(filesUri, ALBUM_PROJECTION, MediaStore.MediaColumns.DATA + "=?", selectionArgs, null); if (cursor == null) { return 0; } try { if (!cursor.moveToFirst()) { return 0; } return cursor.getInt(1); } finally { cursor.close(); } } private static final byte [] temptrack_mp3 = new byte [] { 73, 68, 51, 4, 0, 0, 0, 0, 8, 65, 84, 80, 69, 49, 0, 0, 0, 24, 0, 0, 0, 123, 77, 101, 100, 105, 97, 87, 114, 105, 116, 101, 32, 87, 111, 114, 107, 97, 114, 111, 117, 110, 100, 125, 84, 65, 76, 66, 0, 0, 0, 24, 0, 0, 0, 123, 77, 101, 100, 105, 97, 87, 114, 105, 116, 101, 32, 87, 111, 114, 107, 97, 114, 111, 117, 110, 100, 125, 84, 73, 84, 50, 0, 0, 0, 24, 0, 0, 0, 123, 77, 101, 100, 105, 97, 87, 114, 105, 116, 101, 32, 87, 111, 114, 107, 97, 114, 111, 117, 110, 100, 125, 65, 80, 73, 67, 0, 0, 2, 33, 0, 0, 0, 105, 109, 97, 103, 101, 47, 112, 110, 103, 0, 3, 0, -119, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 32, 0, 0, 0, 32, 8, 2, 0, 0, 0, -4, 24, -19, -93, 0, 0, 0, 1, 115, 82, 71, 66, 0, -82, -50, 28, -23, 0, 0, 0, -50, 73, 68, 65, 84, 72, -57, -19, 85, -55, 10, -128, 64, 8, 77, -1, -1, -97, -19, 48, 36, -30, 62, 83, -76, 64, 30, 66, -59, -52, 124, 79, -35, -74, 95, -34, 38, 68, 68, 68, 82, 81, -2, -95, -69, 78, 25, 31, 102, 87, -70, 124, 70, -2, 40, 114, 8, 74, 3, 0, -22, 42, 76, 77, 0, -112, 4, -96, -78, 59, -33, -112, 1, 101, 60, 90, 0, -72, 34, -42, 71, 22, 78, 20, -107, 92, -2, -51, 45, 20, -78, 96, 42, -14, -48, 33, 74, -17, 98, 96, 69, 117, -103, -101, -58, -26, 28, -56, -106, 106, 121, 103, 75, 70, -96, 11, 84, -97, 39, 37, -86, -24, -66, -48, 39, 67, 107, -128, -97, 100, 81, -78, 121, 58, 0, -44, 44, 82, -112, 44, -20, 18, -100, 34, -122, 59, -25, 57, 12, 53, -117, -94, -103, 96, 61, 31, -123, -126, 69, 35, -53, -45, 27, 102, -115, 72, -10, -94, 37, -121, -56, 61, -126, -2, -70, 118, -69, -100, 0, -93, -100, 54, 12, -49, 92, -85, -23, -125, 51, 123, -83, 58, -21, 8, 59, -47, -110, 75, 57, -81, -66, 70, -71, 95, 46, -111, 29, -73, 67, 31, -101, 122, -93, -81, 8, 0, 0, 0, 0, 73, 69, 78, 68, -82, 66, 96, -126, 84, 68, 84, 71, 0, 0, 0, 20, 0, 0, 0, 50, 48, 49, 52, 45, 48, 52, 45, 48, 49, 84, 50, 49, 58, 51, 57, 58, 51, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -6, -112, -64, 95, -85, 0, 0, 0, 0, 1, -92, 24, 0, 0, 0, 0, 0, 52, -125, -128, 0, 0, 76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -1, -6, -110, -64, -26, -97, -59, 3, -64, 0, 1, -92, 0, 0, 0, 0, 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0, 0, 0, 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0, 0, 0, 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0, 0, 0, 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 76, 65, 77, 69, 51, 46, 57, 51, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, -1, -6, -110, -64, -6, -34, -1, -125, -64, 0, 1, -92, 0, 0, 0, 0, 0, 0, 52, -128, 0, 0, 0, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85 }; private static File installTemporaryTrack(final Context context) throws IOException { final File externalFilesDir = getExternalFilesDir(context); if (externalFilesDir == null) { return null; } final File temporaryTrack = new File(externalFilesDir, "temptrack.mp3"); OutputStream out = null; try { out = new FileOutputStream(temporaryTrack); out.write(temptrack_mp3); } finally { out.close(); } return temporaryTrack; } public static boolean mkdir(final Context context, final File file) throws IOException { if (file.exists()) { return file.isDirectory(); } final File tmpFile = new File(file, ".MediaWriteTemp"); final int albumId = getTemporaryAlbumId(context); if (albumId == 0) { throw new IOException("Failed to create temporary album id."); } final Uri albumUri = Uri.parse(String.format(Locale.US, ALBUM_ART_URI + "/%d", albumId)); final ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DATA, tmpFile.getAbsolutePath()); final ContentResolver contentResolver = context.getContentResolver(); if (contentResolver.update(albumUri, values, null, null) == 0) { values.put(MediaStore.Audio.AlbumColumns.ALBUM_ID, albumId); contentResolver.insert(Uri.parse(ALBUM_ART_URI), values); } try { final ParcelFileDescriptor fd = contentResolver.openFileDescriptor(albumUri, "r"); fd.close(); } finally { delete(context, tmpFile); } return file.exists(); } public static boolean mkfile(final Context context, final File file) { final OutputStream outputStream = getOutputStream(context, file.getPath()); if (outputStream == null) { return false; } try { outputStream.close(); return true; } catch (final IOException e) { } return false; } } ================================================ FILE: project/android/app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in E:\developSoftware\Android\SDK/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Proguard Cocos2d-x for release -keep public class org.cocos2dx.** { *; } -dontwarn org.cocos2dx.** -keep public class com.chukong.** { *; } -dontwarn com.chukong.** -keep public class com.huawei.android.** { *; } -dontwarn com.huawei.android.** -keep public class com.oppo.oiface.engine.** { *; } -dontwarn com.oppo.oiface.engine.** # Proguard Apache HTTP for release -keep class org.apache.http.** { *; } -dontwarn org.apache.http.** # Proguard Android Webivew for release. uncomment if you are using a webview in cocos2d-x #-keep public class android.net.http.SslError #-keep public class android.webkit.WebViewClient #-dontwarn android.webkit.WebView #-dontwarn android.net.http.SslError #-dontwarn android.webkit.WebViewClient ================================================ FILE: project/android/app/res/values/strings.xml ================================================ Kirikiroid2-Yuri ================================================ FILE: project/android/build.gradle ================================================ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { id 'com.android.application' version '7.4.2' apply false id 'com.android.library' version '7.4.2' apply false } allprojects { buildDir = "./../../../build_android" } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: project/android/gradle/wrapper/gradle-wrapper.properties ================================================ #Sat Mar 11 01:47:25 JST 2023 distributionBase=GRADLE_USER_HOME distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME ================================================ FILE: project/android/gradle.properties ================================================ # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx10248m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true # Android SDK version that will be used as the compile project PROP_COMPILE_SDK_VERSION=29 # Android SDK version that will be used as the earliest version of android this application can run on PROP_MIN_SDK_VERSION=22 # Android SDK version that will be used as the latest version of android this application has been tested on PROP_TARGET_SDK_VERSION=29 # List of CPU Archtexture to build that application with # Available architextures (armeabi-v7a | arm64-v8a | x86) # To build for multiple architexture, use the `:` between them # Example - PROP_APP_ABI=armeabi-v7a:arm64-v8a:x86 PROP_APP_ABI=arm64-v8a # android native code build type # none, native code will never be compiled. # cmake, native code will be compiled by CMakeLists.txt # ndk-build, native code will be compiled by Android.mk PROP_BUILD_TYPE=cmake # uncomment it and fill in sign information for release mode #RELEASE_STORE_FILE=file path of keystore #RELEASE_STORE_PASSWORD=password of keystore #RELEASE_KEY_ALIAS=alias of key #RELEASE_KEY_PASSWORD=password of key android.useAndroidX=True ================================================ FILE: project/android/gradlew ================================================ #!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # For Cygwin, ensure paths are in UNIX format before anything is touched. if $cygwin ; then [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` fi # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >&- APP_HOME="`pwd -P`" cd "$SAVED" >&- CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" ================================================ FILE: project/android/gradlew.bat ================================================ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: project/android/settings.gradle ================================================ pluginManagement { repositories { google() mavenCentral() gradlePluginPortal() } } dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } } include ':cocos2dx' project(':cocos2dx').projectDir = new File(settingsDir, '../../thirdparty/port/cocos2d-x/cocos/platform/android/libcocos2dx') include ':krkr2yuri' project(':krkr2yuri').projectDir = new File(settingsDir, 'app') ================================================ FILE: project/ui/.cocos-project.json ================================================ { "engine_type": "prebuilt", "engine_version": "cocos2d-x-3.6", "project_type": "cpp" } ================================================ FILE: project/ui/Resources/res/locale/en_us.xml ================================================ ================================================ FILE: project/ui/Resources/res/locale/ja_jp.xml ================================================ ================================================ FILE: project/ui/Resources/res/locale/zh_cn.xml ================================================ ================================================ FILE: project/ui/Resources/res/locale/zh_tw.xml ================================================ ================================================ FILE: project/ui/cocosstudio/ui/BottomBar.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/BottomBarTextInput.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/CheckListDialog.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/FileItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/FileManageMenu.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/GameMenu.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/KeySelect.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/ListItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/ListView.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/MainFileSelector.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/MediaPlayerBody.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/MediaPlayerFoot.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/MediaPlayerNavi.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/MenuList.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/MessageBox.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/NaviBar.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/NaviBarWithMenu.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/ProgressBox.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/RecentListItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/SelectList.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/SelectListItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/TableView.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/TextPairInput.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/WinMgrOverlay.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/comctrl/CheckBoxItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/comctrl/SelectListItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/comctrl/SeperateItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/comctrl/SliderIconItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/comctrl/SliderTextItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/comctrl/SubDirItem.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/help/AllTips.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/help/MouseModeTips.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/help/ScreenModeTips.csd ================================================ ================================================ FILE: project/ui/cocosstudio/ui/help/TouchModeTips.csd ================================================ ================================================ FILE: project/ui/kr2.ccs ================================================ ================================================ FILE: project/ui/kr2.cfg ================================================ ================================================ FILE: readme.md ================================================ # Krikiroid2-Yuri ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/YuriSizuku/Kirikiroid2Yuri?color=green&label=krkr2yuri&style=flat-square7&logo=4chan) ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/YuriSizuku/Kirikiroid2Yuri/build_android.yml?label=android%28aarch64%29&style=flat-square) ☘️ A krikiroid2 project matained by Yurisizuku. It will support the newer android device and more formats. Roadmap : - core - [ ] replace rendering from cocos to SDL2 - [ ] command line or config files for setting - [ ] recent cx game (hash filename) decryption support - plugin - [ ] [windowEx](https://github.com/wamsoft/windowEx) - [ ] [layerEx](https://github.com/wamsoft/layerEx) - [ ] [layerExDraw](https://github.com/wamsoft/layerExDraw) (gdiPlus) - [ ] [scriptsEx](https://github.com/wamsoft/scriptsEx) - platform - android - [x] SDK level above 21 (android 5.1, Lolipop) - [x] bypass scoped storage - [ ] access extern sdcard by saf - windows - linux - develop - [x] camke project structure, documention for develop - [x] scripts to compile or cross compile - [x] vscode and android studio project for multi enviroment - [x] ci in github action to automaticly build (This project is heavily relying on cocos. Sooner or later, I might rewrite these parts and replace them by SDL2. And because that the upstream didn't provide all the plugins source code, it still needs sometime to adapt them.) ## 1. usage Although now the apk build from source is runable, it is not perfect. Beta version has some problems due to the cocos version change, incomplecate of some code. Currently the beta version is only aimed for debug. Please use [Kirikiroid2_yuri_1.3.9.apk](https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/1.3.9_yuri/Kirikiroid2_yuri_1.3.9.apk) instead. ## 2. Build I add some futures by reverse engine before, and now this project can be build from source. This is really a very hard work, because there are so many dependencies, lack of files, code not compatible problems. ### (1) prepare - wget, 7z, git, make, cmake - python2(for cocos2d-x v3), msys2 (if windows) - thirdparty depedency (see `_fetch.sh` in detail) ``` shell # wget https://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.gz https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz https://downloads.xiph.org/releases/ogg/libogg-1.3.5.tar.gz https://downloads.xiph.org/releases/opus/opusfile-0.12.tar.gz https://www.rarlab.com/rar/unrarsrc-6.0.7.tar.gz https://www.libsdl.org/release/SDL2-2.0.14.tar.gz # git https://github.com/krkrz/oniguruma https://github.com/google/breakpad https://github.com/zeas2/FFmpeg # git with version https://github.com/google/oboe/archive/refs/tags/1.7.0.tar.gz https://github.com/kcat/openal-soft/archive/refs/tags/1.23.0.tar.gz https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/2.1.5.1.tar.gz https://github.com/opencv/opencv/archive/refs/tags/4.7.0.tar.gz https://github.com/lz4/lz4/archive/refs/tags/v1.9.4.tar.gz https://github.com/libarchive/libarchive/archive/refs/tags/v3.6.2.tar.gz https://github.com/cocos2d/cocos2d-x/archive/refs/tags/cocos2d-x-3.17.2.tar.gz ``` In windows, you must use msys2 to build ffmpeg port. You can also download the prebuild ports from [thirdparty_ports.tar.gz](https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/deps/thirdparty_ports.tar.gz"), [thirdparty_build.tar.gz](https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/deps/thirdparty_build.tar.gz). ## (2) android - android sdk with `ANDROID_HOME` variable in env - android ndk 25.2.9519653 See `_androida64.sh` for how to build dependencies. Use `script/cross_android64.sh` to build ports and the use `project/android/gradlew assembleDebug` to build apk. ## 3. Compatibility |game|version|status|description| |----|-------|------|-----------| ## 4. Issues (including solved) (build from souce, beta version) major: - title path button click position is not correct - crash in game menu form - game alert window button can not click - member GdiPlus does not exist - global preference can not save minor: - ~~android studio buildDir not worked and it make dir at root~~ fixed by cmake `add_subdirectory` build dir ## 5. Todo See Roadmap. ___ Original information about kirikiroid2 bellow, also refered some dependencies from [ningshanwutuobang](https://github.com/ningshanwutuobang/Kirikiroid2). ## Kirikiroid2 - A cross-platform port of Kirikiri2/KirikiriZ ========================================================== Based on most code from [Kirikiri2](http://kikyou.info/tvp/) and [KirikiriZ](https://github.com/krkrz/krkrz) Video playback module modified from [kodi](https://github.com/xbmc/xbmc) Some string code from [glibc](https://www.gnu.org/s/libc) and [Apple Libc](https://opensource.apple.com/source/Libc). Real-time texture codec modified from [etcpak](https://bitbucket.org/wolfpld/etcpak.git), [pvrtccompressor](https://bitbucket.org/jthlim/pvrtccompressor), [astcrt](https://github.com/daoo/astcrt) Android storage accessing code from [AmazeFileManager](https://github.com/arpitkh96/AmazeFileManager) ================================================ FILE: script/_androida64.sh ================================================ # must use after _fetch.sh from cross_androida64.sh # audio build_opus() { if ! [ -d $OPUS_SRC/build_$PLATFORM ]; then mkdir -p $OPUS_SRC/build_$PLATFORM ;fi pushd $OPUS_SRC/build_$PLATFORM ../configure --host=aarch64-linux-android \ CC=aarch64-linux-android21-clang AR=llvm-ar \ CXX=aarch64-linux-android21-clang++ \ --prefix=$PORTBUILD_PATH --with-pic make -j$CORE_NUM && make install popd } build_ogg() { if ! [ -d $OGG_SRC/build_$PLATFORM ]; then mkdir -p $OGG_SRC/build_$PLATFORM ;fi pushd $OGG_SRC/build_$PLATFORM ../configure --host=aarch64-linux-android \ CC=aarch64-linux-android21-clang AR=llvm-ar \ CXX=aarch64-linux-android21-clang++ \ --prefix=$PORTBUILD_PATH --with-pic make -j$CORE_NUM && make install popd } build_vorbis() { if ! [ -d $VORBIS_SRC/build_$PLATFORM ]; then mkdir -p $VORBIS_SRC/build_$PLATFORM ;fi pushd $VORBIS_SRC/build_$PLATFORM ../configure --host=aarch64-linux-android \ CC=aarch64-linux-android21-clang AR=llvm-ar \ CXX=aarch64-linux-android21-clang++ \ --prefix=$PORTBUILD_PATH --with-pic \ --with-ogg=$PORTBUILD_PATH make -j$CORE_NUM && make install popd } build_opusfile() # after ogg, opus, vorbits { if ! [ -d $OPUSFILE_SRC/build_$PLATFORM ]; then mkdir -p $OPUSFILE_SRC/build_$PLATFORM ;fi pushd $OPUSFILE_SRC/build_$PLATFORM ../configure --host=aarch64-linux-android \ CC=aarch64-linux-android21-clang AR=llvm-ar \ CXX=aarch64-linux-android21-clang++ \ --prefix=$PORTBUILD_PATH --with-pic \ DEPS_CFLAGS="-I$PORTBUILD_PATH/include -I$PORTBUILD_PATH/include/opus" \ DEPS_LIBS="-L$PORTBUILD_PATH/lib -logg -lopus" \ --disable-http --disable-examples make -j$CORE_NUM && make install cp -rf $CMAKELISTS_PATH/thirdparty/patch/opus/opusfile.h $PORTBUILD_PATH/include/opus/opusfile.h popd } build_oboe() { if ! [ -d $OBOE_SRC/build_$PLATFORM ]; then mkdir -p $OBOE_SRC/build_$PLATFORM ;fi pushd $OBOE_SRC/build_$PLATFORM cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \ -DCMAKE_C_FLAGS="-fPIC" -DCMAKE_CXX_FLAGS="-fPIC" \ -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \ -DLIBTYPE=STATIC make -j$CORE_NUM && make install mv -f $PORTBUILD_PATH/lib/arm64-v8a/liboboe.a $PORTBUILD_PATH/lib/liboboe.a popd } build_openal() { if ! [ -d $OPENAL_SRC/build_$PLATFORM ]; then mkdir -p $OPENAL_SRC/build_$PLATFORM ;fi pushd $OPENAL_SRC/build_$PLATFORM cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \ -DCMAKE_C_FLAGS="-fPIC" -DCMAKE_CXX_FLAGS="-fPIC" \ -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \ -DLIBTYPE=STATIC make -j$CORE_NUM && make install popd } # video build_jpeg() { if ! [ -d $JPEG_SRC/build_$PLATFORM ]; then mkdir -p $JPEG_SRC/build_$PLATFORM ;fi pushd $JPEG_SRC/build_$PLATFORM NDK_PATH=$NDK_HOME TOOLCHAIN=clang ANDROID_VERSION=21 cmake .. -G "Unix Makefiles" \ -DANDROID_ABI=arm64-v8a \ -DANDROID_ARM_MODE=arm \ -DANDROID_PLATFORM=android-${ANDROID_VERSION} \ -DANDROID_TOOLCHAIN=${TOOLCHAIN} \ -DCMAKE_ASM_FLAGS="--target=aarch64-linux-android${ANDROID_VERSION}" \ -DCMAKE_TOOLCHAIN_FILE=${NDK_PATH}/build/cmake/android.toolchain.cmake \ -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH make -j$CORE_NUM && make install popd } build_opencv() { if ! [ -d $OPENCV_SRC/build_$PLATFORM ]; then mkdir -p $OPENCV_SRC/build_$PLATFORM ;fi pushd $OPENCV_SRC/build_$PLATFORM cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \ -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \ -DWITH_CUDA=OFF -DWITH_MATLAB=OFF -DBUILD_ANDROID_EXAMPLES=OFF \ -DBUILD_DOCS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_TESTS=OFF \ -DBUILD_opencv_video=OFF -DBUILD_opencv_videoio=OFF -DBUILD_opencv_features2d=OFF \ -DBUILD_opencv_flann=OFF -DBUILD_opencv_highgui=OFF -DBUILD_opencv_ml=OFF \ -DBUILD_opencv_dnn=OFF -DBUILD_opencv_gapi=OFF -DBUILD_opencv_hal=ON \ -DBUILD_opencv_photo=OFF -DBUILD_opencv_python=OFF -DBUILD_opencv_shape=OFF \ -DBUILD_opencv_stitching=OFF -DBUILD_opencv_superres=OFF -DWITH_ITT=OFF \ -DBUILD_opencv_ts=OFF -DBUILD_opencv_videostab=OFF -DBUILD_ANDROID_PROJECTS=OFF make -j$CORE_NUM && make install cp -rf $PORTBUILD_PATH/sdk/native/3rdparty/libs/arm64-v8a/*.a $PORTBUILD_PATH/lib cp -rf $PORTBUILD_PATH/sdk/native/staticlibs/arm64-v8a/libtegra_hal.a $PORTBUILD_PATH/lib popd } build_ffmpeg() { if ! [ -d $FFMPEG_SRC/build_$PLATFORM ]; then mkdir -p $FFMPEG_SRC/build_$PLATFORM ;fi pushd $FFMPEG_SRC git apply $CMAKELISTS_PATH/thirdparty/patch/ffmpeg/android_ffmpeg.diff cd build_$PLATFORM ../configure --enable-cross-compile --cross-prefix=aarch64-linux-android- \ --cc=aarch64-linux-android21-clang --ar=llvm-ar \ --cxx=aarch64-linux-android21-clang++ --ranlib=llvm-ranlib \ --strip=llvm-strip --prefix=$PORTBUILD_PATH \ --arch=aarch64 --target-os=android --enable-pic --disable-asm \ --enable-static --enable-shared --enable-small --enable-swscale \ --disable-ffmpeg --disable-ffplay --disable-ffprobe \ --disable-avdevice --disable-programs --disable-doc --enable-stripping # use sh directory is not available in windows (absolute path), must use msys2 shell make -j$CORE_NUM && make install popd } # archive build_unrar() { cp -rf $CMAKELISTS_PATH/thirdparty/patch/unrar/android_ulinks.cpp $UNRAR_SRC/ulinks.cpp pushd $UNRAR_SRC make clean make lib -j$CORE_NUM \ CXX=aarch64-linux-android21-clang++ \ AR=llvm-ar STRIP=llvm-strip \ DESTDIR=$PORTBUILD_PATH if ! [ -d $PORTBUILD_PATH/include/unrar ]; then mkdir -p $PORTBUILD_PATH/include/unrar ;fi cp -rf *.a $PORTBUILD_PATH/lib cp -rf *.hpp $PORTBUILD_PATH/include/unrar popd } build_lz4() { pushd $LZ4_SRC make clean make lib -j$CORE_NUM \ CC=aarch64-linux-android21-clang \ CXX=aarch64-linux-android21-clang++ \ AR=llvm-ar STRIP=llvm-strip \ WINBASED=no if ! [ -d $PORTBUILD_PATH/include/lz4 ]; then mkdir -p $PORTBUILD_PATH/include/lz4 ;fi cp -rp lib/*.a $PORTBUILD_PATH/lib cp -rp lib/*.h $PORTBUILD_PATH/include/lz4 popd } build_archive() { if ! [ -d $ARCHIVE_SRC/build_$PLATFORM ]; then mkdir -p $ARCHIVE_SRC/build_$PLATFORM ;fi cp -rf $CMAKELISTS_PATH/thirdparty/patch/android_android_lf.h $ARCHIVE_SRC/libarchive/android_lf.h pushd $ARCHIVE_SRC/build_$PLATFORM cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \ -DENABLE_OPENSSL=OFF -DENABLE_TEST=OFF \ -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH make -j$CORE_NUM && make install if ! [ -d $PORTBUILD_PATH/include/libarchive ]; then mkdir -p $PORTBUILD_PATH/include/libarchive ;fi mv -f $PORTBUILD_PATH/include/archive.h $PORTBUILD_PATH/include/libarchive mv -f $PORTBUILD_PATH/include/archive_entry.h $PORTBUILD_PATH/include/libarchive popd } build_p7zip() { if ! [ -d $P7ZIP_SRC/build_$PLATFORM ]; then mkdir -p $P7ZIP_SRC/build_$PLATFORM ;fi cp -rf $CMAKELISTS_PATH/thirdparty/patch/p7zip/7z* $P7ZIP_SRC/C cp -rf $CMAKELISTS_PATH/thirdparty/patch/p7zip/android_p7zip.cmake $P7ZIP_SRC/CPP/ANDROID/7za/jni/CMakeLists.txt pushd $P7ZIP_SRC/build_$PLATFORM cmake ../CPP/ANDROID/7za/jni -G "Unix Makefiles" \ -DCMAKE_BUILD_TYPE=MinSizeRel \ -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \ -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake make -j$CORE_NUM if ! [ -d $PORTBUILD_PATH/include/p7zip/C ]; then mkdir -p $PORTBUILD_PATH/include/p7zip/C ;fi if ! [ -d $PORTBUILD_PATH/include/p7zip/CPP ]; then mkdir -p $PORTBUILD_PATH/include/p7zip/CPP ;fi cp -rf lib7za.a $PORTBUILD_PATH/lib cp -rf ../C/*.h $PORTBUILD_PATH/include/p7zip/C cp -rf ../CPP $PORTBUILD_PATH/include/p7zip rm -rf $PORTBUILD_PATH/include/p7zip/CPP/**/*.cpp rm -rf $PORTBUILD_PATH/include/p7zip/CPP/**/**/*.cpp rm -rf $PORTBUILD_PATH/include/p7zip/CPP/**/**/**/*.cpp rm -rf $PORTBUILD_PATH/include/p7zip/CPP/**/**/**/**/*.cpp rm -rf $PORTBUILD_PATH/include/p7zip/CPP/ANDROID/7za/obj popd } # others build_oniguruma() { if ! [ -d $ONIGURUMA_SRC/build_$PLATFORM ]; then mkdir -p $ONIGURUMA_SRC/build_$PLATFORM ;fi cp -rf $CMAKELISTS_PATH/thirdparty/patch/oniguruma/oniguruma.cmake $ONIGURUMA_SRC/CMakeLists.txt pushd $ONIGURUMA_SRC/build_$PLATFORM cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \ -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH make -j$CORE_NUM && make install popd } build_breakpad() # after linux-syscall { if ! [ -d $BREAKPAD_SRC/build_$PLATFORM ]; then mkdir -p $BREAKPAD_SRC/build_$PLATFORM ;fi cp -rf $SYSCALL_SRC/lss $BREAKPAD_SRC/src/third_party/ pushd $BREAKPAD_SRC/build_$PLATFORM ../configure --host=aarch64-linux-android \ CC=aarch64-linux-android21-clang AR=llvm-ar \ CXX=aarch64-linux-android21-clang++ STRIP=llvm-strip \ --prefix=$PORTBUILD_PATH \ --disable-tools make -j$CORE_NUM && make install-strip popd } # framework build_sdl2() { if ! [ -d $SDL2_SRC/build_$PLATFORM ]; then mkdir -p $SDL2_SRC/build_$PLATFORM ;fi cp -rf $CMAKELISTS_PATH/thirdparty/patch/sdl2/android_SDL_android.c $SDL2_SRC/src/core/android/SDL_android.c pushd $SDL2_SRC/build_$PLATFORM cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \ -DANDROID=ON -DCMAKE_SYSTEM_NAME=Linux \ -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \ -DHIDAPI=OFF -DHAVE_GCC_WDECLARATION_AFTER_STATEMENT=OFF make -j$CORE_NUM && make install popd } build_cocos2dx() { if ! [ -d $COCOS2DX_SRC/platform/build_$PLATFORM ]; then mkdir -p $COCOS2DX_SRC/build_$PLATFORM ;fi cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_cocos2dx.cmake $COCOS2DX_SRC/CMakeLists.txt cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_CCFileUtils-android.h $COCOS2DX_SRC/cocos/platform/android/CCFileUtils-android.h cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_CCFileUtils-android.cpp $COCOS2DX_SRC/cocos/platform/android/CCFileUtils-android.cpp cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_Java_org_cocos2dx_lib_Cocos2dxHelper.h $COCOS2DX_SRC/cocos/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h cp $CMAKELISTS_PATH/thirdparty/patch/cocos2d-x/android_Java_org_cocos2dx_lib_Cocos2dxHelper.cpp $COCOS2DX_SRC/cocos/platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.cpp pushd $COCOS2DX_SRC/build_$PLATFORM cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=MinSizeRel \ -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \ -DCMAKE_INSTALL_PREFIX=$PORTBUILD_PATH \ -DBUILD_TESTS=OFF -DBUILD_LUA_LIBS=OFF -DBUILD_JS_LIBS=OFF make -j$CORE_NUM cp -rf lib/libcocos2d.a $PORTBUILD_PATH/lib/ cp -rf lib/libext_*.a $PORTBUILD_PATH/lib/ cp -rf engine/cocos/android/libcpp_android_spec.a $PORTBUILD_PATH/lib/ cp -rf ../external/zlib/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/ cp -rf ../external/png/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/ cp -rf ../external/tiff/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/ cp -rf ../external/webp/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/ cp -rf ../external/freetype2/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/ cp -rf ../external/chipmunk/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/ cp -rf ../external/bullet/prebuilt/android/arm64-v8a/*.a $PORTBUILD_PATH/lib/ popd } ================================================ FILE: script/_fetch.sh ================================================ # prepare dirs if ! [ -d $CMAKELISTS_PATH/thirdparty/port ]; then mkdir -p $CMAKELISTS_PATH/thirdparty/port; fi if ! [ -d $CMAKELISTS_PATH/thirdparty/build/arch_androida32 ]; then mkdir -p $CMAKELISTS_PATH/thirdparty/build/arch_androida32; fi if ! [ -d $CMAKELISTS_PATH/thirdparty/build/arch_androida64 ]; then mkdir -p $CMAKELISTS_PATH/thirdparty/build/arch_androida64; fi # fetch by wget function fetch_port() # urlbase, name, outpath { if ! [ -d "$CMAKELISTS_PATH/thirdparty/port/$2" ]; then echo "## fetch_port $1 $2" wget $1/$2.tar.gz -O $CMAKELISTS_PATH/thirdparty/port/$2.tar.gz tar zxf $CMAKELISTS_PATH/thirdparty/port/$2.tar.gz -C $CMAKELISTS_PATH/thirdparty/port fi } # fetch by git function fetch_port2() { if ! [ -d "$CMAKELISTS_PATH/thirdparty/port/$2" ]; then inpath=$1/$2.git outpath=$CMAKELISTS_PATH/thirdparty/port/$2 tag=$3 echo "## fetch_port $inpath $tag" if [ -n "$tag" ]; then git clone --recursive --depth 1 --branch $tag $inpath $outpath else git clone --recursive --depth 1 $inpath $outpath fi fi } # wget ports function fetch_vorbis() { VORBIS_NAME=libvorbis-1.3.7 VORBIS_SRC=$CMAKELISTS_PATH/thirdparty/port/$VORBIS_NAME fetch_port https://downloads.xiph.org/releases/vorbis $VORBIS_NAME } function fetch_opus() { OPUS_NAME=opus-1.3.1 OPUS_SRC=$CMAKELISTS_PATH/thirdparty/port/$OPUS_NAME fetch_port https://archive.mozilla.org/pub/opus $OPUS_NAME } function fetch_ogg() { OGG_NAME=libogg-1.3.5 OGG_SRC=$CMAKELISTS_PATH/thirdparty/port/$OGG_NAME fetch_port https://downloads.xiph.org/releases/ogg $OGG_NAME } function fetch_opusfile() { OPUSFILE_NAME=opusfile-0.12 OPUSFILE_SRC=$CMAKELISTS_PATH/thirdparty/port/$OPUSFILE_NAME fetch_port https://downloads.xiph.org/releases/opus $OPUSFILE_NAME } function fetch_unrar() { UNRAR_NAME=unrarsrc-6.0.7 UNRAR_SRC=$CMAKELISTS_PATH/thirdparty/port/$UNRAR_NAME fetch_port https://www.rarlab.com/rar $UNRAR_NAME if [ -d $CMAKELISTS_PATH/thirdparty/port/unrar ]; then mv $CMAKELISTS_PATH/thirdparty/port/unrar $UNRAR_SRC fi } function fetch_p7zip() { P7ZIP_NAME=p7zip_16.02 P7ZIP_SRC=$CMAKELISTS_PATH/thirdparty/port/$P7ZIP_NAME if ! [ -d "$P7ZIP_SRC" ]; then echo "## fetch_port $P7ZIP_NAME" wget https://sourceforge.net/projects/p7zip/files/p7zip/16.02/p7zip_16.02_src_all.tar.bz2 \ -O $CMAKELISTS_PATH/thirdparty/port/$P7ZIP_NAME.tar.bz2 tar zxf $CMAKELISTS_PATH/thirdparty/port//$P7ZIP_NAME.tar.bz2 \ -C $CMAKELISTS_PATH/thirdparty/port fi } function fetch_sdl2() { SDL2_NAME=SDL2-2.0.14 SDL2_SRC=$CMAKELISTS_PATH/thirdparty/port/$SDL2_NAME fetch_port https://www.libsdl.org/release $SDL2_NAME } # git ports function fetch_openal() { OPENAL_NAME=openal-soft OPENAL_VERSION=1.23.0 OPENAL_SRC=$CMAKELISTS_PATH/thirdparty/port/$OPENAL_NAME fetch_port2 https://github.com/kcat $OPENAL_NAME $OPENAL_VERSION } function fetch_oboe() { OBOE_NAME=oboe OBOE_VERSION=1.7.0 OBOE_SRC=$CMAKELISTS_PATH/thirdparty/port/$OBOE_NAME fetch_port2 https://github.com/google $OBOE_NAME $OBOE_VERSION } function fetch_jpeg() { JPEG_NAME=libjpeg-turbo JPEG_SRC=$CMAKELISTS_PATH/thirdparty/port/$JPEG_NAME JPEG_VERSION=2.1.5.1 fetch_port2 https://github.com/libjpeg-turbo $JPEG_NAME $JPEG_VERSION } function fetch_opencv() { OPENCV_NAME=opencv OPENCV_VERSION=4.7.0 OPENCV_SRC=$CMAKELISTS_PATH/thirdparty/port/$OPENCV_NAME fetch_port2 https://github.com/opencv $OPENCV_NAME $OPENCV_VERSION } function fetch_ffmpeg() { FFMPEG_NAME=ffmpeg FFMPEG_SRC=$CMAKELISTS_PATH/thirdparty/port/$FFMPEG_NAME fetch_port2 https://github.com/zeas2 $FFMPEG_NAME } function fetch_lz4() { LZ4_NAME=lz4 LZ4_VERSION=v1.9.4 LZ4_SRC=$CMAKELISTS_PATH/thirdparty/port/$LZ4_NAME fetch_port2 https://github.com/lz4 $LZ4_NAME $LZ4_VERSION } function fetch_archive() { ARCHIVE_NAME=libarchive ARCHIVE_VERSION=v3.6.2 ARCHIVE_SRC=$CMAKELISTS_PATH/thirdparty/port/$ARCHIVE_NAME fetch_port2 https://github.com/libarchive $ARCHIVE_NAME $ARCHIVE_VERSION } function fetch_oniguruma() { ONIGURUMA_NAME=oniguruma ONIGURUMA_SRC=$CMAKELISTS_PATH/thirdparty/port/$ONIGURUMA_NAME fetch_port2 https://github.com/krkrz $ONIGURUMA_NAME } function fetch_syscall() { SYSCALL_NAME=linux-syscall-support SYSCALL_SRC=$CMAKELISTS_PATH/thirdparty/port/$SYSCALL_NAME fetch_port2 https://github.com/adelshokhy112 $SYSCALL_NAME } function fetch_breakpad() { BREAKPAD_NAME=breakpad BREAKPAD_SRC=$CMAKELISTS_PATH/thirdparty/port/$BREAKPAD_NAME fetch_port2 https://github.com/google $BREAKPAD_NAME } function fetch_cocos2dx() { COCOS2DX_NAME=cocos2d-x COCOS2DX_VERSION=cocos2d-x-3.17.2 COCOS2DX_SRC=$CMAKELISTS_PATH/thirdparty/port/$COCOS2DX_NAME fetch_port2 https://github.com/cocos2d $COCOS2DX_NAME $COCOS2DX_VERSION if ! [ -d "$CMAKELISTS_PATH/thirdparty/port/$COCOS2DX_NAME" ]; then pushd $COCOS2DX_SRC python2 download-deps.py # must use cocos v3 and python2 git config --global url.https://github.com/.insteadOf git://github.com/ git submodule update --init # submodule might cuse some problem, as it use git@ popd fi } # android function fetch_asset() { if ! [ -d "$CMAKELISTS_PATH/assets" ]; then wget https://github.com/YuriSizuku/Kirikiroid2Yuri/releases/download/1.3.9_yuri/Kirikiroid2_yuri_1.3.9.apk \ -O $CMAKELISTS_PATH/thirdparty/port/Kirikiroid2_yuri_1.3.9.apk 7z x -o$CMAKELISTS_PATH $CMAKELISTS_PATH/thirdparty/port/Kirikiroid2_yuri_1.3.9.apk assets fi } # notused ports function fetch_bpg() { BPG_NAME=android-bpg BPG_SRC=$CMAKELISTS_PATH/thirdparty/port/$BPG_NAME fetch_port2 https://github.com/alexandruc $BPG_NAME } function fetch_jxr() { JXR_NAME=jxrlib JXR_SRC=$CMAKELISTS_PATH/thirdparty/port/$JXR_NAME fetch_port2 https://github.com/krkrz $JXR_NAME } ================================================ FILE: script/cross_androida64.sh ================================================ # bash -c "export SKIP_PORTS=yes && ./cross_androida64.sh" PLATFORM=androida64 BUILD_PATH=./../build_${PLATFORM} CMAKELISTS_PATH=$(pwd)/.. PORTBUILD_PATH=$CMAKELISTS_PATH/thirdparty/build/arch_$PLATFORM ANDROID_THIRDPARTY_PATH=$CMAKELISTS_PATH/src/onsyuri_android/app/cpp/thirdparty CORE_NUM=$(cat /proc/cpuinfo | grep -c ^processor) TARGETS=$@ function fetch_ports() { # audio fetch_opus fetch_ogg fetch_vorbis fetch_opusfile fetch_oboe fetch_openal # video fetch_jpeg fetch_opencv fetch_ffmpeg # archive fetch_unrar fetch_lz4 fetch_archive fetch_p7zip # others fetch_oniguruma fetch_syscall fetch_breakpad # framework fetch_sdl2 fetch_cocos2dx } function build_ports() { # audio build_opus build_ogg build_vorbis build_opusfile build_oboe build_openal # video build_jpeg build_opencv build_ffmpeg # archive build_unrar build_lz4 build_archive build_p7zip # others build_oniguruma build_breakpad # framework build_sdl2 build_cocos2dx } # prepare env, tested with ndk 25.2.9519653 if [ -z "$ANDROID_HOME" ]; then ANDROID_HOME=/d/Software/env/sdk/androidsdk; fi NDK_HOME=$ANDROID_HOME/ndk/$(ls -A $ANDROID_HOME/ndk | tail -n 1) PREBUILT_DIR=$NDK_HOME/toolchains/llvm/prebuilt PREBUILT_DIR=$PREBUILT_DIR/$(ls -A $PREBUILT_DIR | tail -n 1) PATH=$NDK_HOME/build:$PREBUILT_DIR/bin:$PATH CC=$(which aarch64-linux-android21-clang) CXX=$(which aarch64-linux-android21-clang++) AR=$(which llvm-ar) RANLIB=$(which llvm-ranlib) NM=$(which llvm-nm) STRIP=$(which llvm-strip) NDKBUILD=$(which ndk-build) SYSROOT=$PREBUILT_DIR/sysroot echo "## ANDROID_HOME=$ANDROID_HOME" echo "## NDK-BUILD=$NDKBUILD" echo "## CC=$CC" echo "## AR=$AR" # fetch and build ports # SKIP_PORTS="yes" source ./_fetch.sh source ./_$PLATFORM.sh fetch_asset if [ -z "$SKIP_PORTS" ]; then fetch_ports build_ports fi # config and build project if [ -z "$BUILD_TYPE" ]; then BUILD_TYPE=MinSizeRel; fi if [ -z "$TARGETS" ]; then TARGETS=all; fi cmake -B $BUILD_PATH -S $CMAKELISTS_PATH \ -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ -DCMAKE_TOOLCHAIN_FILE=$NDK_HOME/build/cmake/android.toolchain.cmake \ -DANDROID_PLATFORM=21 -DANDROID_ABI=arm64-v8a \ -DPORTBUILD_PATH=$PORTBUILD_PATH make -C $BUILD_PATH $TARGETS -j$CORE_NUM # make -C $BUILD_PATH $TARGETS -j1 # $STRIP $BUILD_PATH/libkrkr2yuri.so ================================================ FILE: src/core/Android.mk ================================================ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := krkr2 LOCAL_SRC_FILES := \ $(filter-out $(LOCAL_PATH)/visual/Resampler.cpp, $(wildcard $(LOCAL_PATH)/visual/*.cpp)) \ $(wildcard $(LOCAL_PATH)/base/7zip/*.c) \ $(wildcard $(LOCAL_PATH)/base/7zip/C/*.c) \ $(wildcard $(LOCAL_PATH)/base/7zip/CPP/*/*.cpp) \ $(wildcard $(LOCAL_PATH)/base/7zip/CPP/*/*/*.cpp) \ $(wildcard $(LOCAL_PATH)/base/7zip/CPP/*/*/*/*.cpp) \ $(wildcard $(LOCAL_PATH)/base/*.cpp) \ $(filter-out $(LOCAL_PATH)/base/win32/FuncStubs.cpp $(LOCAL_PATH)/base/win32/SusieArchive.cpp, $(wildcard $(LOCAL_PATH)/base/win32/*.cpp)) \ $(filter-out $(LOCAL_PATH)/environ/MainFormUnit.cpp, $(wildcard $(LOCAL_PATH)/environ/*.cpp)) \ $(wildcard $(LOCAL_PATH)/environ/cocos2d/*.cpp) \ $(wildcard $(LOCAL_PATH)/environ/android/*.cpp) \ $(wildcard $(LOCAL_PATH)/environ/linux/*.cpp) \ $(wildcard $(LOCAL_PATH)/environ/ui/*.cpp) \ $(wildcard $(LOCAL_PATH)/environ/ui/extension/*.cpp) \ environ/win32/SystemControl.cpp \ $(wildcard $(LOCAL_PATH)/extension/*.cpp) \ $(wildcard $(LOCAL_PATH)/movie/*.cpp) \ $(wildcard $(LOCAL_PATH)/movie/*/*.cpp) \ $(wildcard $(LOCAL_PATH)/msg/*.cpp) \ msg/win32/MsgImpl.cpp \ msg/win32/OptionsDesc.cpp \ $(filter-out $(LOCAL_PATH)/sound/xmmlib.cpp $(LOCAL_PATH)/sound/WaveFormatConverter_SSE.cpp, $(wildcard $(LOCAL_PATH)/sound/*.cpp)) \ $(wildcard $(LOCAL_PATH)/sound/win32/*.cpp) \ $(wildcard $(LOCAL_PATH)/tjs2/*.cpp) \ $(wildcard $(LOCAL_PATH)/utils/*.c) \ $(wildcard $(LOCAL_PATH)/utils/*.cpp) \ $(wildcard $(LOCAL_PATH)/utils/encoding/*.c) \ $(wildcard $(LOCAL_PATH)/utils/minizip/*.c) \ $(wildcard $(LOCAL_PATH)/utils/minizip/*.cpp) \ $(wildcard $(LOCAL_PATH)/utils/win32/*.cpp) \ $(wildcard $(LOCAL_PATH)/visual/gl/*.cpp) \ $(wildcard $(LOCAL_PATH)/visual/ogl/*.cpp) \ $(filter-out $(LOCAL_PATH)/visual/win32/GDIFontRasterizer.cpp $(LOCAL_PATH)/visual/win32/NativeFreeTypeFace.cpp \ $(LOCAL_PATH)/visual/win32/TVPSysFont.cpp $(LOCAL_PATH)/visual/win32/VSyncTimingThread.cpp \ , $(wildcard $(LOCAL_PATH)/visual/win32/*.cpp)) \ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES:$(LOCAL_PATH)/%=%) LOCAL_C_INCLUDES += $(LOCAL_PATH)/base \ $(LOCAL_PATH)/base/win32 \ $(LOCAL_PATH)/environ \ $(LOCAL_PATH)/environ/win32 \ $(LOCAL_PATH)/environ/android \ $(LOCAL_PATH)/environ/sdl \ $(LOCAL_PATH)/msg \ $(LOCAL_PATH)/msg/win32 \ $(LOCAL_PATH)/extension \ $(LOCAL_PATH)/sound \ $(LOCAL_PATH)/sound/win32 \ $(LOCAL_PATH)/tjs2 \ $(LOCAL_PATH)/utils \ $(LOCAL_PATH)/utils/win32 \ $(LOCAL_PATH)/../../vendor/freetype/current/include \ $(LOCAL_PATH)/visual \ $(LOCAL_PATH)/visual/ARM \ $(LOCAL_PATH)/visual/win32 \ $(LOCAL_PATH)/../plugins \ $(LOCAL_PATH)/../../vendor/jxrlib/current/common/include \ $(LOCAL_PATH)/../../vendor/jxrlib/current/image/sys \ $(LOCAL_PATH)/../../vendor/jxrlib/current/jxrgluelib \ $(LOCAL_PATH)/../../vendor/libjpeg-turbo/current \ $(LOCAL_PATH)/../../vendor/onig/current \ $(LOCAL_PATH)/../../vendor/libiconv/current/include \ $(LOCAL_PATH)/../../vendor/fmod/include \ $(LOCAL_PATH)/../../vendor/libgdiplus/src \ $(LOCAL_PATH)/../../vendor/opus/current/include \ $(LOCAL_PATH)/../../vendor/opus/opusfile/include \ $(LOCAL_PATH)/../../vendor/opencv/current/build/include \ $(LOCAL_PATH)/../../vendor/openal/current/include \ $(LOCAL_PATH)/../../vendor/lz4 \ $(LOCAL_PATH)/../../libs/android/bpg/include \ $(LOCAL_PATH)/../../libs/android/ffmpeg/include \ $(LOCAL_PATH)/../../libs/android/libarchive/include \ $(LOCAL_PATH)/visual/RenderScript/rs \ $(LOCAL_PATH)/../../vendor/cocos2d-x/current/cocos \ $(LOCAL_PATH)/../../vendor/cocos2d-x/current/cocos/platform \ $(LOCAL_PATH)/../../vendor/cocos2d-x/current/external/webp/include/android \ $(LOCAL_PATH)/../../vendor/cocos2d-x/current/external/jpeg/include/android \ $(LOCAL_PATH)/../../vendor/cocos2d-x/current/external/png/include/android \ $(LOCAL_PATH)/../../vendor/cocos2d-x/current/external \ LOCAL_CPPFLAGS += -DTJS_TEXT_OUT_CRLF -D__STDC_CONSTANT_MACROS -DUSE_UNICODE_FSTRING LOCAL_CFLAGS += -DTJS_TEXT_OUT_CRLF -D_7ZIP_ST LOCAL_STATIC_LIBRARIES := ffmpeg libopencv_imgproc libopencv_core libopencv_hal libtbb gdiplus_static cpufeatures \ opusfile_static opus_static onig_static libbpg_static vorbis_static cairo_static pixman_static expat_static \ breakpad_client openal_static jxrlib_static libarchive_static # libRScpp_static include $(BUILD_STATIC_LIBRARY) $(call import-module, android/cpufeatures) $(call import-module, opus) $(call import-module, opusfile) $(call import-module, onig) $(call import-module, bpg) $(call import-module, opencv) $(call import-module, openal) $(call import-module, vorbis) #$(call import-module, android-ndk-profiler) $(call import-module, jxrlib) $(call import-module, ffmpeg) $(call import-module, cairo) $(call import-module, pixman) $(call import-module, gdiplus) $(call import-module, expat) $(call import-module, google_breakpad) #$(call import-module, libRScpp) $(call import-module, libarchive) ================================================ FILE: src/core/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.6) project(krkr2core) set(KRKR2CORE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) set(COCOS2DX_PATH ${KRKR2CORE_PATH}/../../thirdparty/port/cocos2d-x) # prepare static lib function(add_static_library TARGET LIBNAME) if ("${LIBNAME}" STREQUAL "") set(LIBNAME "lib${TARGET}.a") endif() add_library("${TARGET}_static" STATIC IMPORTED GLOBAL) set_target_properties("${TARGET}_static" PROPERTIES IMPORTED_LOCATION ${PORTBUILD_PATH}/lib/${LIBNAME} ) endfunction() add_static_library(jpeg libturbojpeg.a) add_static_library(ogg "") add_static_library(opus "") add_static_library(opusfile "") add_static_library(vorbis "") add_static_library(vorbisfile "") add_static_library(vorbisenc "") add_static_library(openal "") add_static_library(archive "") add_static_library(avutil "") add_static_library(avfilter "") add_static_library(avformat "") add_static_library(avcodec "") add_static_library(swscale "") add_static_library(swresample "") add_static_library(onig "") add_static_library(sdl2 libSDL2.a) # search kr2core src file(GLOB KRKR2CORE_CODE ${KRKR2CORE_PATH}/visual/*.cpp ${KRKR2CORE_PATH}/base/*.cpp ${KRKR2CORE_PATH}/base/win32/*.cpp ${KRKR2CORE_PATH}/environ/*.cpp ${KRKR2CORE_PATH}/environ/ConfigManager/*.cpp ${KRKR2CORE_PATH}/environ/cocos2d/*.cpp ${KRKR2CORE_PATH}/environ/linux/*.cpp ${KRKR2CORE_PATH}/environ/ui/*.cpp ${KRKR2CORE_PATH}/environ/ui/extension/*.cpp ${KRKR2CORE_PATH}/environ/win32/SystemControl.cpp ${KRKR2CORE_PATH}/extension/*.cpp ${KRKR2CORE_PATH}/movie/*.cpp ${KRKR2CORE_PATH}/movie/*/*.cpp ${KRKR2CORE_PATH}/msg/*.cpp ${KRKR2CORE_PATH}/msg/win32/MsgImpl.cpp ${KRKR2CORE_PATH}/msg/win32/OptionsDesc.cpp ${KRKR2CORE_PATH}/sound/*.cpp ${KRKR2CORE_PATH}/sound/win32/*.cpp ${KRKR2CORE_PATH}/tjs2/*.cpp ${KRKR2CORE_PATH}/utils/*.c ${KRKR2CORE_PATH}/utils/*.cpp ${KRKR2CORE_PATH}/utils/encoding/*.c ${KRKR2CORE_PATH}/utils/minizip/*.c ${KRKR2CORE_PATH}/utils/minizip/*.cpp ${KRKR2CORE_PATH}/utils/win32/*.cpp ${KRKR2CORE_PATH}/visual/gl/*.cpp ${KRKR2CORE_PATH}/visual/ogl/*.cpp ${KRKR2CORE_PATH}/visual/win32/*.cpp ) file(GLOB KRKR2CORE_CODEANDROID ${KRKR2CORE_PATH}/environ/android/*.cpp ${KRKR2CORE_PATH}/sound/ARM/*.c ${KRKR2CORE_PATH}/sound/ARM/*.cpp ${KRKR2CORE_PATH}/visual/ARM/*.cpp ${KRKR2CORE_PATH}/visual/ARM/*.c ) list(REMOVE_ITEM KRKR2CORE_CODE ${KRKR2CORE_PATH}/base/win32/FuncStubs.cpp ${KRKR2CORE_PATH}/base/win32/SusieArchive.cpp ${KRKR2CORE_PATH}/environ/MainFormUnit.cpp ${KRKR2CORE_PATH}/environ/XP3ArchiveRepack.cpp ${KRKR2CORE_PATH}/environ/ui/XP3RepackForm.cpp ${KRKR2CORE_PATH}/sound/xmmlib.cpp ${KRKR2CORE_PATH}/sound/WaveFormatConverter_SSE.cpp ${KRKR2CORE_PATH}/visual/Resampler.cpp ${KRKR2CORE_PATH}/visual/win32/GDIFontRasterizer.cpp ${KRKR2CORE_PATH}/visual/win32/NativeFreeTypeFace.cpp ${KRKR2CORE_PATH}/visual/win32/TVPSysFont.cpp ${KRKR2CORE_PATH}/visual/win32/VSyncTimingThread.cpp ${KRKR2CORE_PATH}/visual/LoadJXR.cpp ${KRKR2CORE_PATH}/visual/LoadBPG.cpp ) if(CMAKE_SYSTEM_NAME MATCHES "Android") list(APPEND KRKR2CORE_CODE ${KRKR2CORE_CODEANDROID}) set(PLATFORM android) elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") set(PLATFORM linux) elseif(CMAKE_SYSTEM_NAME MATCHES "Windows") set(PLATFORM win32) else() set(PLATFORM android) endif() # make krkr2core add_library(${PROJECT_NAME} STATIC ${KRKR2CORE_CODE}) if(CMAKE_SYSTEM_NAME MATCHES "Android") target_include_directories(${PROJECT_NAME} PUBLIC ${PORTBUILD_PATH}/sdk/native/jni/include ${CMAKE_ANDROID_NDK}/sources/android/cpufeatures ) target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,-Bdynamic log android EGL GLESv2 GLESv1_CM OpenSLES ) endif() target_include_directories(${PROJECT_NAME} PUBLIC ${KRKR2CORE_PATH}/ ${KRKR2CORE_PATH}/base ${KRKR2CORE_PATH}/base/win32 ${KRKR2CORE_PATH}/environ ${KRKR2CORE_PATH}/environ/win32 ${KRKR2CORE_PATH}/environ/android ${KRKR2CORE_PATH}/environ/sdl ${KRKR2CORE_PATH}/msg ${KRKR2CORE_PATH}/msg/win32 ${KRKR2CORE_PATH}/extension ${KRKR2CORE_PATH}/sound ${KRKR2CORE_PATH}/sound/win32 ${KRKR2CORE_PATH}/tjs2 ${KRKR2CORE_PATH}/utils ${KRKR2CORE_PATH}/utils/win32 ${KRKR2CORE_PATH}/visual ${KRKR2CORE_PATH}/visual/ARM ${KRKR2CORE_PATH}/visual/win32 ${KRKR2CORE_PATH}/visual/RenderScript/rs ${KRKR2CORE_PATH}/../plugins ${COCOS2DX_PATH} ${COCOS2DX_PATH}/cocos ${COCOS2DX_PATH}/cocos/scripting ${COCOS2DX_PATH}/cocos/editor-support ${COCOS2DX_PATH}/extensions ${COCOS2DX_PATH}/external ${COCOS2DX_PATH}/external/png/include/${PLATFORM} ${COCOS2DX_PATH}/external/webp/include/${PLATFORM} ${COCOS2DX_PATH}/external/freetype2/include/${PLATFORM} ${COCOS2DX_PATH}/external/freetype2/include/${PLATFORM}/freetype2 ${PORTBUILD_PATH}/include ) target_compile_definitions(${PROJECT_NAME} PUBLIC -DTJS_TEXT_OUT_CRLF -D__STDC_CONSTANT_MACROS -DUSE_UNICODE_FSTRING -DTJS_TEXT_OUT_CRLF -D_7ZIP_ST ) target_compile_options(${PROJECT_NAME} PUBLIC -fPIC ) target_link_directories(${PROJECT_NAME} PUBLIC ${PORTBUILD_PATH}/lib ) target_link_libraries(${PROJECT_NAME} PUBLIC -Wl,-Bstatic # audio ogg_static opus_static vorbis_static vorbisfile_static vorbisenc_static opusfile_static oboe openal_static # image jpeg_static opencv_imgproc opencv_core tegra_hal # video avutil_static avfilter_static avformat_static avcodec_static swscale_static swresample_static # archive unrar lz4 archive_static # libbpg_static jxrlib_static 7za # others onig_static breakpad breakpad_client # framework sdl2_static cocos2d ext_unzip ext_tinyxml2 ext_xxhash ext_edtaa3func ext_poly2tri ext_recast ext_clipper ext_convertUTF ext_pvmp3dec chipmunk BulletCollision BulletDynamics BulletMultiThreaded LinearMath MiniCL z png webp tiff freetype ) ================================================ FILE: src/core/base/7zArchive.cpp ================================================ #include "tjsCommHead.h" #include "StorageIntf.h" #include "UtilStreams.h" #include extern "C" { #include "p7zip/C/7z.h" #include "p7zip/C/7zFile.h" #include "p7zip/C/7zCrc.h" } #include "StorageImpl.h" static ISzAlloc allocImp = { [](void *p, size_t size) -> void *{ return malloc(size); }, [](void *p, void *addr) { free(addr); } }; class SevenZipStreamWrap { public: CSzArEx db; tTJSBinaryStream *_stream; CLookToRead lookStream; struct CSeekInStream : public ISeekInStream { SevenZipStreamWrap *Host; } archiveStream; public: SevenZipStreamWrap(tTJSBinaryStream * st) : _stream(st) { archiveStream.Host = this; archiveStream.Read = [](void *p, void *buf, size_t *size)->SRes {return ((CSeekInStream*)p)->Host->StreamRead(buf, size); }; archiveStream.Seek = [](void *p, Int64 *pos, ESzSeek origin)->SRes {return ((CSeekInStream*)p)->Host->StreamSeek(pos, origin); }; LookToRead_CreateVTable(&lookStream, false); lookStream.realStream = &archiveStream; SzArEx_Init(&db); if (!g_CrcTable[1]) CrcGenerateTable(); } ~SevenZipStreamWrap() { SzArEx_Free(&db, &allocImp); delete _stream; } SRes StreamRead(void *buf, size_t *size) { *size = _stream->Read(buf, *size); return SZ_OK; } SRes StreamSeek(Int64 *pos, ESzSeek origin) { tjs_int whence = TJS_BS_SEEK_SET; switch (origin) { case SZ_SEEK_CUR: whence = TJS_BS_SEEK_CUR; break; case SZ_SEEK_END: whence = TJS_BS_SEEK_END; break; case SZ_SEEK_SET: whence = TJS_BS_SEEK_SET; break; default: break; } *pos = _stream->Seek(*pos, whence); return SZ_OK; } }; class SevenZipArchive : public tTVPArchive, public SevenZipStreamWrap { std::vector > filelist; public: SevenZipArchive(const ttstr & name, tTJSBinaryStream *st) : tTVPArchive(name), SevenZipStreamWrap(st) { } virtual ~SevenZipArchive() { } virtual tjs_uint GetCount() { return filelist.size(); } virtual ttstr GetName(tjs_uint idx) { return filelist[idx].first; } virtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx) { tjs_uint fileIndex = filelist[idx].second; UInt64 fileSize = SzArEx_GetFileSize(&db, fileIndex); if (fileSize <= 0) return new tTVPMemoryStream(); UInt32 folderIndex = db.FileToFolder[fileIndex]; if (folderIndex == (UInt32)-1) return nullptr; const CSzAr *p = &db.db; CSzFolder folder; CSzData sd; const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; sd.Data = data; sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex]; if (SzGetNextFolderItem(&folder, &sd) != SZ_OK) return nullptr; if (folder.NumCoders == 1) { UInt64 startPos = db.dataPos; const UInt64 *packPositions = p->PackPositions + p->FoStartPackStreamIndex[folderIndex]; UInt64 offset = packPositions[0]; UInt64 inSize = packPositions[1] - offset; #define k_Copy 0 if (folder.Coders[0].MethodID == k_Copy && inSize == fileSize) { return new TArchiveStream(this, startPos + offset, inSize); } } UInt32 blockIndex; Byte *outBuffer = nullptr; size_t outBufferSize; size_t offset, outSizeProcessed; SRes res = SzArEx_Extract(&db, &lookStream.s, fileIndex, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocImp); tTVPMemoryStream *mem; if (offset == 0 && fileSize <= outBufferSize) { mem = new tTVPMemoryStream(outBuffer, outBufferSize); } else { Byte *buf = new Byte[fileSize]; memcpy(buf, outBuffer, fileSize); mem = new tTVPMemoryStream(buf, fileSize); delete outBuffer; } return mem; } bool Open(bool normalizeFileName) { SRes res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocImp); if (res != SZ_OK) { _stream = nullptr; return false; } for (int i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; bool isDir = SzArEx_IsDir(&db, i); if (isDir) continue; size_t len = SzArEx_GetFileNameUtf16(&db, i, NULL); ttstr filename; SzArEx_GetFileNameUtf16(&db, i, (UInt16*)filename.AllocBuffer(len)); filename.FixLen(); if (normalizeFileName) NormalizeInArchiveStorageName(filename); filelist.emplace_back(filename, i); } if (normalizeFileName) { std::sort(filelist.begin(), filelist.end(), [](const std::pair& a, const std::pair& b) { return a.first < b.first; }); } return true; } }; tTVPArchive * TVPOpen7ZArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) { tjs_uint64 pos = st->GetPosition(); bool checkZIP = st->ReadI16LE() == 0x7A37; // '7z' st->SetPosition(pos); if (!checkZIP) return nullptr; SevenZipArchive *arc = new SevenZipArchive(name, st); if (!arc->Open(normalizeFileName)) { delete arc; return nullptr; } return arc; } #if 0 void TVPUnpack7ZArchive(tTJSBinaryStream *st, ttstr outpath) { tjs_uint64 origpos = st->GetPosition(); SevenZipStreamWrap szsw(st); CSzArEx &db = szsw.db; SRes res = SzArEx_Open(&db, &szsw.lookStream.s, &allocImp, &allocImp); if (res != SZ_OK) return; outpath += TJS_W("/"); for (int i = 0; i < db.db.NumFolders; ++i) { ; } for (int i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; size_t len = SzArEx_GetFileNameUtf16(&db, i, NULL); ttstr filename; SzArEx_GetFileNameUtf16(&db, i, (UInt16*)filename.AllocBuffer(len)); filename.FixLen(); bool isDir = SzArEx_IsDir(&db, i); ttstr fullpath = outpath + filename; if (isDir) { if (!TVPCheckExistentLocalFolder(fullpath)) TVPCreateFolders(fullpath); } else { tjs_uint fileIndex = i; UInt64 fileSize = SzArEx_GetFileSize(&db, fileIndex); if (fileSize <= 0) { FILE *fp = fopen(fullpath.AsStdString().c_str(), "wb"); fclose(fp); } UInt32 folderIndex = db.FileToFolder[fileIndex]; if (folderIndex == (UInt32)-1) continue; const CSzAr *p = &db.db; CSzFolder folder; CSzData sd; const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; sd.Data = data; sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex]; if (SzGetNextFolderItem(&folder, &sd) != SZ_OK) continue; if (folder.NumCoders == 1) { UInt64 startPos = db.dataPos; const UInt64 *packPositions = p->PackPositions + p->FoStartPackStreamIndex[folderIndex]; UInt64 offset = packPositions[0]; UInt64 inSize = packPositions[1] - offset; if (folder.Coders[0].MethodID == k_Copy && inSize == fileSize) { CopyStreamToFile(st, origpos + startPos + offset, inSize, fullpath); continue; } } UInt32 blockIndex; Byte *outBuffer = nullptr; size_t outBufferSize; size_t offset, outSizeProcessed; SRes res = SzArEx_Extract(&db, &szsw.lookStream.s, fileIndex, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &allocImp, &allocImp); tTVPMemoryStream *mem; if (offset == 0 && fileSize <= outBufferSize) { mem = new tTVPMemoryStream(outBuffer, outBufferSize); } else { Byte *buf = new Byte[fileSize]; memcpy(buf, outBuffer, fileSize); mem = new tTVPMemoryStream(buf, fileSize); delete outBuffer; } return mem; } } } #endif ================================================ FILE: src/core/base/BinaryStream.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Text read/write stream //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include #include "TextStream.h" #include "MsgIntf.h" #include "DebugIntf.h" #include "EventIntf.h" #include "UtilStreams.h" #include "tjsError.h" /* Text stream is used by TJS's Array.saveStruct, Dictionary.saveStruct etc. to input/output binary files. */ //--------------------------------------------------------------------------- tTJSBinaryStream * TVPCreateBinaryStreamForRead(const ttstr & name, const ttstr & modestr) { // check o mode tTJSBinaryStream* stream = TVPCreateStream(name, TJS_BS_READ); const tjs_char* o_ofs = TJS_strchr(modestr.c_str(), TJS_W('o')); if(o_ofs != NULL) { // seek to offset o_ofs++; tjs_char buf[256]; int i; for(i = 0; i < 255; i++) { if(o_ofs[i] >= TJS_W('0') && o_ofs[i] <= TJS_W('9')) buf[i] = o_ofs[i]; else break; } buf[i] = 0; tjs_uint64 ofs = ttstr(buf).AsInteger(); stream->SetPosition(ofs); } return stream; } //--------------------------------------------------------------------------- tTJSBinaryStream * TVPCreateBinaryStreamForWrite(const ttstr & name, const ttstr & modestr) { tTJSBinaryStream* stream; // check o mode const tjs_char * o_ofs; o_ofs = TJS_strchr(modestr.c_str(), TJS_W('o')); if(o_ofs != NULL) { // seek to offset o_ofs++; tjs_char buf[256]; int i; for(i = 0; i < 255; i++) { if(o_ofs[i] >= TJS_W('0') && o_ofs[i] <= TJS_W('9')) buf[i] = o_ofs[i]; else break; } buf[i] = 0; tjs_uint64 ofs = ttstr(buf).AsInteger(); stream = TVPCreateStream(name, TJS_BS_UPDATE); stream->SetPosition(ofs); } else { stream = TVPCreateStream(name, TJS_BS_WRITE); } return stream; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/BinaryStream.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Text read/write stream //--------------------------------------------------------------------------- #ifndef BinaryStreamH #define BinaryStreamH #include "StorageIntf.h" //--------------------------------------------------------------------------- // BinaryStream Functions //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(tTJSBinaryStream *, TVPCreateBinaryStreamForRead, (const ttstr &name, const ttstr &modestr)); TJS_EXP_FUNC_DEF(tTJSBinaryStream *, TVPCreateBinaryStreamForWrite, (const ttstr &name, const ttstr &modestr)); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/CharacterSet.cpp ================================================ //--------------------------------------------------------------------------- /* 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" #include "MsgIntf.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; } #if 1 else { TVPThrowExceptionMessage(TJS_W("Out of UTF-16 range conversion from UTF-8 code")); } #else // ȉIWĩR[hǁAʂȂ͂B 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; } #endif 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; } //--------------------------------------------------------------------------- tjs_int TVPUtf8ToWideCharString(const char * in, tjs_uint length, tjs_char *out) { // convert input utf-8 string to output wide string int count = 0; const char *end = in + length; while(*in && in < end) { if(in + 6 > end) { // fetch utf-8 character length const unsigned char ch = *(const unsigned char *)in; if(ch >= 0x80) { tjs_uint len = 0; if(ch < 0xc2) return -1; else if(ch < 0xe0) len = 2; else if(ch < 0xf0) len = 3; else if(ch < 0xf8) len = 4; else if(ch < 0xfc) len = 5; else if(ch < 0xfe) len = 6; else return -1; if(in + len > end) return -1; } } 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; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/CharacterSet.h ================================================ //--------------------------------------------------------------------------- /* 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)); extern tjs_int TVPUtf8ToWideCharString(const char * in, tjs_uint length, tjs_char *out); #endif ================================================ FILE: src/core/base/EventIntf.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Script/Window Event Handling and Dispatching / System Idle Event Delivering //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include #include "SysInitIntf.h" #include "EventIntf.h" #include "WindowIntf.h" #include "tjsDictionary.h" #include "MsgIntf.h" #include "ScriptMgnIntf.h" #include "TickCount.h" #include "SystemImpl.h" //--------------------------------------------------------------------------- // tTVPEvent : script event class //--------------------------------------------------------------------------- extern tjs_uint64 TVPEventSequenceNumber; class tTVPEvent { iTJSDispatch2 *Target; iTJSDispatch2 *Source; ttstr EventName; tjs_uint32 Tag; tjs_uint NumArgs; tTJSVariant *Args; tjs_uint32 Flags; tjs_uint64 Sequence; public: tTVPEvent(iTJSDispatch2 *target, iTJSDispatch2 *source, ttstr &eventname, tjs_uint32 tag, tjs_uint numargs, tTJSVariant *args, tjs_uint32 flags) { // constructor // eventname is not a const object but this object only touch to // eventname.GetHint() Args = NULL; Target = NULL; Source = NULL; Sequence = TVPEventSequenceNumber; EventName = eventname; NumArgs = numargs; Args = new tTJSVariant[NumArgs]; for(tjs_uint i=0; iAddRef(); if(Source) Source->AddRef(); } tTVPEvent(const tTVPEvent &ref) { // copy constructor Args = NULL; Target = NULL; Source = NULL; EventName = ref.EventName; NumArgs = ref.NumArgs; Args = new tTJSVariant[NumArgs]; for(tjs_uint i=0; iAddRef(); if(Source) Source->AddRef(); } ~tTVPEvent() { if(Args) delete [] Args; if(Target) Target->Release(); if(Source) Source->Release(); } void Deliver() { if(!TJSIsObjectValid(Target->IsValid(0, NULL, NULL, Target))) return; // The target had been invalidated tTJSVariant **ArgsPtr = new tTJSVariant*[NumArgs]; for(tjs_uint i=0; iFuncCall(0, EventName.c_str(), EventName.GetHint(), NULL, NumArgs, ArgsPtr, Target); } catch(...) { delete [] ArgsPtr; throw; } delete [] ArgsPtr; } iTJSDispatch2 * GetTargetNoAddRef() const { return Target; } iTJSDispatch2 * GetSourceNoAddRef() const { return Source; } ttstr & GetEventName() { return EventName; } tjs_uint32 GetTag() const { return Tag; } tjs_uint32 GetFlags() const { return Flags; } tjs_uint64 GetSequence() const; }; //--------------------------------------------------------------------------- tjs_uint64 tTVPEvent::GetSequence() const { return Sequence; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPWinUpdateEvent : window update event class //--------------------------------------------------------------------------- class tTVPWinUpdateEvent { tTJSNI_BaseWindow *Window; public: tTVPWinUpdateEvent(tTJSNI_BaseWindow *window) { Window = window; } tTVPWinUpdateEvent(const tTVPWinUpdateEvent & ref) { Window = ref.Window; } ~tTVPWinUpdateEvent() { } void Deliver() const { if (static_cast(Window)->GetVisible()) Window->UpdateContent(); } tTJSNI_BaseWindow * GetWindow() const { return Window; } void MarkEmpty() { Window = NULL; } bool IsEmpty() const { return Window == NULL; } }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // global/static definitions //--------------------------------------------------------------------------- // event queue must be a globally sequential queue std::vector TVPInputEventQueue; std::vector TVPEventQueue; std::vector TVPWinUpdateEventQueue; bool TVPExclusiveEventPosted = false; // true if exclusive event is posted tjs_uint64 TVPEventSequenceNumber = 0; // event sequence number tjs_uint64 TVPEventSequenceNumberToProcess = 0; // current event sequence which must be processed static void TVPDestroyEventQueue() { // delete all event objects // deletion of event object may cause other deletion of event objects. { std::vector::iterator i; while(TVPEventQueue.size()) { i = TVPEventQueue.end() -1; tTVPEvent * ev = *i; TVPEventQueue.erase(i); delete ev; } } //-- { std::vector::iterator i; while(TVPInputEventQueue.size()) { i = TVPInputEventQueue.end() - 1; tTVPBaseInputEvent * ev = *i; TVPInputEventQueue.erase(i); delete ev; } } } static tTVPAtExit TVPDestroyEventQueueAtExit (TVP_ATEXIT_PRI_PREPARE, TVPDestroyEventQueue); bool TVPEventDisabled = false; bool TVPEventInterrupting = false; //#define TVP_EVENT_TASK_RETURN_TICK 100000 /* TVP event system once returns to Operation system when TVP_EVENT_TASK_RETURN_TICK is elapsed during event delivering. */ //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPPostEvent //--------------------------------------------------------------------------- void TVPPostEvent(iTJSDispatch2 * source, iTJSDispatch2 *target, ttstr &eventname, tjs_uint32 tag, tjs_uint32 flag, tjs_uint numargs, tTJSVariant *args) { bool evdisabled = TVPEventDisabled || TVPGetSystemEventDisabledState(); if((flag & TVP_EPT_DISCARDABLE) && (TVPEventInterrupting || evdisabled)) return; tjs_int method = flag & TVP_EPT_METHOD_MASK; if(method == TVP_EPT_IMMEDIATE) { // the event is delivered immediately if(evdisabled) return; try { try { tTVPEvent(target, source, eventname, tag, numargs, args, flag). Deliver(); } TJS_CONVERT_TO_TJS_EXCEPTION } TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W("immediate event")); return; } if(method == TVP_EPT_REMOVE_POST) { // events in queue that have same target/source/name/tag are to be removed std::vector::iterator i; i = TVPEventQueue.begin(); while(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end()) { if(source == (*i)->GetSourceNoAddRef() && target == (*i)->GetTargetNoAddRef() && eventname == (*i)->GetEventName() && ((tag==0)?true:(tag==(*i)->GetTag())) ) { tTVPEvent *ev = *i; TVPEventQueue.erase(i); i = TVPEventQueue.begin(); delete ev; } else { i++; } } } // put into queue TVPEventQueue.push_back(new tTVPEvent(target, source, eventname, tag, numargs, args, flag)); // is exclusive? if((flag & TVP_EPT_PRIO_MASK) == TVP_EPT_EXCLUSIVE) TVPExclusiveEventPosted = true; // make sure that the event is to be delivered. TVPInvokeEvents(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCancelEvents //--------------------------------------------------------------------------- tjs_int TVPCancelEvents(iTJSDispatch2 * source, iTJSDispatch2 *target, const ttstr &eventname, tjs_uint32 tag) { tjs_int count = 0; std::vector::iterator i; i = TVPEventQueue.begin(); while(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end()) { if(source == (*i)->GetSourceNoAddRef() && target == (*i)->GetTargetNoAddRef() && eventname == (*i)->GetEventName() && ((tag==0)?true:(tag==(*i)->GetTag())) ) { tTVPEvent *ev = *i; TVPEventQueue.erase(i); i = TVPEventQueue.begin(); delete ev; count ++; } else { i++; } } return count; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPAreEventsInQueue //--------------------------------------------------------------------------- bool TVPAreEventsInQueue(iTJSDispatch2 * source, iTJSDispatch2 *target, const ttstr &eventname, tjs_uint32 tag) { std::vector::iterator i; i = TVPEventQueue.begin(); while(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end()) { if(source == (*i)->GetSourceNoAddRef() && target == (*i)->GetTargetNoAddRef() && eventname == (*i)->GetEventName() && ((tag==0)?true:(tag==(*i)->GetTag())) ) return true; i++; } return false; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCountEventsInQueue //--------------------------------------------------------------------------- tjs_int TVPCountEventsInQueue(iTJSDispatch2 * source, iTJSDispatch2 *target, const ttstr &eventname, tjs_uint32 tag) { tjs_int count = 0; std::vector::iterator i; i = TVPEventQueue.begin(); while(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end()) { if(source == (*i)->GetSourceNoAddRef() && target == (*i)->GetTargetNoAddRef() && eventname == (*i)->GetEventName() && ((tag==0)?true:(tag==(*i)->GetTag())) ) count ++; i++; } return count; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCancelEventByTag //--------------------------------------------------------------------------- void TVPCancelEventsByTag(iTJSDispatch2 * source, iTJSDispatch2 *target, tjs_uint32 tag) { std::vector::iterator i; i = TVPEventQueue.begin(); while(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end()) { if(source == (*i)->GetSourceNoAddRef() && target == (*i)->GetTargetNoAddRef() && ((tag==0)?true:(tag==(*i)->GetTag())) ) { tTVPEvent *ev = *i; TVPEventQueue.erase(i); i = TVPEventQueue.begin(); delete ev; } else { i++; } } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCancelSourceEvent //--------------------------------------------------------------------------- void TVPCancelSourceEvents(iTJSDispatch2 * source) { std::vector::iterator i; i = TVPEventQueue.begin(); while(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end()) { if(source == (*i)->GetSourceNoAddRef()) { tTVPEvent *ev = *i; TVPEventQueue.erase(i); i = TVPEventQueue.begin(); delete ev; } else { i++; } } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPDiscardAllDiscardableEvents //--------------------------------------------------------------------------- void TVPDiscardAllDiscardableEvents() { std::vector::iterator i; i = TVPEventQueue.begin(); while(/*TVPEventQueue.size() &&*/ i != TVPEventQueue.end()) { if((*i)->GetFlags() & TVP_EPT_DISCARDABLE) { tTVPEvent *ev = *i; TVPEventQueue.erase(i); i = TVPEventQueue.begin(); delete ev; } else { i++; } } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPDeliverAllEvents //--------------------------------------------------------------------------- static void _TVPDeliverEventByPrio(tjs_uint prio) { while(true) { tTVPEvent *e; // retrieve item to deliver if(TVPEventQueue.size() == 0) break; std::vector::iterator i = TVPEventQueue.begin(); while(i != TVPEventQueue.end()) { if((*i)->GetSequence() <= TVPEventSequenceNumberToProcess && (((*i)->GetFlags() & TVP_EPT_PRIO_MASK) == prio)) break; i++; } if(i == TVPEventQueue.end()) break; e = *i; TVPEventQueue.erase(i); // event delivering try { e->Deliver(); } catch(...) { delete e; throw; } delete e; } } static bool _TVPDeliverAllEvents2() { TVPExclusiveEventPosted = false; // process exclusive events _TVPDeliverEventByPrio(TVP_EPT_EXCLUSIVE); // check exclusive events if(TVPExclusiveEventPosted) return true; // process input event queue while(true) { tTVPBaseInputEvent *e; // retrieve item to deliver if(TVPInputEventQueue.size() == 0) break; std::vector::iterator i = TVPInputEventQueue.begin(); e = *i; TVPInputEventQueue.erase(i); // event delivering try { e->Deliver(); } catch(...) { delete e; throw; } delete e; // check exclusive events if(TVPExclusiveEventPosted) return true; } // process normal event queue _TVPDeliverEventByPrio(TVP_EPT_NORMAL); // check exclusive events if(TVPExclusiveEventPosted) return true; return true; } //--------------------------------------------------------------------------- static bool _TVPDeliverAllEvents() { // deliver all pending events to targets. if(TVPEventDisabled) return true; // event invokation was received... TVPEventReceived(); // for script event objects bool ret_value; ret_value = _TVPDeliverAllEvents2(); return ret_value; } //--------------------------------------------------------------------------- void TVPDeliverAllEvents() { bool r; if(!TVPEventInterrupting) { TVPEventSequenceNumberToProcess = TVPEventSequenceNumber; TVPEventSequenceNumber ++; // increment sequence number } TVPEventInterrupting = false; try { try { r = _TVPDeliverAllEvents(); } TJS_CONVERT_TO_TJS_EXCEPTION } TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W("event")); if(!r) { // event processing is to be interrupted // XXX: currently this is not functional TVPEventInterrupting = true; TVPCallDeliverAllEventsOnIdle(); } if(!TVPExclusiveEventPosted && !TVPEventInterrupting) { try { try { // process idle event queue _TVPDeliverEventByPrio(TVP_EPT_IDLE); } TJS_CONVERT_TO_TJS_EXCEPTION } TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W("idle event")); // process continuous events if(TVPProcessContinuousHandlerEventFlag) { TVPProcessContinuousHandlerEventFlag = false; // processed // XXX: strictly saying, we need something like InterlockedExchange // to look/set this flag, because TVPProcessContinuousHandlerEventFlag // may be accessed by another thread. But I have no dought about // that no one does care of missing one event in rare race condition. TVPDeliverContinuousEvent(); } try { try { // for window content updating TVPDeliverWindowUpdateEvents(); } TJS_CONVERT_TO_TJS_EXCEPTION } TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W("window update")); } else { } if(TVPEventQueue.size() == 0) { TVPEventSequenceNumber = 0; // reset the number } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPPostWindowUpdate //--------------------------------------------------------------------------- bool TVPWindowUpdateEventsDelivering = false; void TVPPostWindowUpdate(tTJSNI_BaseWindow *window) { if(!TVPWindowUpdateEventsDelivering) { if(TVPWinUpdateEventQueue.size()) { // since duplication is not allowed ... std::vector::const_iterator i; for(i = TVPWinUpdateEventQueue.begin(); i !=TVPWinUpdateEventQueue.end(); i++) { if(!i->IsEmpty() && window == i->GetWindow()) return; } } } else { if(TVPWinUpdateEventQueue.size()) { // duplication is allowed up to two tjs_int count = 0; std::vector::const_iterator i; for(i = TVPWinUpdateEventQueue.begin(); i !=TVPWinUpdateEventQueue.end(); i++) { if(!i->IsEmpty() && window == i->GetWindow()) { count++; if(count == 2) return; } } } } // put into queue. TVPWinUpdateEventQueue.emplace_back(window); // make sure that the event is to be delivered. TVPInvokeEvents(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPRemoveWindowUpdate //--------------------------------------------------------------------------- void TVPRemoveWindowUpdate(tTJSNI_BaseWindow *window) { // removes all window update events from queue. if(TVPWinUpdateEventQueue.size()) { std::vector::iterator i; for(i = TVPWinUpdateEventQueue.begin(); i !=TVPWinUpdateEventQueue.end(); i++) { if(!i->IsEmpty() && window == i->GetWindow()) i->MarkEmpty(); } } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPDeliverWindowUpdateEvents //--------------------------------------------------------------------------- void TVPDeliverWindowUpdateEvents() { if(TVPWindowUpdateEventsDelivering) return; // does not allow re-entering TVPWindowUpdateEventsDelivering = true; try { for(tjs_uint i = 0; i < TVPWinUpdateEventQueue.size(); i++) { if(!TVPWinUpdateEventQueue[i].IsEmpty()) TVPWinUpdateEventQueue[i].Deliver(); } } catch(...) { TVPWinUpdateEventQueue.clear(); TVPWindowUpdateEventsDelivering = false; throw; } TVPWinUpdateEventQueue.clear(); TVPWindowUpdateEventsDelivering = false; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Input Event related //--------------------------------------------------------------------------- tjs_int TVPInputEventTagMax = 0; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPPostInputEvent //--------------------------------------------------------------------------- void TVPPostInputEvent(tTVPBaseInputEvent *ev, tjs_uint32 flags) { // flag check if((flags & TVP_EPT_DISCARDABLE) && (TVPEventDisabled || TVPGetSystemEventDisabledState())) { delete ev; return; } if(flags & TVP_EPT_REMOVE_POST) { // cancel previously posted events TVPCancelInputEvents(ev->GetSource(), ev->GetTag()); } // push into the event queue TVPInputEventQueue.push_back(ev); // make sure that the event is to be delivered. TVPInvokeEvents(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCancelInputEvents //--------------------------------------------------------------------------- void TVPCancelInputEvents(void * source) { // removes all evens which have the same source if(TVPInputEventQueue.size()) { std::vector::iterator i; for(i = TVPInputEventQueue.begin(); i !=TVPInputEventQueue.end();) { if(source == (*i)->GetSource()) { tTVPBaseInputEvent *ev = *i; i = TVPInputEventQueue.erase(i); delete ev; } else { i++; } } } } //--------------------------------------------------------------------------- void TVPCancelInputEvents(void * source, tjs_int tag) { // removes all evens which have the same source and the same tag if(TVPInputEventQueue.size()) { std::vector::iterator i; for(i = TVPInputEventQueue.begin(); i !=TVPInputEventQueue.end();) { if(source == (*i)->GetSource() && tag == (*i)->GetTag()) { tTVPBaseInputEvent *ev = *i; i = TVPInputEventQueue.erase(i); delete ev; } else { i++; } } } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetInputEventCount //--------------------------------------------------------------------------- tjs_int TVPGetInputEventCount() { return (tjs_int)TVPInputEventQueue.size(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCreateEventObject //--------------------------------------------------------------------------- iTJSDispatch2 * TVPCreateEventObject(const tjs_char *type, iTJSDispatch2 *targthis, iTJSDispatch2 *targ) { // create a dictionary object for event dispatching ( to "action" method ) iTJSDispatch2 * object = TJSCreateDictionaryObject(); static ttstr type_name(TJS_W("type")); static ttstr target_name(TJS_W("target")); { tTJSVariant val(type); if(TJS_FAILED(object->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, type_name.c_str(), type_name.GetHint(), &val, object))) TVPThrowInternalError; } { tTJSVariant val(targthis, targ); if(TJS_FAILED(object->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, target_name.c_str(), target_name.GetHint(), &val, object))) TVPThrowInternalError; } return object; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- ttstr TVPActionName(TJS_W("action")); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Continuous Event Delivering related //--------------------------------------------------------------------------- bool TVPProcessContinuousHandlerEventFlag = false; static std::vector TVPContinuousEventVector; static std::vector TVPContinuousHandlerVector; static bool TVPContinuousEventProcessing = false; static void TVPDestroyContinuousHandlerVector() { std::vector::iterator i; for(i = TVPContinuousHandlerVector.begin(); i != TVPContinuousHandlerVector.end(); i++) { i->Release(); } TVPContinuousHandlerVector.clear(); } static tTVPAtExit TVPDestroyContinuousHandlerVectorAtExit (TVP_ATEXIT_PRI_PREPARE, TVPDestroyContinuousHandlerVector); //--------------------------------------------------------------------------- void TVPAddContinuousEventHook(tTVPContinuousEventCallbackIntf *cb) { TVPBeginContinuousEvent(); TVPContinuousEventVector.push_back(cb); } //--------------------------------------------------------------------------- void TVPRemoveContinuousEventHook(tTVPContinuousEventCallbackIntf *cb) { std::vector::iterator i; for(i = TVPContinuousEventVector.begin(); i !=TVPContinuousEventVector.end();) { if(cb == *i) *i = NULL; // simply assign a null i++; } } //--------------------------------------------------------------------------- static void _TVPDeliverContinuousEvent() // internal { TVPStartTickCount(); tjs_uint64 tick = TVPGetTickCount(); if(TVPContinuousEventVector.size()) { bool emptyflag = false; for(tjs_uint32 i = 0; i < TVPContinuousEventVector.size(); i++) { // note that the handler can remove itself while the event if(TVPContinuousEventVector[i]) TVPContinuousEventVector[i]->OnContinuousCallback(tick); else emptyflag = true; if(TVPExclusiveEventPosted) return; // check exclusive events } if(emptyflag) { // the array has empty cell // eliminate empty std::vector::iterator i; for(i = TVPContinuousEventVector.begin(); i !=TVPContinuousEventVector.end();) { if(*i == NULL) i = TVPContinuousEventVector.erase(i); else i++; } } } if(!TVPEventDisabled && TVPContinuousHandlerVector.size()) { bool emptyflag = false; tTJSVariant vtick((tjs_int64)tick); tTJSVariant *pvtick = &vtick; for(tjs_uint i = 0; i < TVPContinuousHandlerVector.size(); i++) { if(TVPContinuousHandlerVector[i].Object) { tjs_error er; try { er = TVPContinuousHandlerVector[i].FuncCall(0, NULL, NULL, NULL, 1, &pvtick, NULL); } catch(...) { // failed TVPContinuousHandlerVector[i].Release(); TVPContinuousHandlerVector[i].Object = TVPContinuousHandlerVector[i].ObjThis = NULL; throw; } if(TJS_FAILED(er)) { // failed TVPContinuousHandlerVector[i].Release(); TVPContinuousHandlerVector[i].Object = TVPContinuousHandlerVector[i].ObjThis = NULL; emptyflag = true; } if(TVPExclusiveEventPosted) return; // check exclusive events } else { emptyflag = true; } } if(emptyflag) { // the array has empty cell // eliminate empty std::vector::iterator i; for(i = TVPContinuousHandlerVector.begin(); i !=TVPContinuousHandlerVector.end();) { if(!i->Object) { i->Release(); i = TVPContinuousHandlerVector.erase(i); } else { i++; } } } } if(!TVPContinuousEventVector.size() && !TVPContinuousHandlerVector.size()) TVPEndContinuousEvent(); } //--------------------------------------------------------------------------- void TVPDeliverContinuousEvent() { if(TVPContinuousEventProcessing) return; TVPContinuousEventProcessing = true; try { try { try { _TVPDeliverContinuousEvent(); } catch(...) { TVPContinuousEventProcessing = false; throw; } } TJS_CONVERT_TO_TJS_EXCEPTION } TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W("continuous event")); TVPContinuousEventProcessing = false; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void TVPAddContinuousHandler(tTJSVariantClosure clo) { std::vector::iterator i; i = std::find(TVPContinuousHandlerVector.begin(), TVPContinuousHandlerVector.end(), clo); if(i == TVPContinuousHandlerVector.end()) { TVPBeginContinuousEvent(); clo.AddRef(); TVPContinuousHandlerVector.emplace_back(clo); } } //--------------------------------------------------------------------------- void TVPRemoveContinuousHandler(tTJSVariantClosure clo) { std::vector::iterator i; i = std::find(TVPContinuousHandlerVector.begin(), TVPContinuousHandlerVector.end(), clo); if(i != TVPContinuousHandlerVector.end()) { i->Release(); i->Object = i->ObjThis = NULL; } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // "Compact" Event Delivering related //--------------------------------------------------------------------------- // Compact events are to be delivered when: // 1. the application is in idle state for long duration // 2. the application had been deactivated ( application has lost the focus ) // 3. the application had been minimized // these are to reduce memory usage, like garbage collection, cache cleaning, // or etc ... //--------------------------------------------------------------------------- static std::vector TVPCompactEventVector; bool TVPEnableGlobalHeapCompaction = false; //--------------------------------------------------------------------------- void TVPAddCompactEventHook(tTVPCompactEventCallbackIntf *cb) { TVPCompactEventVector.push_back(cb); } //--------------------------------------------------------------------------- void TVPRemoveCompactEventHook(tTVPCompactEventCallbackIntf *cb) { std::vector::iterator i; for(i = TVPCompactEventVector.begin(); i !=TVPCompactEventVector.end();) { if(cb == *i) *i = NULL; // simply assign a null i++; } } //--------------------------------------------------------------------------- extern void TVPDoSaveSystemVariables(); void TVPDeliverCompactEvent(tjs_int level) { // must be called by each platforms's implementation //std::vector::iterator i; if(TVPCompactEventVector.size()) { bool emptyflag = false; for(tjs_uint i = 0; i < TVPCompactEventVector.size(); i ++) { // note that the handler can remove itself while the event try { try { if(TVPCompactEventVector[i]) TVPCompactEventVector[i]->OnCompact(level); else emptyflag = true; } TJS_CONVERT_TO_TJS_EXCEPTION } TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION_FORCE_SHOW_EXCEPTION(TJS_W("Compact Event")); } if(emptyflag) { // the array has empty cell // eliminate empty std::vector::iterator i; for(i = TVPCompactEventVector.begin(); i !=TVPCompactEventVector.end();) { if(*i == NULL) i = TVPCompactEventVector.erase(i); else i++; } } } TVPDoSaveSystemVariables(); #if 0 if( level >= TVP_COMPACT_LEVEL_MAX && TVPEnableGlobalHeapCompaction ) { // Do compact CRT and Global Heap HANDLE hHeap = ::GetProcessHeap(); if( hHeap ) { ::HeapCompact( hHeap, 0 ); } HANDLE hCrtHeap = (HANDLE)_get_heap_handle(); if( hCrtHeap && hCrtHeap != hHeap ) { ::HeapCompact( hCrtHeap, 0 ); } } #endif } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // AsyncTrigger related //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTJSNI_AsyncTrigger //--------------------------------------------------------------------------- tTJSNI_AsyncTrigger::tTJSNI_AsyncTrigger() { Owner = NULL; Cached = true; IdlePendingCount = 0; Mode = atmNormal; ActionOwner.Object = ActionOwner.ObjThis = NULL; ActionName = TVPActionName; } //--------------------------------------------------------------------------- tjs_error TJS_INTF_METHOD tTJSNI_AsyncTrigger::Construct(tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *tjs_obj) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; tjs_error hr = inherited::Construct(numparams, param, tjs_obj); if(TJS_FAILED(hr)) return hr; if(numparams >= 2 && param[1]->Type() != tvtVoid) ActionName = *param[1]; // action function to be called ActionOwner = param[0]->AsObjectClosure(); Owner = tjs_obj; return TJS_S_OK; } //--------------------------------------------------------------------------- void TJS_INTF_METHOD tTJSNI_AsyncTrigger::Invalidate() { TVPCancelSourceEvents(Owner); Owner = NULL; ActionOwner.Release(); ActionOwner.ObjThis = ActionOwner.Object = NULL; inherited::Invalidate(); } //--------------------------------------------------------------------------- void tTJSNI_AsyncTrigger::Trigger() { // trigger event if(Owner) { if(Cached) { // remove undelivered events from queue when "Cached" flag is set TVPCancelSourceEvents(Owner); } static ttstr eventname(TJS_W("onFire")); tjs_uint32 flags = TVP_EPT_POST; if(Mode == atmExclusive) flags |= TVP_EPT_EXCLUSIVE; // fire exclusive event if(Mode == atmAtIdle) flags |= TVP_EPT_IDLE; // fire idle event TVPPostEvent(Owner, Owner, eventname, 0, flags, 0, NULL); } } //--------------------------------------------------------------------------- void tTJSNI_AsyncTrigger::Cancel() { // cancel event if(Owner) TVPCancelSourceEvents(Owner); IdlePendingCount = 0; } //--------------------------------------------------------------------------- void tTJSNI_AsyncTrigger::SetCached(bool b) { // set cached operation flag. // when this flag is set, only one event is delivered at once. if(Cached != b) { Cached = b; Cancel(); // all events are canceled } } //--------------------------------------------------------------------------- void tTJSNI_AsyncTrigger::SetMode(tTVPAsyncTriggerMode m) { if(Mode != m) { Mode = m; Cancel(); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTJSNC_AsyncTrigger //--------------------------------------------------------------------------- tjs_uint32 tTJSNC_AsyncTrigger::ClassID = -1; tTJSNC_AsyncTrigger::tTJSNC_AsyncTrigger() : inherited(TJS_W("AsyncTrigger")) { // registration of native members TJS_BEGIN_NATIVE_MEMBERS(AsyncTrigger) // constructor TJS_DECL_EMPTY_FINALIZE_METHOD //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_CONSTRUCTOR_DECL(/*var.name*/_this, /*var.type*/tTJSNI_AsyncTrigger, /*TJS class name*/AsyncTrigger) { return TJS_S_OK; } TJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/AsyncTrigger) //---------------------------------------------------------------------- //-- methods //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/trigger) { TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger); _this->Trigger(); return TJS_S_OK; } TJS_END_NATIVE_METHOD_DECL(/*func. name*/trigger) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/cancel) { TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger); _this->Cancel(); return TJS_S_OK; } TJS_END_NATIVE_METHOD_DECL(/*func. name*/cancel) //---------------------------------------------------------------------- //-- events //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/onFire) { TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger); tTJSVariantClosure obj = _this->GetActionOwnerNoAddRef(); if(obj.Object) { ttstr & actionname = _this->GetActionName(); TVP_ACTION_INVOKE_BEGIN(0, "onFire", objthis); TVP_ACTION_INVOKE_END_NAME(obj, actionname.IsEmpty() ? NULL :actionname.c_str(), actionname.IsEmpty() ? NULL :actionname.GetHint()); } return TJS_S_OK; } TJS_END_NATIVE_METHOD_DECL(/*func. name*/onFire) //---------------------------------------------------------------------- //--properties //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(cached) { TJS_BEGIN_NATIVE_PROP_GETTER { TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger); *result = _this->GetCached(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_BEGIN_NATIVE_PROP_SETTER { TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger); _this->SetCached(*param); return TJS_S_OK; } TJS_END_NATIVE_PROP_SETTER } TJS_END_NATIVE_PROP_DECL(cached) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(mode) { TJS_BEGIN_NATIVE_PROP_GETTER { TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger); *result = (tjs_int)_this->GetMode(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_BEGIN_NATIVE_PROP_SETTER { TJS_GET_NATIVE_INSTANCE(/*var. name*/_this, /*var. type*/tTJSNI_AsyncTrigger); _this->SetMode((tTVPAsyncTriggerMode)(tjs_int)*param); return TJS_S_OK; } TJS_END_NATIVE_PROP_SETTER } TJS_END_NATIVE_PROP_DECL(mode) //---------------------------------------------------------------------- TJS_END_NATIVE_MEMBERS } //--------------------------------------------------------------------------- tTJSNativeInstance *tTJSNC_AsyncTrigger::CreateNativeInstance() { return new tTJSNI_AsyncTrigger(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- tTJSNativeClass * TVPCreateNativeClass_AsyncTrigger() { return new tTJSNC_AsyncTrigger(); } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/EventIntf.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Script Event/Window Handling and Dispatching / System Idle Event Delivering //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #ifndef EventIntfH #define EventIntfH #include "tjsNative.h" //--------------------------------------------------------------------------- // Event dispatching //--------------------------------------------------------------------------- extern void TVPDeliverAllEvents(); // called from (indirectly) the OS extern bool TVPEventDisabled; // do not write to this variable directly extern void TVPInvokeEvents(); // implement this in each platform, // to ensure calling "TVPDeliverAllEvents" when the Application is // ready to deliver the events. extern void TVPEventReceived(); // implement this in each platform. // notifies that events are delivered and ensure being ready for next event. extern void TVPCallDeliverAllEventsOnIdle(); // implement this in each platform. // once return control to OS, and set to call TVPInvokeEvents() after it. //--------------------------------------------------------------------------- // somewhat public TJS_EXP_FUNC_DEF(void, TVPBreathe, ()); // implement this in each platform // to handle OS's message events // this should be called when in a long time processing, something like a // network access, to reply to user's Windowing message, repainting, etc... // in TVPBreathe, TVP events must not be invoked. ( happened events over the // long time processing are pending until next timing of message delivering. ) TJS_EXP_FUNC_DEF(bool, TVPGetBreathing, ()); // return whether now is in event breathing TJS_EXP_FUNC_DEF(void, TVPSetSystemEventDisabledState, (bool en)); /* sets whether system overall event handling is enabled. this works distinctly from TVPEventDisabled. */ TJS_EXP_FUNC_DEF(bool, TVPGetSystemEventDisabledState, ()); //--------------------------------------------------------------------------- /*[*/ //--------------------------------------------------------------------------- // Script Event Related //--------------------------------------------------------------------------- #define TVP_EPT_POST 0x00 // normal post, simply add to queue #define TVP_EPT_REMOVE_POST 0x01 // remove event in pending queue that has same target, source, tag and // name before post // (for input events, only the source and the tag are to be checked) #define TVP_EPT_IMMEDIATE 0x02 // the event will be delivered immediately #define TVP_EPT_DISCARDABLE 0x10 // the event can be discarded when event system is disabled #define TVP_EPT_NORMAL 0x00 // (with TVP_EPT_POST only) // the event will have normal priority. #define TVP_EPT_EXCLUSIVE 0x20 // (with TVP_EPT_POST only) // the event is given priority and other posted events are not processed // until the exclusive event is processed. #define TVP_EPT_IDLE 0x40 // (with TVP_EPT_POST only) // the event is only delivered after the system processes all other events. // this will have a priority roughly identical to "continuous" events. #define TVP_EPT_PRIO_MASK 0xe0 #define TVP_EPT_METHOD_MASK 0x0f /*]*/ //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(void, TVPPostEvent, (iTJSDispatch2 * source, iTJSDispatch2 *target, ttstr &eventname, tjs_uint32 tag, tjs_uint32 flag, tjs_uint numargs, tTJSVariant *args)); // posts TVP event. this function itself is thread-safe. TJS_EXP_FUNC_DEF(tjs_int, TVPCancelEvents, (iTJSDispatch2 * source, iTJSDispatch2 *target, const ttstr &eventname, tjs_uint32 tag = 0)); // removes events that has specified source/target/name/tag. // tag == 0 removes all tag from queue. // returns count of removed events. TJS_EXP_FUNC_DEF(bool, TVPAreEventsInQueue, (iTJSDispatch2 * source, iTJSDispatch2 *target, const ttstr &eventname, tjs_uint32 tag)); // returns whether the events are in queue that have specified // source/target/name/tag. // tag == 0 matches all tag in queue. TJS_EXP_FUNC_DEF(tjs_int, TVPCountEventsInQueue, (iTJSDispatch2 * source, iTJSDispatch2 *target, const ttstr &eventname, tjs_uint32 tag)); // returns count of the events in queue that have specified // source/target/name/tag. // tag == 0 matches all tag in queue. TJS_EXP_FUNC_DEF(void, TVPCancelEventsByTag, (iTJSDispatch2 * source, iTJSDispatch2 *target, tjs_uint32 tag = 0)); // removes all events which have the same source/target/tag. // tag == 0 removes all tag from queue. TJS_EXP_FUNC_DEF(void, TVPCancelSourceEvents, (iTJSDispatch2 * source)); // removes all events that has specified source. //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Window update event related //--------------------------------------------------------------------------- class tTJSNI_BaseWindow; extern void TVPPostWindowUpdate(tTJSNI_BaseWindow *window); extern void TVPRemoveWindowUpdate(tTJSNI_BaseWindow *window); extern void TVPDeliverWindowUpdateEvents(); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // User input event related //--------------------------------------------------------------------------- class tTVPBaseInputEvent // base user input event class { void * Source; tjs_int Tag; public: tTVPBaseInputEvent(void *source, tjs_int tag) { Source = source; Tag = tag; } virtual ~tTVPBaseInputEvent() {}; virtual void Deliver() const = 0; void * GetSource() const { return Source; } tjs_int GetTag() const { return Tag; } }; //--------------------------------------------------------------------------- extern tjs_int TVPInputEventTagMax; class tTVPUniqueTagForInputEvent // a class for getting unique tag per a event class { public: tjs_int Tag; tTVPUniqueTagForInputEvent() : Tag(++TVPInputEventTagMax) {;} operator tjs_int() const { return Tag; } }; //--------------------------------------------------------------------------- extern void TVPPostInputEvent(tTVPBaseInputEvent *ev, tjs_uint32 flags = 0); extern void TVPCancelInputEvents(void * source); extern void TVPCancelInputEvents(void * source, tjs_int tag); extern tjs_int TVPGetInputEventCount(); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCreateEventObject //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(iTJSDispatch2 *, TVPCreateEventObject, (const tjs_char *type, iTJSDispatch2 *targthis, iTJSDispatch2 *targ)); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // some macros for driving "action" method //--------------------------------------------------------------------------- extern ttstr TVPActionName; #define TVP_ACTION_INVOKE_BEGIN(argnum, name, object) \ { \ if(numparams < (argnum)) return TJS_E_BADPARAMCOUNT; \ tjs_int arg_count = 0; \ iTJSDispatch2 *evobj = TVPCreateEventObject(TJS_W(name), (object), \ (object)); \ tTJSVariant evval(evobj, evobj); \ evobj->Release(); #define TVP_ACTION_INVOKE_MEMBER(name) \ {\ static ttstr member_name(TJS_W(name)); \ evobj->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, \ member_name.c_str(), member_name.GetHint(), param[arg_count++], \ evobj); \ } #define TVP_ACTION_INVOKE_END(object) \ tTJSVariant *pevval = &evval; \ (object).FuncCall(0, TVPActionName.c_str(), TVPActionName.GetHint(), \ result, 1, &pevval, NULL); \ } #define TVP_ACTION_INVOKE_END_NAME(object, name, hint) \ tTJSVariant *pevval = &evval; \ (object).FuncCall(0, (name), (hint), \ result, 1, &pevval, NULL); \ } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Continuous Event related //--------------------------------------------------------------------------- /*[*/ class tTVPContinuousEventCallbackIntf // callback class for continuous event delivering { public: virtual void TJS_INTF_METHOD OnContinuousCallback(tjs_uint64 tick) = 0; }; /*]*/ //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(void, TVPAddContinuousEventHook, (tTVPContinuousEventCallbackIntf *cb)); TJS_EXP_FUNC_DEF(void, TVPRemoveContinuousEventHook, (tTVPContinuousEventCallbackIntf *cb)); extern void TVPBeginContinuousEvent(); // must be implemented in each platforms // this must begin calling TVPDeliverContinuousEvent extern void TVPEndContinuousEvent(); // must be implemented in each platforms // this must stop calling TVPDeliverContinuousEvent extern void TVPDeliverContinuousEvent(); // must be called by each platforms's implementation extern void TVPAddContinuousHandler(tTJSVariantClosure clo); // add callback function written in TJS extern void TVPRemoveContinuousHandler(tTJSVariantClosure clo); // remove callback function added by TVPAddIdleHandler extern bool TVPProcessContinuousHandlerEventFlag; //--------------------------------------------------------------------------- /*[*/ //--------------------------------------------------------------------------- // System "Compact" Event related //--------------------------------------------------------------------------- #define TVP_COMPACT_LEVEL_IDLE 5 // the application is in idle state #define TVP_COMPACT_LEVEL_DEACTIVATE 10 // the application had been deactivated #define TVP_COMPACT_LEVEL_MINIMIZE 15 // the application had been minimized #define TVP_COMPACT_LEVEL_MAX 100 // strongest level, should clear all caches //--------------------------------------------------------------------------- class tTVPCompactEventCallbackIntf // callback class for compact event delivering { public: virtual void TJS_INTF_METHOD OnCompact(tjs_int level) = 0; }; /*]*/ //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(void, TVPAddCompactEventHook, (tTVPCompactEventCallbackIntf *cb)); TJS_EXP_FUNC_DEF(void, TVPRemoveCompactEventHook, (tTVPCompactEventCallbackIntf *cb)); extern void TVPDeliverCompactEvent(tjs_int level); // must be called by each platforms's implementation //--------------------------------------------------------------------------- /* AsyncTrigger is a class for invoking events at asynchronous. Script can trigger event but the event is not delivered immediately, is delivered at next event flush phase. */ /*[*/ //--------------------------------------------------------------------------- // AsyncTrigger related //--------------------------------------------------------------------------- enum tTVPAsyncTriggerMode { atmNormal, atmExclusive, atmAtIdle }; /*]*/ //--------------------------------------------------------------------------- // tTJSNI_AsyncTrigger : TJS AsyncTrigger native instance //--------------------------------------------------------------------------- class tTJSNI_AsyncTrigger : public tTJSNativeInstance { typedef tTJSNativeInstance inherited; protected: iTJSDispatch2 *Owner; tTJSVariantClosure ActionOwner; // object to send action ttstr ActionName; bool Cached; // cached operation tTVPAsyncTriggerMode Mode; // event mode tjs_int IdlePendingCount; public: tTJSNI_AsyncTrigger(); tjs_error TJS_INTF_METHOD Construct(tjs_int numparams, tTJSVariant **param, iTJSDispatch2 *tjs_obj); void TJS_INTF_METHOD Invalidate(); public: tTJSVariantClosure GetActionOwnerNoAddRef() const { return ActionOwner; } ttstr & GetActionName() { return ActionName; } void Trigger(); void Cancel(); bool GetCached() const { return Cached; } void SetCached(bool b); tTVPAsyncTriggerMode GetMode() const { return Mode; } void SetMode(tTVPAsyncTriggerMode m); }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTJSNC_AsyncTrigger : TJS AsyncTrigger class //--------------------------------------------------------------------------- class tTJSNC_AsyncTrigger : public tTJSNativeClass { typedef tTJSNativeClass inherited; public: tTJSNC_AsyncTrigger(); static tjs_uint32 ClassID; protected: tTJSNativeInstance *CreateNativeInstance(); }; //--------------------------------------------------------------------------- extern tTJSNativeClass * TVPCreateNativeClass_AsyncTrigger(); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/PluginIntf.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // "Plugins" class interface //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include "PluginIntf.h" #include "MsgIntf.h" //--------------------------------------------------------------------------- // tTJSNC_Plugins //--------------------------------------------------------------------------- tjs_uint32 tTJSNC_Plugins::ClassID = -1; tTJSNC_Plugins::tTJSNC_Plugins() : inherited(TJS_W("Plugins")) { // registration of native members TJS_BEGIN_NATIVE_MEMBERS(Plugins) TJS_DECL_EMPTY_FINALIZE_METHOD //---------------------------------------------------------------------- //-- methods //---------------------------------------------------------------------- //--properties //--------------------------------------------------------------------------- TJS_END_NATIVE_MEMBERS } //--------------------------------------------------------------------------- tTJSNativeInstance * tTJSNC_Plugins::CreateNativeInstance() { // this class cannot create an instance TVPThrowExceptionMessage(TVPCannotCreateInstance); return NULL; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/PluginIntf.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // "Plugins" class interface //--------------------------------------------------------------------------- #ifndef PluginIntfH #define PluginIntfH #include "tjsNative.h" #if 0 #ifndef __stdcall #define __stdcall #endif #ifndef __cdecl #define __cdecl #endif #ifndef _stdcall #define _stdcall #endif #ifndef _cdecl #define _cdecl #endif #endif //--------------------------------------------------------------------------- // tTJSNC_Plugins : TJS Plugins class //--------------------------------------------------------------------------- class tTJSNC_Plugins : public tTJSNativeClass { typedef tTJSNativeClass inherited; public: tTJSNC_Plugins(); static tjs_uint32 ClassID; protected: tTJSNativeInstance *CreateNativeInstance(); }; //--------------------------------------------------------------------------- extern tTJSNativeClass * TVPCreateNativeClass_Plugins(); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/ScriptMgnIntf.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // TJS2 Script Managing //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include "tjs.h" #include "tjsDebug.h" #include "tjsArray.h" #include "ScriptMgnIntf.h" #include "StorageIntf.h" #include "DebugIntf.h" #include "WindowIntf.h" #include "LayerIntf.h" #include "CDDAIntf.h" #include "MIDIIntf.h" #include "WaveIntf.h" #include "TimerIntf.h" #include "EventIntf.h" #include "SystemIntf.h" #include "PluginIntf.h" #include "MenuItemIntf.h" #include "ClipboardIntf.h" #include "MsgIntf.h" #include "KAGParser.h" #include "VideoOvlIntf.h" #include "PadIntf.h" #include "TextStream.h" #include "Random.h" #include "tjsRandomGenerator.h" #include "SysInitIntf.h" #include "PhaseVocoderFilter.h" #include "BasicDrawDevice.h" #include "BinaryStream.h" #include "SysInitImpl.h" #include "SystemControl.h" #include "Application.h" #include "RectItf.h" #include "ImageFunction.h" #include "BitmapIntf.h" #include "tjsScriptBlock.h" #include "ApplicationSpecialPath.h" #include "SystemImpl.h" #include "BitmapLayerTreeOwner.h" #include "Extension.h" #include "Platform.h" #include "ConfigManager/LocaleConfigManager.h" //--------------------------------------------------------------------------- // Script system initialization script //--------------------------------------------------------------------------- static const tjs_nchar * TVPInitTJSScript = // note that this script is stored as narrow string TJS_N("const\ \ /* constants */\ /* tTVPBorderStyle */ bsNone=0, bsSingle=1, bsSizeable=2, bsDialog=3, bsToolWindow=4, bsSizeToolWin=5,\ /* tTVPUpdateType */ utNormal=0, utEntire =1,\ /* tTVPMouseButton */ mbLeft=0, mbRight=1, mbMiddle=2, mbX1=3, mbX2=4,\ /* tTVPMouseCursorState */ mcsVisible=0, mcsTempHidden=1, mcsHidden=2,\ /* tTVPImeMode */ imDisable=0, imClose=1, imOpen=2, imDontCare=3, imSAlpha=4, imAlpha=5, imHira=6, imSKata=7, imKata=8, imChinese=9, imSHanguel=10, imHanguel=11,\ /* Set of shift state */ ssShift=(1<<0), ssAlt=(1<<1), ssCtrl=(1<<2), ssLeft=(1<<3), ssRight=(1<<4), ssMiddle=(1<<5), ssDouble =(1<<6), ssRepeat = (1<<7),\ /* TVP_FSF_???? */ fsfFixedPitch=1, fsfSameCharSet=2, fsfNoVertical=4, \ fsfTrueTypeOnly=8, fsfUseFontFace=0x100, fsfIgnoreSymbol=0x10,\ /* tTVPLayerType */ ltBinder=0, ltCoverRect=1, ltOpaque=1, ltTransparent=2, ltAlpha=2, ltAdditive=3, ltSubtractive=4, ltMultiplicative=5, ltEffect=6, ltFilter=7, ltDodge=8, ltDarken=9, ltLighten=10, ltScreen=11, ltAddAlpha = 12,\ ltPsNormal = 13, ltPsAdditive = 14, ltPsSubtractive = 15, ltPsMultiplicative = 16, ltPsScreen = 17, ltPsOverlay = 18, ltPsHardLight = 19, ltPsSoftLight = 20, ltPsColorDodge = 21, ltPsColorDodge5 = 22, ltPsColorBurn = 23, ltPsLighten = 24, ltPsDarken = 25, ltPsDifference = 26, ltPsDifference5 = 27, ltPsExclusion = 28, \ /* tTVPBlendOperationMode */ omPsNormal = ltPsNormal,omPsAdditive = ltPsAdditive,omPsSubtractive = ltPsSubtractive,omPsMultiplicative = ltPsMultiplicative,omPsScreen = ltPsScreen,omPsOverlay = ltPsOverlay,omPsHardLight = ltPsHardLight,omPsSoftLight = ltPsSoftLight,omPsColorDodge = ltPsColorDodge,omPsColorDodge5 = ltPsColorDodge5,omPsColorBurn = ltPsColorBurn,omPsLighten = ltPsLighten,omPsDarken = ltPsDarken,omPsDifference = ltPsDifference,omPsDifference5 = ltPsDifference5,omPsExclusion = ltPsExclusion, \ omAdditive=ltAdditive, omSubtractive=ltSubtractive, omMultiplicative=ltMultiplicative, omDodge=ltDodge, omDarken=ltDarken, omLighten=ltLighten, omScreen=ltScreen, omAddAlpha=ltAddAlpha, omOpaque=ltOpaque, omAlpha=ltAlpha, omAuto = 128,\ /* tTVPDrawFace */ dfBoth=0, dfAlpha = dfBoth, dfAddAlpha = 4, dfMain=1, dfOpaque = dfMain, dfMask=2, dfProvince=3, dfAuto=128,\ /* tTVPHitType */ htMask=0, htProvince=1,\ /* tTVPScrollTransFrom */ sttLeft=0, sttTop=1, sttRight=2, sttBottom=3,\ /* tTVPScrollTransStay */ ststNoStay=0, ststStayDest=1, ststStaySrc=2, \ /* tTVPKAGDebugLevel */ tkdlNone=0, tkdlSimple=1, tkdlVerbose=2, \ /* tTVPAsyncTriggerMode */ atmNormal=0, atmExclusive=1, atmAtIdle=2, \ /* tTVPBBStretchType */ stNearest=0, stFastLinear=1, stLinear=2, stCubic=3, stSemiFastLinear = 4, stFastCubic = 5, stLanczos2 = 6, stFastLanczos2 = 7, stLanczos3 = 8, stFastLanczos3 = 9, stSpline16 = 10, stFastSpline16 = 11, stSpline36 = 12, stFastSpline36 = 13, stAreaAvg = 14, stFastAreaAvg = 15, stGaussian = 16, stFastGaussian = 17, stBlackmanSinc = 18, stFastBlackmanSinc = 19, stRefNoClip = 0x10000,\ /* tTVPClipboardFormat */ cbfText = 1,\ /* TVP_COMPACT_LEVEL_???? */ clIdle = 5, clDeactivate = 10, clMinimize = 15, clAll = 100,\ /* tTVPVideoOverlayMode Add: T.Imoto */ vomOverlay=0, vomLayer=1, vomMixer=2, vomMFEVR=3,\ /* tTVPPeriodEventReason */ perLoop = 0, perPeriod = 1, perPrepare = 2, perSegLoop = 3,\ /* tTVPSoundGlobalFocusMode */ sgfmNeverMute = 0, sgfmMuteOnMinimize = 1, sgfmMuteOnDeactivate = 2,\ /* tTVPTouchDevice */ tdNone=0, tdIntegratedTouch=0x01, tdExternalTouch=0x02, tdIntegratedPen=0x04, tdExternalPen=0x08, tdMultiInput=0x40, tdDigitizerReady=0x80,\ tdMouse=0x0100, tdMouseWheel=0x0200,\ /* Display Orientation */ oriUnknown=0, oriPortrait=1, oriLandscape=2,\ \ /* file attributes */\ faReadOnly=0x01, faHidden=0x02, faSysFile=0x04, faVolumeID=0x08, faDirectory=0x10, faArchive=0x20, faAnyFile=0x3f,\ /* mouse cursor constants */\ crDefault = 0x0,\ crNone = -1,\ crArrow = -2,\ crCross = -3,\ crIBeam = -4,\ crSize = -5,\ crSizeNESW = -6,\ crSizeNS = -7,\ crSizeNWSE = -8,\ crSizeWE = -9,\ crUpArrow = -10,\ crHourGlass = -11,\ crDrag = -12,\ crNoDrop = -13,\ crHSplit = -14,\ crVSplit = -15,\ crMultiDrag = -16,\ crSQLWait = -17,\ crNo = -18,\ crAppStart = -19,\ crHelp = -20,\ crHandPoint = -21,\ crSizeAll = -22,\ crHBeam = 1,\ /* color constants */\ clScrollBar = 0x80000000,\ clBackground = 0x80000001,\ clActiveCaption = 0x80000002,\ clInactiveCaption = 0x80000003,\ clMenu = 0x80000004,\ clWindow = 0x80000005,\ clWindowFrame = 0x80000006,\ clMenuText = 0x80000007,\ clWindowText = 0x80000008,\ clCaptionText = 0x80000009,\ clActiveBorder = 0x8000000a,\ clInactiveBorder = 0x8000000b,\ clAppWorkSpace = 0x8000000c,\ clHighlight = 0x3399ff,\ clHighlightText = 0x8000000e,\ clBtnFace = 0xf0f0f0,\ clBtnShadow = 0x787878,\ clGrayText = 0x80000011,\ clBtnText = 0x000000,\ clInactiveCaptionText = 0x80000013,\ clBtnHighlight = 0x80000014,\ cl3DDkShadow = 0x80000015,\ cl3DLight = 0x80000016,\ clInfoText = 0x80000017,\ clInfoBk = 0x80000018,\ clNone = 0x1fffffff,\ clAdapt= 0x01ffffff,\ clPalIdx = 0x3000000,\ clAlphaMat = 0x4000000,\ /* for Menu.trackPopup (see winuser.h) */\ tpmLeftButton = 0x0000,\ tpmRightButton = 0x0002,\ tpmLeftAlign = 0x0000,\ tpmCenterAlign = 0x0004,\ tpmRightAlign = 0x0008,\ tpmTopAlign = 0x0000,\ tpmVCenterAlign = 0x0010,\ tpmBottomAlign = 0x0020,\ tpmHorizontal = 0x0000,\ tpmVertical = 0x0040,\ tpmNoNotify = 0x0080,\ tpmReturnCmd = 0x0100,\ tpmRecurse = 0x0001,\ tpmHorPosAnimation = 0x0400,\ tpmHorNegAnimation = 0x0800,\ tpmVerPosAnimation = 0x1000,\ tpmVerNegAnimation = 0x2000,\ tpmNoAnimation = 0x4000,\ /* for Pad.showScrollBars (see Vcl/stdctrls.hpp :: enum TScrollStyle) */\ ssNone = 0,\ ssHorizontal = 1,\ ssVertical = 2,\ ssBoth = 3,\ /* virtual keycodes */\ VK_LBUTTON =0x01,\ VK_RBUTTON =0x02,\ VK_CANCEL =0x03,\ VK_MBUTTON =0x04,\ VK_BACK =0x08,\ VK_TAB =0x09,\ VK_CLEAR =0x0C,\ VK_RETURN =0x0D,\ VK_SHIFT =0x10,\ VK_CONTROL =0x11,\ VK_MENU =0x12,\ VK_PAUSE =0x13,\ VK_CAPITAL =0x14,\ VK_KANA =0x15,\ VK_HANGEUL =0x15,\ VK_HANGUL =0x15,\ VK_JUNJA =0x17,\ VK_FINAL =0x18,\ VK_HANJA =0x19,\ VK_KANJI =0x19,\ VK_ESCAPE =0x1B,\ VK_CONVERT =0x1C,\ VK_NONCONVERT =0x1D,\ VK_ACCEPT =0x1E,\ VK_MODECHANGE =0x1F,\ VK_SPACE =0x20,\ VK_PRIOR =0x21,\ VK_NEXT =0x22,\ VK_END =0x23,\ VK_HOME =0x24,\ VK_LEFT =0x25,\ VK_UP =0x26,\ VK_RIGHT =0x27,\ VK_DOWN =0x28,\ VK_SELECT =0x29,\ VK_PRINT =0x2A,\ VK_EXECUTE =0x2B,\ VK_SNAPSHOT =0x2C,\ VK_INSERT =0x2D,\ VK_DELETE =0x2E,\ VK_HELP =0x2F,\ VK_0 =0x30,\ VK_1 =0x31,\ VK_2 =0x32,\ VK_3 =0x33,\ VK_4 =0x34,\ VK_5 =0x35,\ VK_6 =0x36,\ VK_7 =0x37,\ VK_8 =0x38,\ VK_9 =0x39,\ VK_A =0x41,\ VK_B =0x42,\ VK_C =0x43,\ VK_D =0x44,\ VK_E =0x45,\ VK_F =0x46,\ VK_G =0x47,\ VK_H =0x48,\ VK_I =0x49,\ VK_J =0x4A,\ VK_K =0x4B,\ VK_L =0x4C,\ VK_M =0x4D,\ VK_N =0x4E,\ VK_O =0x4F,\ VK_P =0x50,\ VK_Q =0x51,\ VK_R =0x52,\ VK_S =0x53,\ VK_T =0x54,\ VK_U =0x55,\ VK_V =0x56,\ VK_W =0x57,\ VK_X =0x58,\ VK_Y =0x59,\ VK_Z =0x5A,\ VK_LWIN =0x5B,\ VK_RWIN =0x5C,\ VK_APPS =0x5D,\ VK_NUMPAD0 =0x60,\ VK_NUMPAD1 =0x61,\ VK_NUMPAD2 =0x62,\ VK_NUMPAD3 =0x63,\ VK_NUMPAD4 =0x64,\ VK_NUMPAD5 =0x65,\ VK_NUMPAD6 =0x66,\ VK_NUMPAD7 =0x67,\ VK_NUMPAD8 =0x68,\ VK_NUMPAD9 =0x69,\ VK_MULTIPLY =0x6A,\ VK_ADD =0x6B,\ VK_SEPARATOR =0x6C,\ VK_SUBTRACT =0x6D,\ VK_DECIMAL =0x6E,\ VK_DIVIDE =0x6F,\ VK_F1 =0x70,\ VK_F2 =0x71,\ VK_F3 =0x72,\ VK_F4 =0x73,\ VK_F5 =0x74,\ VK_F6 =0x75,\ VK_F7 =0x76,\ VK_F8 =0x77,\ VK_F9 =0x78,\ VK_F10 =0x79,\ VK_F11 =0x7A,\ VK_F12 =0x7B,\ VK_F13 =0x7C,\ VK_F14 =0x7D,\ VK_F15 =0x7E,\ VK_F16 =0x7F,\ VK_F17 =0x80,\ VK_F18 =0x81,\ VK_F19 =0x82,\ VK_F20 =0x83,\ VK_F21 =0x84,\ VK_F22 =0x85,\ VK_F23 =0x86,\ VK_F24 =0x87,\ VK_NUMLOCK =0x90,\ VK_SCROLL =0x91,\ VK_LSHIFT =0xA0,\ VK_RSHIFT =0xA1,\ VK_LCONTROL =0xA2,\ VK_RCONTROL =0xA3,\ VK_LMENU =0xA4,\ VK_RMENU =0xA5,\ /* VK_PADXXXX are KIRIKIRI specific */\ VK_PADLEFT =0x1B5,\ VK_PADUP =0x1B6,\ VK_PADRIGHT =0x1B7,\ VK_PADDOWN =0x1B8,\ VK_PAD1 =0x1C0,\ VK_PAD2 =0x1C1,\ VK_PAD3 =0x1C2,\ VK_PAD4 =0x1C3,\ VK_PAD5 =0x1C4,\ VK_PAD6 =0x1C5,\ VK_PAD7 =0x1C6,\ VK_PAD8 =0x1C7,\ VK_PAD9 =0x1C8,\ VK_PAD10 =0x1C9,\ VK_PADANY = 0x1DF,\ VK_PROCESSKEY =0xE5,\ VK_ATTN =0xF6,\ VK_CRSEL =0xF7,\ VK_EXSEL =0xF8,\ VK_EREOF =0xF9,\ VK_PLAY =0xFA,\ VK_ZOOM =0xFB,\ VK_NONAME =0xFC,\ VK_PA1 =0xFD,\ VK_OEM_CLEAR =0xFE,\ frFreeType=0,\ frGDI=1,\ /* graphic cache system */\ gcsAuto=-1,\ /* image 'mode' tag (mainly is generated by image format converter) constants */\ imageTagLayerType = %[\ opaque :%[type:ltOpaque ],\ rect :%[type:ltOpaque ],\ alpha :%[type:ltAlpha ],\ transparent :%[type:ltAlpha ],\ addalpha :%[type:ltAddAlpha ],\ add :%[type:ltAdditive ],\ sub :%[type:ltSubtractive ],\ mul :%[type:ltMultiplicative ],\ dodge :%[type:ltDodge ],\ darken :%[type:ltDarken ],\ lighten :%[type:ltLighten ],\ screen :%[type:ltScreen ],\ psnormal :%[type:ltPsNormal ],\ psadd :%[type:ltPsAdditive ],\ pssub :%[type:ltPsSubtractive ],\ psmul :%[type:ltPsMultiplicative ],\ psscreen :%[type:ltPsScreen ],\ psoverlay :%[type:ltPsOverlay ],\ pshlight :%[type:ltPsHardLight ],\ psslight :%[type:ltPsSoftLight ],\ psdodge :%[type:ltPsColorDodge ],\ psdodge5 :%[type:ltPsColorDodge5 ],\ psburn :%[type:ltPsColorBurn ],\ pslighten :%[type:ltPsLighten ],\ psdarken :%[type:ltPsDarken ],\ psdiff :%[type:ltPsDifference ],\ psdiff5 :%[type:ltPsDifference5 ],\ psexcl :%[type:ltPsExclusion ],\ ],\ /* draw thread num */\ dtnAuto=0\ ;"); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // global variables //--------------------------------------------------------------------------- tTJS *TVPScriptEngine = NULL; ttstr TVPStartupScriptName(TJS_W("startup.tjs")); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Garbage Collection stuff //--------------------------------------------------------------------------- class tTVPTJSGCCallback : public tTVPCompactEventCallbackIntf { void TJS_INTF_METHOD OnCompact(tjs_int level) { // OnCompact method from tTVPCompactEventCallbackIntf // called when the application is idle, deactivated, minimized, or etc... if(TVPScriptEngine) { if(level >= TVP_COMPACT_LEVEL_IDLE) { TVPScriptEngine->DoGarbageCollection(); } } } } static TVPTJSGCCallback; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPInitScriptEngine //--------------------------------------------------------------------------- static bool TVPScriptEngineInit = false; void TVPInitScriptEngine() { if(TVPScriptEngineInit) return; TVPScriptEngineInit = true; tTJSVariant val; // Set eval expression mode if(TVPGetCommandLine(TJS_W("-evalcontext"), &val) ) { ttstr str(val); if(str == TJS_W("global")) { TJSEvalOperatorIsOnGlobal = true; TJSWarnOnNonGlobalEvalOperator = true; } } // Set igonre-prop compat mode if(TVPGetCommandLine(TJS_W("-unaryaster"), &val) ) { ttstr str(val); if(str == TJS_W("compat")) { TJSUnaryAsteriskIgnoresPropAccess = true; } } // Set debug mode if(TVPGetCommandLine(TJS_W("-debug"), &val) ) { ttstr str(val); if(str == TJS_W("yes")) { TJSEnableDebugMode = true; TVPAddImportantLog((const tjs_char *)TVPWarnDebugOptionEnabled); // if(TVPGetCommandLine(TJS_W("-warnrundelobj"), &val) ) // { // str = val; // if(str == TJS_W("yes")) // { TJSWarnOnExecutionOnDeletingObject = true; // } // } } } // Set Read text encoding #if 0 if(TVPGetCommandLine(TJS_W("-readencoding"), &val) ) { ttstr str(val); TVPSetDefaultReadEncoding( str ); } TVPScriptTextEncoding = ttstr(TVPGetDefaultReadEncoding()); #endif #ifdef TVP_START_UP_SCRIPT_NAME TVPStartupScriptName = TVP_START_UP_SCRIPT_NAME; #else // Set startup script name if(TVPGetCommandLine(TJS_W("-startup"), &val) ) { ttstr str(val); TVPStartupScriptName = str; } #endif // create script engine object TVPScriptEngine = new tTJS(); // add kirikiriz //TVPScriptEngine->SetPPValue( TJS_W("kirikiriz"), 1 ); // set TJSGetRandomBits128 TJSGetRandomBits128 = TVPGetRandomBits128; // script system initialization TVPScriptEngine->ExecScript(ttstr(TVPInitTJSScript)); // set console output gateway handler TVPScriptEngine->SetConsoleOutput(TVPGetTJS2ConsoleOutputGateway()); // set text stream functions TJSCreateTextStreamForRead = TVPCreateTextStreamForRead; TJSCreateTextStreamForWrite = TVPCreateTextStreamForWrite; // set binary stream functions TJSCreateBinaryStreamForRead = TVPCreateBinaryStreamForRead; TJSCreateBinaryStreamForWrite = TVPCreateBinaryStreamForWrite; // register some TVP classes/objects/functions/propeties iTJSDispatch2 *dsp; iTJSDispatch2 *global = TVPScriptEngine->GetGlobalNoAddRef(); #define REGISTER_OBJECT(classname, instance) \ dsp = (instance); \ val = tTJSVariant(dsp/*, dsp*/); \ dsp->Release(); \ global->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP, TJS_W(#classname), NULL, \ &val, global); /* classes */ REGISTER_OBJECT(Debug, TVPCreateNativeClass_Debug()); REGISTER_OBJECT(Font, TVPCreateNativeClass_Font()); REGISTER_OBJECT(Layer, TVPCreateNativeClass_Layer()); REGISTER_OBJECT(CDDASoundBuffer, TVPCreateNativeClass_CDDASoundBuffer()); REGISTER_OBJECT(MIDISoundBuffer, TVPCreateNativeClass_MIDISoundBuffer()); REGISTER_OBJECT(Timer, TVPCreateNativeClass_Timer()); REGISTER_OBJECT(AsyncTrigger, TVPCreateNativeClass_AsyncTrigger()); REGISTER_OBJECT(System, TVPCreateNativeClass_System()); REGISTER_OBJECT(Storages, TVPCreateNativeClass_Storages()); REGISTER_OBJECT(Plugins, TVPCreateNativeClass_Plugins()); REGISTER_OBJECT(VideoOverlay, TVPCreateNativeClass_VideoOverlay()); REGISTER_OBJECT(Pad, TVPCreateNativeClass_Pad()); REGISTER_OBJECT(Clipboard, TVPCreateNativeClass_Clipboard()); REGISTER_OBJECT(Scripts, TVPCreateNativeClass_Scripts()); // declared in this file REGISTER_OBJECT(Rect, TVPCreateNativeClass_Rect()); REGISTER_OBJECT(Bitmap, TVPCreateNativeClass_Bitmap()); REGISTER_OBJECT(ImageFunction, TVPCreateNativeClass_ImageFunction()); REGISTER_OBJECT(BitmapLayerTreeOwner, TVPCreateNativeClass_BitmapLayerTreeOwner()); /* KAG special support */ REGISTER_OBJECT(KAGParser, TVPCreateNativeClass_KAGParser()); /* WaveSoundBuffer and its filters */ iTJSDispatch2 * waveclass = NULL; REGISTER_OBJECT(WaveSoundBuffer, (waveclass = TVPCreateNativeClass_WaveSoundBuffer())); dsp = new tTJSNC_PhaseVocoder(); val = tTJSVariant(dsp); dsp->Release(); waveclass->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP|TJS_STATICMEMBER, TJS_W("PhaseVocoder"), NULL, &val, waveclass); /* Window and its drawdevices */ iTJSDispatch2 * windowclass = NULL; REGISTER_OBJECT(Window, (windowclass = TVPCreateNativeClass_Window())); dsp = new tTJSNC_BasicDrawDevice(); val = tTJSVariant(dsp); dsp->Release(); windowclass->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP|TJS_STATICMEMBER, TJS_W("BasicDrawDevice"), NULL, &val, windowclass); windowclass->PropSet(TJS_MEMBERENSURE|TJS_IGNOREPROP|TJS_STATICMEMBER, TJS_W("PassThroughDrawDevice"), NULL, &val, windowclass); // compatible for old version kr2 REGISTER_OBJECT(MenuItem, TVPCreateNativeClass_MenuItem()); // register "menu" to windowclass // Add Extension Classes TVPCauseAtInstallExtensionClass( global ); // Garbage Collection Hook TVPAddCompactEventHook(&TVPTJSGCCallback); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPUninitScriptEngine //--------------------------------------------------------------------------- static bool TVPScriptEngineUninit = false; void TVPUninitScriptEngine() { if(TVPScriptEngineUninit) return; TVPScriptEngineUninit = true; //TVPScriptEngine->Shutdown(); TVPScriptEngine->Release(); /* Objects, theirs lives are contolled by reference counter, may not be all freed here in some occations. */ TVPScriptEngine = NULL; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPRestartScriptEngine //--------------------------------------------------------------------------- void TVPRestartScriptEngine() { TVPUninitScriptEngine(); TVPScriptEngineInit = false; TVPInitScriptEngine(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetScriptEngine //--------------------------------------------------------------------------- tTJS * TVPGetScriptEngine() { return TVPScriptEngine; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetScriptDispatch //--------------------------------------------------------------------------- iTJSDispatch2 * TVPGetScriptDispatch() { if(TVPScriptEngine) return TVPScriptEngine->GetGlobal(); else return NULL; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPExecuteScript //--------------------------------------------------------------------------- void TVPExecuteScript(const ttstr& content, tTJSVariant *result) { if(TVPScriptEngine) TVPScriptEngine->ExecScript(content, result); else TVPThrowInternalError; } //--------------------------------------------------------------------------- void TVPExecuteScript(const ttstr& content, const ttstr &name, tjs_int lineofs, tTJSVariant *result) { if(TVPScriptEngine) TVPScriptEngine->ExecScript(content, result, NULL, &name, lineofs); else TVPThrowInternalError; } //--------------------------------------------------------------------------- void TVPExecuteScript(const ttstr& content, iTJSDispatch2 *context, tTJSVariant *result) { if(TVPScriptEngine) TVPScriptEngine->ExecScript(content, result, context); else TVPThrowInternalError; } //--------------------------------------------------------------------------- void TVPExecuteScript(const ttstr& content, const ttstr &name, tjs_int lineofs, iTJSDispatch2 *context, tTJSVariant *result) { if(TVPScriptEngine) TVPScriptEngine->ExecScript(content, result, context, &name, lineofs); else TVPThrowInternalError; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPExecuteExpression //--------------------------------------------------------------------------- void TVPExecuteExpression(const ttstr& content, tTJSVariant *result) { TVPExecuteExpression(content, NULL, result); } //--------------------------------------------------------------------------- void TVPExecuteExpression(const ttstr& content, const ttstr &name, tjs_int lineofs, tTJSVariant *result) { TVPExecuteExpression(content, name, lineofs, NULL, result); } //--------------------------------------------------------------------------- void TVPExecuteExpression(const ttstr& content, iTJSDispatch2 *context, tTJSVariant *result) { if(TVPScriptEngine) { iTJSConsoleOutput *output = TVPScriptEngine->GetConsoleOutput(); TVPScriptEngine->SetConsoleOutput(NULL); // once set TJS console to null try { TVPScriptEngine->EvalExpression(content, result, context); } catch(...) { TVPScriptEngine->SetConsoleOutput(output); throw; } TVPScriptEngine->SetConsoleOutput(output); } else { TVPThrowInternalError; } } //--------------------------------------------------------------------------- void TVPExecuteExpression(const ttstr& content, const ttstr &name, tjs_int lineofs, iTJSDispatch2 *context, tTJSVariant *result) { if(TVPScriptEngine) { iTJSConsoleOutput *output = TVPScriptEngine->GetConsoleOutput(); TVPScriptEngine->SetConsoleOutput(NULL); // once set TJS console to null try { TVPScriptEngine->EvalExpression(content, result, context, &name, lineofs); } catch(...) { TVPScriptEngine->SetConsoleOutput(output); throw; } TVPScriptEngine->SetConsoleOutput(output); } else { TVPThrowInternalError; } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPExecuteBytecode //--------------------------------------------------------------------------- void TVPExecuteBytecode( const tjs_uint8* content, size_t len, iTJSDispatch2 *context, tTJSVariant *result, const tjs_char *name ) { if(!TVPScriptEngine) TVPThrowInternalError; TVPScriptEngine->LoadByteCode( content, len, result, context, name); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void TVPExecuteStorage(const ttstr &name, tTJSVariant *result, bool isexpression, const tjs_char * modestr) { TVPExecuteStorage(name, NULL, result, isexpression, modestr); } //--------------------------------------------------------------------------- void TVPExecuteStorage(const ttstr &name, iTJSDispatch2 *context, tTJSVariant *result, bool isexpression, const tjs_char * modestr) { // execute storage which contains script if(!TVPScriptEngine) TVPThrowInternalError; { // for bytecode ttstr place(TVPSearchPlacedPath(name)); ttstr shortname(TVPExtractStorageName(place)); tTJSBinaryStream* stream = TVPCreateBinaryStreamForRead(place, modestr); if( stream ) { bool isbytecode = false; try { isbytecode = TVPScriptEngine->LoadByteCode( stream, result, context, shortname.c_str() ); } catch(...) { delete stream; throw; } delete stream; if( isbytecode ) return; } } ttstr place(TVPSearchPlacedPath(name)); ttstr shortname(TVPExtractStorageName(place)); iTJSTextReadStream * stream = TVPCreateTextStreamForRead(place, modestr); ttstr buffer; try { stream->Read(buffer, 0); } catch(...) { stream->Destruct(); throw; } stream->Destruct(); if(TVPScriptEngine) { if(!isexpression) TVPScriptEngine->ExecScript(buffer, result, context, &shortname); else TVPScriptEngine->EvalExpression(buffer, result, context, &shortname); } } //--------------------------------------------------------------------------- void TVPCompileStorage( const ttstr& name, bool isrequestresult, bool outputdebug, bool isexpression, const ttstr& outputpath ) { // execute storage which contains script if(!TVPScriptEngine) TVPThrowInternalError; ttstr place(TVPSearchPlacedPath(name)); ttstr shortname(TVPExtractStorageName(place)); iTJSTextReadStream * stream = TVPCreateTextStreamForRead(place, TJS_W("")); ttstr buffer; try { stream->Read(buffer, 0); } catch(...) { stream->Destruct(); throw; } stream->Destruct(); tTJSBinaryStream* outputstream = TVPCreateStream(outputpath, TJS_BS_WRITE); if(TVPScriptEngine) { try { TVPScriptEngine->CompileScript( buffer.c_str(), outputstream, isrequestresult, outputdebug, isexpression, name.c_str(), 0 ); } catch(...) { delete outputstream; throw; } } delete outputstream; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCreateMessageMapFile //--------------------------------------------------------------------------- void TVPCreateMessageMapFile(const ttstr &filename) { #ifdef TJS_TEXT_OUT_CRLF ttstr script(TJS_W("{\r\n\tvar r = System.assignMessage;\r\n")); #else ttstr script(TJS_W("{\n\tvar r = System.assignMessage;\n")); #endif script += TJSCreateMessageMapString(); script += TJS_W("}"); iTJSTextWriteStream * stream = TVPCreateTextStreamForWrite( filename, TJS_W("")); try { stream->Write(script); } catch(...) { stream->Destruct(); throw; } stream->Destruct(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPDumpScriptEngine //--------------------------------------------------------------------------- void TVPDumpScriptEngine() { TVPTJS2StartDump(); TVPScriptEngine->SetConsoleOutput(TVPGetTJS2DumpOutputGateway()); try { TVPScriptEngine->Dump(); } catch(...) { TVPTJS2EndDump(); TVPScriptEngine->SetConsoleOutput(TVPGetTJS2ConsoleOutputGateway()); throw; } TVPScriptEngine->SetConsoleOutput(TVPGetTJS2ConsoleOutputGateway()); TVPTJS2EndDump(); } //--------------------------------------------------------------------------- bool TVPStartupSuccess = false; void TVPOpenPatchLibUrl(); //--------------------------------------------------------------------------- // TVPExecuteStartupScript //--------------------------------------------------------------------------- void TVPExecuteStartupScript() { ttstr strPatchError; try { ttstr patch = TVPGetAppPath() + "patch.tjs"; if(TVPIsExistentStorageNoSearch(patch)) TVPExecuteStorage(patch); } catch (const TJS::eTJSScriptError &e) { ttstr &msg = strPatchError; msg += e.GetMessage(); const tjs_char *pszBlockName = e.GetBlockName(); if (pszBlockName && *pszBlockName) { msg += TJS_W("\n@line("); tjs_char tmp[34]; msg += TJS_int_to_str(e.GetSourceLine(), tmp); msg += TJS_W(") "); msg += pszBlockName; } msg += TJS_W("\n"); msg += e.GetTrace(); } catch (const TJS::eTJS &e) { if (!TVPSystemUninitCalled) strPatchError = e.GetMessage(); } catch (const std::exception &e) { strPatchError = e.what(); } catch (const char* e) { strPatchError = e; } catch (const tjs_char* e) { strPatchError = e; } if (!strPatchError.IsEmpty()) { ttstr msg = LocaleConfigManager::GetInstance()->GetText("startup_patch_fail"); msg += "\n"; msg += strPatchError; std::vector btns; btns.emplace_back(LocaleConfigManager::GetInstance()->GetText("msgbox_ok")); btns.emplace_back(LocaleConfigManager::GetInstance()->GetText("browse_patch_lib")); if (TVPShowSimpleMessageBox(msg, TVPGetPackageVersionString(), btns) == 1) { TVPOpenPatchLibUrl(); } } // execute "startup.tjs" // try // { try { ttstr place(TVPSearchPlacedPath(TVPStartupScriptName)); TVPAddLog(TJS_W("(info) Loading startup script : ") + place); TVPStartupSuccess = false; try { iTJSTextReadStream * stream = TVPCreateTextStreamForRead(place, ""); stream->Destruct(); TVPExecuteStorage(TVPStartupScriptName); TVPStartupSuccess = true; } catch (...) { if (!TVPIsExistentStorage(TJS_W("System/Initialize.tjs"))) { throw; } } if (TVPStartupSuccess) { } else { // try direct execute initialize.tjs to compatible for some patch TVPExecuteStorage(TJS_W("System/Initialize.tjs")); TVPStartupSuccess = true; } TVPAddLog(TJS_W("(info) Startup script ended.")); try { ttstr patch = TVPGetAppPath() + "AfterStartup.tjs"; if (TVPIsExistentStorageNoSearch(patch)) TVPExecuteStorage(patch); } catch (...) {} } TJS_CONVERT_TO_TJS_EXCEPTION //} //TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(TJS_W("startup")) } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // unhandled exception handler related //--------------------------------------------------------------------------- static bool TJSGetSystem_exceptionHandler_Object(tTJSVariantClosure & dest) { // get System.exceptionHandler iTJSDispatch2 * global = TVPGetScriptEngine()->GetGlobalNoAddRef(); if(!global) return false; tTJSVariant val; tTJSVariant val2; tTJSVariantClosure clo; tjs_error er; er = global->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("System"), NULL, &val, global); if(TJS_FAILED(er)) return false; if(val.Type() != tvtObject) return false; clo = val.AsObjectClosureNoAddRef(); if(clo.Object == NULL) return false; clo.PropGet(TJS_MEMBERMUSTEXIST, TJS_W("exceptionHandler"), NULL, &val2, NULL); if(val2.Type() != tvtObject) return false; dest = val2.AsObjectClosure(); if(!dest.Object) { dest.Release(); return false; } return true; } //--------------------------------------------------------------------------- bool TVPProcessUnhandledException(eTJSScriptException &e) { bool result; tTJSVariantClosure clo; clo.Object = clo.ObjThis = NULL; try { // get the script engine tTJS *engine = TVPGetScriptEngine(); if(!engine) return false; // the script engine had been shutdown // get System.exceptionHandler if(!TJSGetSystem_exceptionHandler_Object(clo)) return false; // System.exceptionHandler cannot be retrieved // execute clo tTJSVariant obj(e.GetValue()); tTJSVariant *pval[] = { &obj }; tTJSVariant res; clo.FuncCall(0, NULL, NULL, &res, 1, pval, NULL); result = res.operator bool(); } catch(eTJSScriptError &e) { clo.Release(); TVPShowScriptException(e); } catch(eTJS &e) { clo.Release(); TVPShowScriptException(e); } catch(...) { clo.Release(); throw; } clo.Release(); return result; } //--------------------------------------------------------------------------- bool TVPProcessUnhandledException(eTJSScriptError &e) { bool result; tTJSVariantClosure clo; clo.Object = clo.ObjThis = NULL; try { // get the script engine tTJS *engine = TVPGetScriptEngine(); if(!engine) return false; // the script engine had been shutdown // get System.exceptionHandler if(!TJSGetSystem_exceptionHandler_Object(clo)) return false; // System.exceptionHandler cannot be retrieved // execute clo tTJSVariant obj; tTJSVariant msg(e.GetMessage()); tTJSVariant trace(e.GetTrace()); TJSGetExceptionObject(engine, &obj, msg, &trace); tTJSVariant *pval[] = { &obj }; tTJSVariant res; clo.FuncCall(0, NULL, NULL, &res, 1, pval, NULL); result = res.operator bool(); } catch(eTJSScriptError &e) { clo.Release(); TVPShowScriptException(e); } catch(eTJS &e) { clo.Release(); TVPShowScriptException(e); } catch(...) { clo.Release(); throw; } clo.Release(); return result; } //--------------------------------------------------------------------------- bool TVPProcessUnhandledException(eTJS &e) { bool result; tTJSVariantClosure clo; clo.Object = clo.ObjThis = NULL; try { // get the script engine tTJS *engine = TVPGetScriptEngine(); if(!engine) return false; // the script engine had been shutdown // get System.exceptionHandler if(!TJSGetSystem_exceptionHandler_Object(clo)) return false; // System.exceptionHandler cannot be retrieved // execute clo tTJSVariant obj; tTJSVariant msg(e.GetMessage()); TJSGetExceptionObject(engine, &obj, msg); tTJSVariant *pval[] = { &obj }; tTJSVariant res; clo.FuncCall(0, NULL, NULL, &res, 1, pval, NULL); result = res.operator bool(); } catch(eTJSScriptError &e) { clo.Release(); TVPShowScriptException(e); } catch(eTJS &e) { clo.Release(); TVPShowScriptException(e); } catch(...) { clo.Release(); throw; } clo.Release(); return result; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void TVPStartObjectHashMap() { // addref ObjectHashMap if the program is being debugged. if(TJSEnableDebugMode) TJSAddRefObjectHashMap(); } //--------------------------------------------------------------------------- // TVPBeforeProcessUnhandledException //--------------------------------------------------------------------------- void TVPBeforeProcessUnhandledException() { TVPDumpHWException(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPShowScriptException //--------------------------------------------------------------------------- /* These functions display the error location, reason, etc. And disable the script event dispatching to avoid massive occurrence of errors. */ extern ttstr TVPGetErrorDialogTitle(); //--------------------------------------------------------------------------- void TVPShowScriptException(eTJS &e) { TVPSetSystemEventDisabledState(true); TVPOnError(); if(!TVPSystemUninitCalled) { ttstr errstr = (ttstr(TVPScriptExceptionRaised) + TJS_W("\n") + e.GetMessage()); TVPAddLog(ttstr(TVPScriptExceptionRaised) + TJS_W("\n") + e.GetMessage()); TVPShowSimpleMessageBox(errstr, TVPGetErrorDialogTitle()); //Application->MessageDlg( errstr.AsStdString(), std::wstring(), mtError, mbOK ); TVPTerminateSync(1); } } //--------------------------------------------------------------------------- void TVPShowScriptException(eTJSScriptError &e) { TVPSetSystemEventDisabledState(true); TVPOnError(); if(!TVPSystemUninitCalled) { ttstr errstr = (ttstr(TVPScriptExceptionRaised) + TJS_W("\n") + e.GetMessage()); TVPAddLog(ttstr(TVPScriptExceptionRaised) + TJS_W("\n") + e.GetMessage()); if(e.GetTrace().GetLen() != 0) TVPAddLog(ttstr(TJS_W("trace : ")) + e.GetTrace()); TVPShowSimpleMessageBox(errstr, TVPGetErrorDialogTitle()); // Application->MessageDlg( errstr.AsStdString(), Application->GetTitle(), mtStop, mbOK ); #ifdef TVP_ENABLE_EXECUTE_AT_EXCEPTION const tjs_char* scriptName = e.GetBlockNoAddRef()->GetName(); if( scriptName != NULL && scriptName[0] != 0 ) { ttstr path(scriptName); try { ttstr newpath = TVPGetPlacedPath(path); if( newpath.IsEmpty() ) { path = TVPNormalizeStorageName(path); } else { path = newpath; } TVPGetLocalName( path ); std::wstring scriptPath( path.AsStdString() ); tjs_int lineno = 1+e.GetBlockNoAddRef()->SrcPosToLine(e.GetPosition() )- e.GetBlockNoAddRef()->GetLineOffset(); #if defined(WIN32) && defined(_DEBUG) && !defined(ENABLE_DEBUGGER) // fobKsĂ鎞AVisual Studio ōsWv鎞̎wfobOo͂ɏoāAbreak Œ~ if( ::IsDebuggerPresent() ) { std::wstring debuglile( std::wstring(L"2>")+path.AsStdString()+L"("+std::to_wstring(lineno)+L"): error :" + errstr.AsStdString() ); ::OutputDebugString( debuglile.c_str() ); // breakŒ~AȌo͍s_uNbN΁AOӏ̃XNvgVisual StudioŊJ ::DebugBreak(); } #endif scriptPath = std::wstring(L"\"") + scriptPath + std::wstring(L"\""); tTJSVariant val; if( TVPGetCommandLine(TJS_W("-exceptionexe"), &val) ) { ttstr exepath(val); //exepath = ttstr(TJS_W("\"")) + exepath + ttstr(TJS_W("\"")); if( TVPGetCommandLine(TJS_W("-exceptionarg"), &val) ) { ttstr arg(val); if( !exepath.IsEmpty() && !arg.IsEmpty() ) { std::wstring str( arg.AsStdString() ); str = ApplicationSpecialPath::ReplaceStringAll( str, std::wstring(L"%filepath%"), scriptPath ); str = ApplicationSpecialPath::ReplaceStringAll( str, std::wstring(L"%line%"), std::to_wstring(lineno) ); //exepath = exepath + ttstr(str); //_wsystem( exepath.c_str() ); arg = ttstr(str); TVPAddLog( ttstr(TJS_W("(execute) "))+exepath+ttstr(TJS_W(" "))+arg); TVPShellExecute( exepath, arg ); } } } } catch(...) { } } #endif TVPTerminateSync(1); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPInitializeStartupScript //--------------------------------------------------------------------------- void TVPInitializeStartupScript() { TVPStartObjectHashMap(); TVPExecuteStartupScript(); if(TVPTerminateOnNoWindowStartup && TVPGetWindowCount() == 0 ) { // no window is created and main window is invisible Application->Terminate(); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTJSNC_Scripts //--------------------------------------------------------------------------- tjs_uint32 tTJSNC_Scripts::ClassID = -1; tTJSNC_Scripts::tTJSNC_Scripts() : inherited(TJS_W("Scripts")) { // registration of native members TJS_BEGIN_NATIVE_MEMBERS(Scripts) TJS_DECL_EMPTY_FINALIZE_METHOD //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/Scripts) { return TJS_S_OK; } TJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/Scripts) //---------------------------------------------------------------------- //-- methods //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/execStorage) { // execute script which stored in storage if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr name = *param[0]; ttstr modestr; if(numparams >=2 && param[1]->Type() != tvtVoid) modestr = *param[1]; iTJSDispatch2 *context = numparams >= 3 && param[2]->Type() != tvtVoid ? param[2]->AsObjectNoAddRef() : NULL; TVPExecuteStorage(name, context, result, false, modestr.c_str()); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/execStorage) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/evalStorage) { // execute expression which stored in storage if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr name = *param[0]; ttstr modestr; if(numparams >=2 && param[1]->Type() != tvtVoid) modestr = *param[1]; iTJSDispatch2 *context = numparams >= 3 && param[2]->Type() != tvtVoid ? param[2]->AsObjectNoAddRef() : NULL; TVPExecuteStorage(name, context, result, true, modestr.c_str()); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/evalStorage) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/compileStorage) // bytecode { if(numparams < 2) return TJS_E_BADPARAMCOUNT; ttstr name = *param[0]; ttstr output = *param[1]; bool isresult = false; if( numparams >= 3 && (tjs_int)*param[2] ) { isresult = true; } bool outputdebug = false; if( numparams >= 4 && (tjs_int)*param[3] ) { outputdebug = true; } bool isexpression = false; if( numparams >= 5 && (tjs_int)*param[4] ) { isexpression = true; } TVPCompileStorage( name, isresult, outputdebug, isexpression, output ); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/compileStorage) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/exec) { // execute given string as a script if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr content = *param[0]; ttstr name; tjs_int lineofs = 0; if(numparams >= 2 && param[1]->Type() != tvtVoid) name = *param[1]; if(numparams >= 3 && param[2]->Type() != tvtVoid) lineofs = *param[2]; iTJSDispatch2 *context = numparams >= 4 && param[3]->Type() != tvtVoid ? param[3]->AsObjectNoAddRef() : NULL; if(TVPScriptEngine) TVPScriptEngine->ExecScript(content, result, context, &name, lineofs); else TVPThrowInternalError; return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/exec) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/eval) { // execute given string as a script if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr content = *param[0]; ttstr name; tjs_int lineofs = 0; if(numparams >= 2 && param[1]->Type() != tvtVoid) name = *param[1]; if(numparams >= 3 && param[2]->Type() != tvtVoid) lineofs = *param[2]; iTJSDispatch2 *context = numparams >= 4 && param[3]->Type() != tvtVoid ? param[3]->AsObjectNoAddRef() : NULL; if(TVPScriptEngine) TVPScriptEngine->EvalExpression(content, result, context, &name, lineofs); else TVPThrowInternalError; return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/eval) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/dump) { // execute given string as a script TVPDumpScriptEngine(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/dump) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getTraceString) { // get current stack trace as string tjs_int limit = 0; if(numparams >= 1 && param[0]->Type() != tvtVoid) limit = *param[0]; if(result) { *result = TJSGetStackTraceString(limit); } return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getTraceString) //---------------------------------------------------------------------- #ifdef TJS_DEBUG_DUMP_STRING TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/dumpStringHeap) { // dump all strings held by TJS2 framework TJSDumpStringHeap(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/dumpStringHeap) #endif //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setCallMissing) /* UNDOCUMENTED: subject to change */ { // set to call "missing" method if(numparams < 1) return TJS_E_BADPARAMCOUNT; iTJSDispatch2 *dsp = param[0]->AsObjectNoAddRef(); if(dsp) { tTJSVariant missing(TJS_W("missing")); dsp->ClassInstanceInfo(TJS_CII_SET_MISSING, 0, &missing); } return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/setCallMissing) /* UNDOCUMENTED: subject to change */ //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getClassNames) /* UNDOCUMENTED: subject to change */ { // get class name as an array, last (most end) class first. if(numparams < 1) return TJS_E_BADPARAMCOUNT; iTJSDispatch2 *dsp = param[0]->AsObjectNoAddRef(); if(dsp) { iTJSDispatch2 * array = TJSCreateArrayObject(); try { tjs_uint num = 0; while(true) { tTJSVariant val; tjs_error err = dsp->ClassInstanceInfo(TJS_CII_GET, num, &val); if(TJS_FAILED(err)) break; array->PropSetByNum(TJS_MEMBERENSURE, num, &val, array); num ++; } if(result) *result = tTJSVariant(array, array); } catch(...) { array->Release(); throw; } array->Release(); } else { return TJS_E_FAIL; } return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getClassNames) /* UNDOCUMENTED: subject to change */ //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(textEncoding) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetDefaultReadEncoding(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_BEGIN_NATIVE_PROP_SETTER { TVPSetDefaultReadEncoding(*param); return TJS_S_OK; } TJS_END_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(textEncoding) //---------------------------------------------------------------------- TJS_END_NATIVE_MEMBERS } //--------------------------------------------------------------------------- tTJSNativeInstance * tTJSNC_Scripts::CreateNativeInstance() { // this class cannot create an instance TVPThrowExceptionMessage(TVPCannotCreateInstance); return NULL; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCreateNativeClass_Scripts //--------------------------------------------------------------------------- tTJSNativeClass * TVPCreateNativeClass_Scripts() { tTJSNC_Scripts *cls = new tTJSNC_Scripts(); // setup some platform-specific members //---------------------------------------------------------------------- // currently none //---------------------------------------------------------------------- return cls; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/ScriptMgnIntf.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // TJS2 Script Managing //--------------------------------------------------------------------------- #ifndef ScriptMgnImtfH #define ScriptMgnImtfH #include "tjs.h" #include "tjsNative.h" #include "tjsError.h" //--------------------------------------------------------------------------- // implementation in this unit //--------------------------------------------------------------------------- extern ttstr TVPStartupScriptName; extern void TVPInitScriptEngine(); extern void TVPUninitScriptEngine(); extern void TVPRestartScriptEngine(); extern tTJS* TVPGetScriptEngine(); TJS_EXP_FUNC_DEF(iTJSDispatch2 *, TVPGetScriptDispatch, ()); TJS_EXP_FUNC_DEF(void, TVPExecuteScript, (const ttstr& content, tTJSVariant *result = NULL)); TJS_EXP_FUNC_DEF(void, TVPExecuteScript, (const ttstr& content, iTJSDispatch2 *context, tTJSVariant *result = NULL)); TJS_EXP_FUNC_DEF(void, TVPExecuteExpression, (const ttstr &content, tTJSVariant *result = NULL)); TJS_EXP_FUNC_DEF(void, TVPExecuteExpression, (const ttstr &content, iTJSDispatch2 *context, tTJSVariant *result = NULL)); TJS_EXP_FUNC_DEF(void, TVPExecuteScript, (const ttstr& content, const ttstr &name, tjs_int lineofs, tTJSVariant *result = NULL)); TJS_EXP_FUNC_DEF(void, TVPExecuteScript, (const ttstr& content, const ttstr &name, tjs_int lineofs, iTJSDispatch2 *context, tTJSVariant *result = NULL)); TJS_EXP_FUNC_DEF(void, TVPExecuteExpression, (const ttstr &content, const ttstr &name, tjs_int lineofs, tTJSVariant *result = NULL)); TJS_EXP_FUNC_DEF(void, TVPExecuteExpression, (const ttstr &content, const ttstr &name, tjs_int lineofs, iTJSDispatch2 *context, tTJSVariant *result = NULL)); TJS_EXP_FUNC_DEF(void, TVPExecuteStorage, (const ttstr &name, tTJSVariant *result = NULL, bool isexpression = false, const tjs_char *modestr = NULL)); TJS_EXP_FUNC_DEF(void, TVPExecuteStorage, (const ttstr &name, iTJSDispatch2 *context, tTJSVariant *result = NULL, bool isexpression = false, const tjs_char *modestr = NULL)); TJS_EXP_FUNC_DEF(void, TVPDumpScriptEngine, ()); TJS_EXP_FUNC_DEF(void, TVPExecuteBytecode, (const tjs_uint8* content, size_t len, iTJSDispatch2 *context, tTJSVariant *result = NULL, const tjs_char *name = NULL )); extern void TVPExecuteStartupScript(); TJS_EXP_FUNC_DEF(void, TVPCreateMessageMapFile, (const ttstr &filename)); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // implementation in each platform to show script exception message //--------------------------------------------------------------------------- extern void TVPShowScriptException(eTJS &e); extern void TVPShowScriptException(eTJSScriptError &e); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPBeforeProcessUnhandledException (implementation in each platform) //--------------------------------------------------------------------------- extern void TVPBeforeProcessUnhandledException(); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // unhandled exception handler related macros //--------------------------------------------------------------------------- extern bool TVPProcessUnhandledException(eTJSScriptException &e); extern bool TVPProcessUnhandledException(eTJSScriptError &e); extern bool TVPProcessUnhandledException(eTJS &e); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPInitializeStartupScript //--------------------------------------------------------------------------- extern void TVPInitializeStartupScript(); extern bool TVPCheckProcessLog(); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // unhandled exception handler related macros //--------------------------------------------------------------------------- #define TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION(origin) \ catch(eTJSScriptException &e) \ { \ TVPBeforeProcessUnhandledException(); \ e.AddTrace(ttstr(origin)); \ if(!TVPProcessUnhandledException(e)) \ TVPShowScriptException(e); \ } \ catch(eTJSScriptError &e) \ { \ TVPBeforeProcessUnhandledException(); \ e.AddTrace(ttstr(origin)); \ if(!TVPProcessUnhandledException(e)) \ TVPShowScriptException(e); \ } \ catch(eTJS &e) \ { \ TVPBeforeProcessUnhandledException(); \ if(!TVPProcessUnhandledException(e)) \ TVPShowScriptException(e); \ } \ catch(...) \ { \ TVPBeforeProcessUnhandledException(); \ throw; \ } #define TVP_CATCH_AND_SHOW_SCRIPT_EXCEPTION_FORCE_SHOW_EXCEPTION(origin) \ catch(eTJSScriptError &e) \ { \ TVPBeforeProcessUnhandledException(); \ e.AddTrace(ttstr(origin)); \ TVPShowScriptException(e); \ } \ catch(eTJS &e) \ { \ TVPBeforeProcessUnhandledException(); \ TVPShowScriptException(e); \ } \ catch(...) \ { \ TVPBeforeProcessUnhandledException(); \ throw; \ } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTJSNC_Scripts : TJS Scripts class //--------------------------------------------------------------------------- class tTJSNC_Scripts : public tTJSNativeClass { typedef tTJSNativeClass inherited; public: tTJSNC_Scripts(); static tjs_uint32 ClassID; protected: tTJSNativeInstance *CreateNativeInstance(); }; //--------------------------------------------------------------------------- extern tTJSNativeClass * TVPCreateNativeClass_Scripts(); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/StorageIntf.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Universal Storage System //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include #include #include #include "StorageIntf.h" #include "tjsUtils.h" #include "MsgIntf.h" #include "EventIntf.h" #include "DebugIntf.h" #include "tjsArray.h" #include "SysInitIntf.h" #include "XP3Archive.h" #include "TickCount.h" #define TVP_DEFAULT_ARCHIVE_CACHE_NUM 64 #define TVP_DEFAULT_AUTOPATH_CACHE_NUM 256 //--------------------------------------------------------------------------- // global variables //--------------------------------------------------------------------------- // current media ( ex. "http" "ftp" "file" ) ttstr TVPCurrentMedia; // archive delimiter // this changes '>' from '#' since 2.19 beta 14 tjs_char TVPArchiveDelimiter = '>'; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // statics //--------------------------------------------------------------------------- static tTJSStaticCriticalSection TVPCreateStreamCS; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // utilities //--------------------------------------------------------------------------- ttstr TVPStringFromBMPUnicode(const tjs_uint16 *src, tjs_int maxlen) { // convert to ttstr from BMP unicode if(sizeof(tjs_char) == 2) { // sizeof(tjs_char) is 2 (windows native) if(maxlen == -1) return ttstr((const tjs_char*)src); else return ttstr((const tjs_char*)src, maxlen); } else if(sizeof(tjs_char) == 4) { // sizeof(tjs_char) is 4 (UCS32) // FIXME: NOT TESTED CODE tjs_int len = 0; const tjs_uint16 *p = src; while(*p) len++, p++; if(maxlen != -1 && len > maxlen) len = maxlen; ttstr ret((tTJSStringBufferLength)(len)); tjs_char *dest = ret.Independ(); p = src; while(len && *p) { *dest = *p; dest++; p++; len --; } *dest = 0; ret.FixLen(); return ret; } return (const tjs_char*)TVPTjsCharMustBeTwoOrFour; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPStorageMediaManager //--------------------------------------------------------------------------- class tTVPStorageMediaManager { class tMediaNameString : public tTJSString { public: bool operator == (const tMediaNameString &rhs) const { const tjs_char * l_p = c_str(); const tjs_char * r_p = rhs.c_str(); while(*l_p && *r_p) { if(*l_p == TJS_W(':')) break; if(*r_p == TJS_W(':')) break; if(*l_p != *r_p) break; l_p++; r_p++; } if((*l_p == TJS_W(':') || *l_p == 0) && (*r_p == TJS_W(':') || *r_p == 0)) return true; return false; } }; class tHashFunc { public: static tjs_uint32 Make(const tMediaNameString &key) { if(key.IsEmpty()) return 0; const tjs_char *str = key.c_str(); tjs_uint32 ret = 0; while(*str && *str != ':') { ret += *str; ret += (ret << 10); ret ^= (ret >> 6); str++; } ret += (ret << 3); ret ^= (ret >> 11); ret += (ret << 15); if(!ret) ret = (tjs_uint32)-1; return ret; } }; class tMediaRecord { public: ttstr CurrentDomain; ttstr CurrentPath; tTJSRefHolder MediaIntf; tjs_int MediaNameLen; // bool IsCaseSensitive; tMediaRecord(iTVPStorageMedia *media) : MediaIntf(media), CurrentDomain("."), CurrentPath("/") { ttstr name; media->GetName(name); MediaNameLen = name.GetLen(); /*IsCaseSensitive = media->IsCaseSensitive();*/ } const tjs_char *GetDomainAndPath(const ttstr &name) { return name.c_str() + MediaNameLen + 3; // 3 = strlen("://") } }; typedef tTJSHashTable tHashTable; tHashTable HashTable; public: tTVPStorageMediaManager(); ~tTVPStorageMediaManager(); private: static void ThrowUnsupportedMediaType(const ttstr &name); tMediaRecord * GetMediaRecord(const ttstr &name); public: void Register(iTVPStorageMedia * media); void Unregister(iTVPStorageMedia * media); ttstr NormalizeStorageName(const ttstr &name, ttstr *ret_media = NULL, ttstr *ret_domain = NULL, ttstr *ret_path = NULL); void SetCurrentDirectory(const ttstr &name); static ttstr ExtractMediaName(const ttstr &name); bool CheckExistentStorage(const ttstr & name); tTJSBinaryStream * Open(const ttstr & name, tjs_uint32 flags); void GetListAt(const ttstr &name, iTVPStorageLister *lister); ttstr GetLocallyAccessibleName(const ttstr &name); } TVPStorageMediaManager; //--------------------------------------------------------------------------- tTVPStorageMediaManager::tTVPStorageMediaManager() { iTVPStorageMedia *filemedia = TVPCreateFileMedia(); Register(filemedia); filemedia->Release(); } //--------------------------------------------------------------------------- tTVPStorageMediaManager::~tTVPStorageMediaManager() { } //--------------------------------------------------------------------------- void tTVPStorageMediaManager::ThrowUnsupportedMediaType(const ttstr &name) { TVPThrowExceptionMessage(TVPUnsupportedMediaName, ExtractMediaName(name)); } //--------------------------------------------------------------------------- tTVPStorageMediaManager::tMediaRecord * tTVPStorageMediaManager::GetMediaRecord(const ttstr &name) { tMediaRecord *rec = HashTable.Find(*(tMediaNameString*)&name); if(!rec) ThrowUnsupportedMediaType(name); return rec; } //--------------------------------------------------------------------------- void tTVPStorageMediaManager::Register(iTVPStorageMedia * media) { ttstr medianame; media->GetName(medianame); tMediaRecord *rec = HashTable.Find(*(tMediaNameString*)&medianame); if(rec) TVPThrowExceptionMessage( TVPMediaNameHadAlreadyBeenRegistered, medianame ); tMediaRecord new_rec(media); HashTable.Add(*(tMediaNameString*)&medianame, new_rec); } //--------------------------------------------------------------------------- void tTVPStorageMediaManager::Unregister(iTVPStorageMedia * media) { ttstr medianame; media->GetName(medianame); tMediaRecord *rec = HashTable.Find(*(tMediaNameString*)&medianame); if(!rec) TVPThrowExceptionMessage( TVPMediaNameIsNotRegistered, medianame ); HashTable.Delete(*(tMediaNameString*)&medianame); } //--------------------------------------------------------------------------- ttstr tTVPStorageMediaManager::NormalizeStorageName(const ttstr &name, ttstr *ret_media, ttstr *ret_domain, ttstr *ret_path) { // Normalize storage name. // storage name is basically in following form: // media://domain/path // media is sort of access method, like "file", "http" ...etc. // domain represents in which computer the data is. // path is where the data is in the computer. // empty check if(name.IsEmpty()) return name; // empty name is empty name // pre-normalize const tjs_char *pca;//, *pcb, *pcc; tjs_char *pa, *pb, *pc; ttstr tmp(name); TVPPreNormalizeStorageName(tmp); // unify path delimiter pa = tmp.Independ(); while(*pa) { if(*pa == TJS_W('\\')) *pa = TJS_W('/'); pa++; } // save in-archive storage name and normalize it ttstr inarchive_name; bool inarc_name_found = false; pca = tmp.c_str(); pa = const_cast(TJS_strchr(pca, TVPArchiveDelimiter)); if(pa) { inarchive_name = ttstr(pa + 1); tTVPArchive::NormalizeInArchiveStorageName(inarchive_name); inarc_name_found = true; tmp = ttstr(pca, (int)(pa - pca)); } if(tmp.IsEmpty()) TVPThrowExceptionMessage(TVPInvalidPathName, name); // split the name into media, domain, path // (and guess what component is omitted) ttstr media, domain, path; // - find media name // media name is: /^[A-Za-z]+:/ pa = pb = tmp.Independ(); while(*pa) { if(!( (*pa >= TJS_W('A') && *pa <= TJS_W('Z')) || (*pa >= TJS_W('a') && *pa <= TJS_W('z')) )) break; pa ++; } if(*pa == TJS_W(':')) { // media name found media = ttstr(pb, (int)(pa - pb)); pa ++; } else { pa = pb; } // - find domain name // at this place, pa may point one of following: // ///path (domain is omitted) // //domain/path (none is omitted) // /path (domain is omitted) // relative-path (domain and current path are omitted) if(pa[0] == TJS_W('/')) { if(pa[1] == TJS_W('/')) { if(pa[2] == TJS_W('/')) { // slash count 3: domain is ommited pa += 2; } else { // slash count 2: none is omitted pa += 2; // find '/' as a domain delimiter pc = TJS_strchr(pa, TJS_W('/')); if(!pc) TVPThrowExceptionMessage(TVPInvalidPathName, name); domain = ttstr(pa, (int)(pc - pa)); pa = pc; } } else { // slash count 1: domain is omitted ; // } } // - get path name path = pa; // supply omitted and normalize if(media.IsEmpty()) { media = TVPCurrentMedia; } else { // normalize media name ( make them all small ) tjs_char *p = media.Independ(); while(*p) { if(*p >= TJS_W('A') && *p <= TJS_W('Z')) *p += (TJS_W('a') - TJS_W('A')); p ++; } } tMediaRecord * mediarec = GetMediaRecord(media); if(domain.IsEmpty()) domain = mediarec->CurrentDomain; mediarec->MediaIntf.GetObjectNoAddRef()->NormalizeDomainName(domain); if(path.IsEmpty()) { path = TJS_W("/"); } else if(path.c_str()[0] != TJS_W('/')) { path = mediarec->CurrentPath + path; } mediarec->MediaIntf.GetObjectNoAddRef()->NormalizePathName(path); // compress redudant path accesses if(inarc_name_found) { tjs_char tmp[2]; tmp[0] = TVPArchiveDelimiter; tmp[1] = 0; path += tmp + inarchive_name; } pa = pb = pc = path.Independ(); // pa = read pointer, pb = write pointer, pc = start tjs_int dot_count = -1; while(true) { if(*pa == TVPArchiveDelimiter || *pa == TJS_W('/') || *pa == 0) { tjs_char delim = 0; if(*pa && dot_count == 0) { // duplicated slashes pb --; } else if(dot_count > 0) { pb --; while(pb >= pc) { if(*pb == TJS_W('/') || *pb == TVPArchiveDelimiter) { dot_count --; if(dot_count == 0) { delim = *pb; break; } if(*pb == TVPArchiveDelimiter) TVPThrowExceptionMessage(TVPInvalidPathName, name); } pb --; } if(pb < pc) TVPThrowExceptionMessage(TVPInvalidPathName, name); } if(!delim) *pb = *pa; else *pb = delim; if(*pa == 0) break; pb ++; pa ++; dot_count = 0; } else if(*pa == TJS_W('.')) { *(pb++) = *(pa++); if(dot_count != -1) dot_count ++; } else { *(pb++) = *(pa++); dot_count = -1; } } path.FixLen(); // merge and return normalize storage name if(ret_media) *ret_media = media; if(ret_domain) *ret_domain = domain; if(ret_path) *ret_path = path; tmp = media + TJS_W("://") + domain + path; return tmp; } //--------------------------------------------------------------------------- void tTVPStorageMediaManager::SetCurrentDirectory(const ttstr &name) { tjs_char ch = name.GetLastChar(); if(ch != TJS_W('/') && ch != TJS_W('\\') && ch != TVPArchiveDelimiter) TVPThrowExceptionMessage(TVPMissingPathDelimiterAtLast); ttstr media, domain, path; NormalizeStorageName(name, &media, &domain, &path); tMediaRecord *rec = GetMediaRecord(media); rec->CurrentDomain = domain; rec->CurrentPath = path; TVPCurrentMedia = media; } //--------------------------------------------------------------------------- ttstr tTVPStorageMediaManager::ExtractMediaName(const ttstr &name) { // extract media name from normalized storage named "name". // returned media name does not contain colon. const tjs_char * p = name.c_str(); const tjs_char * po = p; while(*p && *p != TJS_W(':')) p++; return ttstr(po, (int)(p - po)); } //--------------------------------------------------------------------------- bool tTVPStorageMediaManager::CheckExistentStorage(const ttstr & name) { // gateway for CheckExistentStorage // name must not be an in-archive storage name tMediaRecord *rec = GetMediaRecord(name); return rec->MediaIntf.GetObjectNoAddRef()->CheckExistentStorage(rec->GetDomainAndPath(name)); } //--------------------------------------------------------------------------- tTJSBinaryStream * tTVPStorageMediaManager::Open(const ttstr & name, tjs_uint32 flags) { // gateway for Open // name must not be an in-archive storage name tMediaRecord *rec = GetMediaRecord(name); return rec->MediaIntf.GetObjectNoAddRef()->Open(rec->GetDomainAndPath(name), flags); } //--------------------------------------------------------------------------- void tTVPStorageMediaManager::GetListAt(const ttstr &name, iTVPStorageLister * lister) { // gateway for GetListAt // name must not be an in-archive storage name tMediaRecord *rec = GetMediaRecord(name); /*return */rec->MediaIntf.GetObjectNoAddRef()->GetListAt(rec->GetDomainAndPath(name), lister); } //--------------------------------------------------------------------------- ttstr tTVPStorageMediaManager::GetLocallyAccessibleName(const ttstr &name) { // gateway for GetLocallyAccessibleName // name must not be an in-archive storage name tMediaRecord *rec = GetMediaRecord(name); ttstr dname = rec->GetDomainAndPath(name); rec->MediaIntf.GetObjectNoAddRef()->GetLocallyAccessibleName(dname); return dname; } //--------------------------------------------------------------------------- void TVPGetListAt(const ttstr &name, iTVPStorageLister * lister) { TVPStorageMediaManager.GetListAt(name, lister); } //--------------------------------------------------------------------------- void TVPRegisterStorageMedia(iTVPStorageMedia *media) { TVPStorageMediaManager.Register(media); } //--------------------------------------------------------------------------- void TVPUnregisterStorageMedia(iTVPStorageMedia *media) { TVPStorageMediaManager.Unregister(media); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPNormalizeStorgeName : storage name normalization //--------------------------------------------------------------------------- ttstr TVPNormalizeStorageName(const ttstr & _name) // TODO: check what is done in TVPNormalizeStorageName { return TVPStorageMediaManager.NormalizeStorageName(_name); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPSetCurrentDirectory //--------------------------------------------------------------------------- void TVPSetCurrentDirectory(const ttstr & _name) { TVPStorageMediaManager.SetCurrentDirectory(_name); TVPClearStorageCaches(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetLocalName and TVPGetLocallyAccessibleName //--------------------------------------------------------------------------- void TVPGetLocalName(ttstr &name) { ttstr tmp = TVPGetLocallyAccessibleName(name); if(tmp.IsEmpty()) TVPThrowExceptionMessage(TVPCannotGetLocalName, name); name = tmp; } //--------------------------------------------------------------------------- ttstr TVPGetLocallyAccessibleName(const ttstr &name) { if(TJS_strchr(name.c_str(), TVPArchiveDelimiter)) return TJS_W(""); // in-archive storage is always not accessible from local file system return TVPStorageMediaManager.GetLocallyAccessibleName(name); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPArchive //--------------------------------------------------------------------------- void tTVPArchive::NormalizeInArchiveStorageName(ttstr & name) { // normalization of in-archive storage name does : if(name.IsEmpty()) return; // make all characters small // change '\\' to '/' tjs_char *ptr = name.Independ(); while(*ptr) { if(*ptr >= TJS_W('A') && *ptr <= TJS_W('Z')) *ptr += TJS_W('a') - TJS_W('A'); else if(*ptr == TJS_W('\\')) *ptr = TJS_W('/'); ptr++; } // eliminate duplicated slashes ptr = name.Independ(); tjs_char *org_ptr = ptr; tjs_char *dest = ptr; while(*ptr) { if(*ptr != TJS_W('/')) { *dest = *ptr; ptr ++; dest ++; } else { if(ptr != org_ptr) { *dest = *ptr; ptr ++; dest ++; } while(*ptr == TJS_W('/')) ptr++; } } *dest = 0; name.FixLen(); } //--------------------------------------------------------------------------- void tTVPArchive::AddToHash() { // enter all names to the hash table tjs_uint Count = GetCount(); tjs_uint i; for(i = 0; i < Count; i++) { ttstr name = GetName(i); NormalizeInArchiveStorageName(name); Hash.Add(name, i); } } //--------------------------------------------------------------------------- tTJSBinaryStream * tTVPArchive::CreateStream(const ttstr & name) { if(name.IsEmpty()) return NULL; if(!Init) { Init = true; AddToHash(); } tjs_uint *p = Hash.Find(name); if(!p) TVPThrowExceptionMessage(TVPStorageInArchiveNotFound, name, ArchiveName); return CreateStreamByIndex(*p); } //--------------------------------------------------------------------------- bool tTVPArchive::IsExistent(const ttstr & name) { if(name.IsEmpty()) return false; if(!Init) { Init = true; AddToHash(); } return Hash.Find(name) != NULL; } //--------------------------------------------------------------------------- tjs_int tTVPArchive::GetFirstIndexStartsWith(const ttstr & prefix) { // returns first index which have 'prefix' at start of the name. // returns -1 if the target is not found. // the item must be sorted by ttstr::operator < , otherwise this function // will not work propertly. tjs_uint total_count = GetCount(); tjs_int s = 0, e = total_count; while(e - s > 1) { tjs_int m = (e + s) / 2; if(!(GetName(m) < prefix)) { // m is after or at the target e = m; } else { // m is before the target s = m; } } // at this point, s or s+1 should point the target. // be certain. if(s >= (tjs_int)total_count) return -1; // out of the index if(GetName(s).StartsWith(prefix)) return s; s++; if(s >= (tjs_int)total_count) return -1; // out of the index if(GetName(s).StartsWith(prefix)) return s; return -1; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPArchiveCache //--------------------------------------------------------------------------- class tTVPArchiveCache { typedef tTJSRefHolder tHolder; tTJSHashCache ArchiveCache; tTJSCriticalSection CS; public: tTVPArchiveCache() : ArchiveCache(TVP_DEFAULT_ARCHIVE_CACHE_NUM) { } ~tTVPArchiveCache() { } void SetMaxCount(tjs_int maxcount) { ArchiveCache.SetMaxCount(maxcount); } void Clear() { // releases all elements ArchiveCache.Clear(); } tTVPArchive * Get(ttstr name) { name = TVPNormalizeStorageName(name); tTJSCSH csh(CS); tjs_uint32 hash = tTJSHashCache::MakeHash(name); tHolder *ptr = ArchiveCache.FindAndTouchWithHash(name, hash); if(ptr) { // exist in the cache return ptr->GetObject(); } if(!TVPIsExistentStorageNoSearch(name)) { // storage not found TVPThrowExceptionMessage(TVPCannotFindStorage, name); } // not exist in the cache tTVPArchive *arc = TVPOpenArchive(name, true); tHolder holder(arc); ArchiveCache.AddWithHash(name, hash, holder); return arc; } private: } TVPArchiveCache; static void TVPClearArchiveCache() { TVPArchiveCache.Clear(); } static tTVPAtExit TVPClearArchiveCacheAtExit (TVP_ATEXIT_PRI_SHUTDOWN, TVPClearArchiveCache); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPIsExistentStorageNoSearch //--------------------------------------------------------------------------- bool TVPIsExistentStorageNoSearchNoNormalize(const ttstr &name) { // does name contain > ? tTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS); const tjs_char * sharp_pos = TJS_strchr(name.c_str(), TVPArchiveDelimiter); if(sharp_pos) { // this storagename indicates a file in an archive ttstr arcname(name, (int)(sharp_pos - name.c_str())); tTVPArchive *arc; arc = TVPArchiveCache.Get(arcname); bool ret; try { ttstr in_arc_name(sharp_pos + 1); tTVPArchive::NormalizeInArchiveStorageName(in_arc_name); ret = arc->IsExistent(in_arc_name); } catch(...) { arc->Release(); throw; } arc->Release(); return ret; } return TVPStorageMediaManager.CheckExistentStorage(name); } //--------------------------------------------------------------------------- bool TVPIsExistentStorageNoSearch(const ttstr &_name) { return TVPIsExistentStorageNoSearchNoNormalize(TVPNormalizeStorageName(_name)); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPExtractStorageExt //--------------------------------------------------------------------------- ttstr TVPExtractStorageExt(const ttstr & name) { // extract an extension from name. // returned string will contain extension delimiter ( '.' ), except for // missing extension of the input string. // ( returns null string when input string does not have an extension ) const tjs_char * s = name.c_str(); tjs_int slen = name.GetLen(); const tjs_char * p = s + slen; p--; while(p>=s) { if(*p == TJS_W('\\')) break; if(*p == TJS_W('/')) break; if(*p == TVPArchiveDelimiter) break; if(*p == TJS_W('.')) { // found extension delimiter tjs_int extlen = (tjs_int)(slen - ( p - s )); return ttstr(p, extlen); } p--; } // not found return ttstr(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPExtractStorageName //--------------------------------------------------------------------------- ttstr TVPExtractStorageName(const ttstr & name) { // extract "name"'s storage name ( excluding path ) and return it. const tjs_char * s = name.c_str(); tjs_int slen = name.GetLen(); const tjs_char * p = s + slen; p--; while(p>=s) { if(*p == TJS_W('\\')) break; if(*p == TJS_W('/')) break; if(*p == TVPArchiveDelimiter) break; p--; } p++; if(p == s) return name; else return ttstr(p, (int)(slen - (p -s))); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPExtractStoragePath //--------------------------------------------------------------------------- ttstr TVPExtractStoragePath(const ttstr & name) { // extract "name"'s path ( including last delimiter ) and return it. const tjs_char * s = name.c_str(); tjs_int slen = name.GetLen(); const tjs_char * p = s + slen; p--; while(p>=s) { if(*p == TJS_W('\\')) break; if(*p == TJS_W('/')) break; if(*p == TVPArchiveDelimiter) break; p--; } p++; return ttstr(s, (int)(p-s)); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPChopStorageExt //--------------------------------------------------------------------------- extern ttstr TVPChopStorageExt(const ttstr & name) { // chop storage's extension and return it. const tjs_char * s = name.c_str(); tjs_int slen = name.GetLen(); const tjs_char * p = s + slen; p--; while(p>=s) { if(*p == TJS_W('\\')) break; if(*p == TJS_W('/')) break; if(*p == TVPArchiveDelimiter) break; if(*p == TJS_W('.')) { // found extension delimiter return ttstr(s, (int)(p-s)); } p--; } // not found return name; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Auto search path support //--------------------------------------------------------------------------- #define TVP_AUTO_PATH_HASH_SIZE 1024 std::vector TVPAutoPathList; tTJSHashCache TVPAutoPathCache(TVP_DEFAULT_AUTOPATH_CACHE_NUM); tTJSHashTable, TVP_AUTO_PATH_HASH_SIZE> TVPAutoPathTable; bool AutoPathTableInit = false; //--------------------------------------------------------------------------- static void TVPClearAutoPathCache() { TVPAutoPathCache.Clear(); TVPAutoPathTable.Clear(); AutoPathTableInit = false; } //--------------------------------------------------------------------------- struct tTVPClearAutoPathCacheCallback : public tTVPCompactEventCallbackIntf { virtual void TJS_INTF_METHOD OnCompact(tjs_int level) { if(level >= TVP_COMPACT_LEVEL_DEACTIVATE) { // clear the auto search path cache on application deactivate tTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS); TVPClearAutoPathCache(); } } } static TVPClearAutoPathCacheCallback; static bool TVPClearAutoPathCacheCallbackInit = false; //--------------------------------------------------------------------------- void TVPAddAutoPath(const ttstr & name) { tTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS); tjs_char lastchar = name.GetLastChar(); if(lastchar != TVPArchiveDelimiter && lastchar != TJS_W('/') && lastchar != TJS_W('\\')) TVPThrowExceptionMessage(TVPMissingPathDelimiterAtLast); ttstr normalized = TVPNormalizeStorageName(name); std::vector::iterator i = std::find(TVPAutoPathList.begin(), TVPAutoPathList.end(), normalized); if(i == TVPAutoPathList.end()) TVPAutoPathList.push_back(normalized); TVPClearAutoPathCache(); } //--------------------------------------------------------------------------- void TVPRemoveAutoPath(const ttstr &name) { tTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS); tjs_char lastchar = name.GetLastChar(); if(lastchar != TVPArchiveDelimiter && lastchar != TJS_W('/') && lastchar != TJS_W('\\')) TVPThrowExceptionMessage(TVPMissingPathDelimiterAtLast); ttstr normalized = TVPNormalizeStorageName(name); std::vector::iterator i = std::find(TVPAutoPathList.begin(), TVPAutoPathList.end(), normalized); if(i != TVPAutoPathList.end()) TVPAutoPathList.erase(i); TVPClearAutoPathCache(); } //--------------------------------------------------------------------------- static tjs_uint TVPRebuildAutoPathTable() { // rebuild auto path table if(AutoPathTableInit) return 0; tTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS); TVPAutoPathTable.Clear(); tjs_uint64 tick = TVPGetTickCount(); TVPAddLog( (const tjs_char*)TVPInfoRebuildingAutoPath ); tjs_uint totalcount = 0; std::vector::iterator it; for(it = TVPAutoPathList.begin(); it != TVPAutoPathList.end(); it++) { const ttstr & path = *it; tjs_uint count = 0; const tjs_char * sharp_pos = TJS_strchr(path.c_str(), TVPArchiveDelimiter); if(sharp_pos) { // this storagename indicates a file in an archive ttstr arcname(path, (int)(sharp_pos - path.c_str())); ttstr in_arc_name(sharp_pos + 1); tTVPArchive::NormalizeInArchiveStorageName(in_arc_name); tjs_int in_arc_name_len = in_arc_name.GetLen(); tTVPArchive *arc; arc = TVPArchiveCache.Get(arcname); try { tjs_uint storagecount = arc->GetCount(); // get first index which the item has 'in_arc_name' as its start // of the string. tjs_int i = arc->GetFirstIndexStartsWith(in_arc_name); if(i != -1) { for(; i < (tjs_int)storagecount; i++) { ttstr name = arc->GetName(i); if(name.StartsWith(in_arc_name)) { if(!TJS_strchr(name.c_str() + in_arc_name_len, TJS_W('/'))) { ttstr sname = TVPExtractStorageName(name); TVPAutoPathTable.Add(sname, path); count ++; } } else { // no need to check more; // because the list is sorted by the name. break; } } } } catch(...) { arc->Release(); throw; } arc->Release(); } else { // normal folder class tLister : public iTVPStorageLister { public: std::vector list; void TJS_INTF_METHOD Add(const ttstr &file) { list.push_back(file); } } lister; TVPStorageMediaManager.GetListAt(path, &lister); for(std::vector::iterator i = lister.list.begin(); i != lister.list.end(); i++) { TVPAutoPathTable.Add(*i, path); count ++; } } // TVPAddLog(ttstr(TJS_W("(info) Path ")) + path + TJS_W(" contains ") + // ttstr((tjs_int)count) + TJS_W(" file(s).")); totalcount += count; } tjs_uint64 endtick = TVPGetTickCount(); TVPAddLog(ttstr(TJS_W("(info) Total ")) + ttstr((tjs_int)totalcount) + TJS_W(" file(s) found, ") + ttstr((tjs_int)TVPAutoPathTable.GetCount()) + TJS_W(" file(s) activated.") + TJS_W(" (") + ttstr((tjs_int)(endtick - tick)) + TJS_W("ms)")); AutoPathTableInit = true; return totalcount; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetPlacedPath //--------------------------------------------------------------------------- ttstr TVPGetPlacedPath(const ttstr & name) { // search path and return the path which the "name" is placed. // returned name is normalized. returns empty string if the storage is not // found. #if 0 // needn't if(!TVPClearAutoPathCacheCallbackInit) { TVPAddCompactEventHook(&TVPClearAutoPathCacheCallback); TVPClearAutoPathCacheCallbackInit = true; } #endif ttstr * incache = TVPAutoPathCache.FindAndTouch(name); if(incache) return *incache; // found in cache tTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS); ttstr normalized(TVPNormalizeStorageName(name)); bool found = TVPIsExistentStorageNoSearchNoNormalize(normalized); if(found) { // found in current folder TVPAutoPathCache.Add(name, normalized); return normalized; } // not found in current folder // search through auto path table ttstr storagename = TVPExtractStorageName(normalized); TVPRebuildAutoPathTable(); // ensure auto path table ttstr *result = TVPAutoPathTable.Find(storagename); if(result) { // found in table ttstr found = *result + storagename; TVPAutoPathCache.Add(name, found); return found; } // not found // TVPAutoPathCache.Add(name, ttstr()); // do not cache now return ttstr(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPSearchPlacedPath //--------------------------------------------------------------------------- ttstr TVPSearchPlacedPath(const ttstr & name) { ttstr place = TVPGetPlacedPath(name); if(place.IsEmpty()) TVPThrowExceptionMessage(TVPCannotFindStorage, name); return place; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPIsExistentStorage //--------------------------------------------------------------------------- bool TVPIsExistentStorage(const ttstr &name) { return !TVPGetPlacedPath(name).IsEmpty(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCreateStream //--------------------------------------------------------------------------- static tTJSBinaryStream * _TVPCreateStream(const ttstr & _name, tjs_uint32 flags) { tTJSCriticalSectionHolder cs_holder(TVPCreateStreamCS); ttstr name; tjs_uint32 access = flags & TJS_BS_ACCESS_MASK; if(access == TJS_BS_WRITE) name = TVPNormalizeStorageName(_name); else name = TVPGetPlacedPath(_name); // file must exist if (name.IsEmpty()) { if (access >= 1) TVPRemoveFromStorageCache(_name); TVPThrowExceptionMessage(TVPCannotOpenStorage, _name); } // does name contain > ? const tjs_char * sharp_pos = TJS_strchr(name.c_str(), TVPArchiveDelimiter); if(sharp_pos) { // this storagename indicates a file in an archive if((flags & TJS_BS_ACCESS_MASK ) !=TJS_BS_READ) TVPThrowExceptionMessage(TVPCannotWriteToArchive); ttstr arcname(name, (int)(sharp_pos - name.c_str())); tTVPArchive *arc; tTJSBinaryStream *stream; arc = TVPArchiveCache.Get(arcname); try { ttstr in_arc_name(sharp_pos + 1); tTVPArchive::NormalizeInArchiveStorageName(in_arc_name); stream = arc->CreateStream(in_arc_name); } catch(...) { arc->Release(); if(access >= 1) TVPRemoveFromStorageCache(_name); throw; } if(access >= 1) TVPRemoveFromStorageCache(_name); arc->Release(); return stream; } tTJSBinaryStream *stream; try { stream = TVPStorageMediaManager.Open(name, flags); } catch(...) { if(access >= 1) TVPRemoveFromStorageCache(_name); throw; } if (access >= 1) TVPRemoveFromStorageCache(_name); return stream; } tTJSBinaryStream * TVPCreateStream(const ttstr & _name, tjs_uint32 flags) { try { return _TVPCreateStream(_name, flags); } catch(eTJSScriptException &e) { if(TJS_strchr(_name.c_str(), '#')) e.AppendMessage(TJS_W("[") + TVPFormatMessage(TVPFilenameContainsSharpWarn, _name) + TJS_W("]")); throw e; } catch(eTJSScriptError &e) { if(TJS_strchr(_name.c_str(), '#')) e.AppendMessage(TJS_W("[") + TVPFormatMessage(TVPFilenameContainsSharpWarn, _name) + TJS_W("]")); throw e; } catch(eTJSError &e) { if(TJS_strchr(_name.c_str(), '#')) e.AppendMessage(TJS_W("[") + TVPFormatMessage(TVPFilenameContainsSharpWarn, _name) + TJS_W("]")); throw e; } catch(...) { // check whether the filename contains '#' (former delimiter for archive // filename before 2.19 beta 14) if(TJS_strchr(_name.c_str(), '#')) TVPAddLog(TVPFormatMessage(TVPFilenameContainsSharpWarn, _name)); throw; } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPClearStorageCaches //--------------------------------------------------------------------------- void TVPClearStorageCaches() { // clear all storage related caches TVPClearXP3SegmentCache(); TVPClearAutoPathCache(); } //--------------------------------------------------------------------------- void TVPRemoveFromStorageCache(const ttstr &name) { TVPAutoPathCache.Delete(name); } //--------------------------------------------------------------------------- // tTJSNC_Storages //--------------------------------------------------------------------------- tjs_uint32 tTJSNC_Storages::ClassID = -1; tTJSNC_Storages::tTJSNC_Storages() : inherited(TJS_W("Storages")) { // registration of native members TJS_BEGIN_NATIVE_MEMBERS(Storages) TJS_DECL_EMPTY_FINALIZE_METHOD //---------------------------------------------------------------------- //-- methods //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/addAutoPath) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr path = *param[0]; TVPAddAutoPath(path); if(result) result->Clear(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/addAutoPath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/removeAutoPath) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr path = *param[0]; TVPRemoveAutoPath(path); if(result) result->Clear(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/removeAutoPath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getFullPath) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr path = *param[0]; if(result) *result = TVPNormalizeStorageName(path); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getFullPath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getPlacedPath) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr path = *param[0]; if(result) *result = TVPGetPlacedPath(path); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/getPlacedPath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/isExistentStorage) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr path = *param[0]; if(result) *result = (tjs_int)TVPIsExistentStorage(path); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/isExistentStorage) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/extractStorageExt) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr path = *param[0]; if(result) *result = TVPExtractStorageExt(path); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/extractStorageExt) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/extractStorageName) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr path = *param[0]; if(result) *result = TVPExtractStorageName(path); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/extractStorageName) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/extractStoragePath) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr path = *param[0]; if(result) *result = TVPExtractStoragePath(path); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/extractStoragePath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/chopStorageExt) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr path = *param[0]; if(result) *result = TVPChopStorageExt(path); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/chopStorageExt) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/clearArchiveCache) { TVPClearArchiveCache(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/clearArchiveCache) //---------------------------------------------------------------------- TJS_END_NATIVE_MEMBERS } //--------------------------------------------------------------------------- tTJSNativeInstance * tTJSNC_Storages::CreateNativeInstance() { // this class cannot create an instance TVPThrowExceptionMessage(TVPCannotCreateInstance); return NULL; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/StorageIntf.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Universal Storage System //--------------------------------------------------------------------------- #ifndef StorageIntfH #define StorageIntfH #include "tjsNative.h" #include "tjsHashSearch.h" #include //--------------------------------------------------------------------------- // archive delimiter //--------------------------------------------------------------------------- extern tjs_char TVPArchiveDelimiter; // = '>'; //--------------------------------------------------------------------------- // utilities //--------------------------------------------------------------------------- ttstr TVPStringFromBMPUnicode(const tjs_uint16 *src, tjs_int maxlen = -1); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPArchive base archive class //--------------------------------------------------------------------------- class tTVPArchive { private: tjs_uint RefCount; public: //-- constructor tTVPArchive(const ttstr & name) { ArchiveName = name; Init = false; RefCount = 1; } virtual ~tTVPArchive() { ; } //-- AddRef and Release void AddRef() { RefCount++; } void Release() { if(RefCount == 1) delete this; else RefCount--; } //-- must be implemented by delivered class virtual tjs_uint GetCount() = 0; virtual ttstr GetName(tjs_uint idx) = 0; // returned name must be already normalized using NormalizeInArchiveStorageName // and the index must be sorted by its name, using ttstr::operator < . // this is needed by fast directory search. virtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx) = 0; //-- others, implemented in this class private: tTJSHashTable, 1024> Hash; bool Init; public: ttstr ArchiveName; public: static void NormalizeInArchiveStorageName(ttstr & name); private: void AddToHash(); public: tTJSBinaryStream * CreateStream(const ttstr & name); bool IsExistent(const ttstr & name); tjs_int GetFirstIndexStartsWith(const ttstr & prefix); // returns first index which have 'prefix' at start of the name. }; //--------------------------------------------------------------------------- /*[*/ //--------------------------------------------------------------------------- // iTVPStorageMedia //--------------------------------------------------------------------------- /* abstract class for managing media ( like file: http: etc.) */ /*]*/ #if 0 /*[*/ // for plug-in class tTJSBinaryStream; /*]*/ #endif /*[*/ //--------------------------------------------------------------------------- class iTVPStorageLister // callback class for GetListAt { public: virtual void TJS_INTF_METHOD Add(const ttstr &file) = 0; }; //--------------------------------------------------------------------------- class iTVPStorageMedia { public: virtual ~iTVPStorageMedia() {} // add by ZeaS virtual void TJS_INTF_METHOD AddRef() = 0; virtual void TJS_INTF_METHOD Release() = 0; virtual void TJS_INTF_METHOD GetName(ttstr &name) = 0; // returns media name like "file", "http" etc. // virtual bool TJS_INTF_METHOD IsCaseSensitive() = 0; // returns whether this media is case sensitive or not virtual void TJS_INTF_METHOD NormalizeDomainName(ttstr &name) = 0; // normalize domain name according with the media's rule virtual void TJS_INTF_METHOD NormalizePathName(ttstr &name) = 0; // normalize path name according with the media's rule // "name" below is normalized but does not contain media, eg. // not "media://domain/path" but "domain/path" virtual bool TJS_INTF_METHOD CheckExistentStorage(const ttstr &name) = 0; // check file existence virtual tTJSBinaryStream * TJS_INTF_METHOD Open(const ttstr & name, tjs_uint32 flags) = 0; // open a storage and return a tTJSBinaryStream instance. // name does not contain in-archive storage name but // is normalized. virtual void TJS_INTF_METHOD GetListAt(const ttstr &name, iTVPStorageLister * lister) = 0; // list files at given place virtual void TJS_INTF_METHOD GetLocallyAccessibleName(ttstr &name) = 0; // basically the same as above, // check wether given name is easily accessible from local OS filesystem. // if true, returns local OS native name. otherwise returns an empty string. }; //--------------------------------------------------------------------------- /*]*/ //--------------------------------------------------------------------------- // must be implemented in each platform //--------------------------------------------------------------------------- extern tTVPArchive * TVPOpenArchive(const ttstr & name, bool normalizeFileName); // open archive and return tTVPArchive instance. TJS_EXP_FUNC_DEF(ttstr, TVPGetTemporaryName, ()); // retrieve file name to store temporary data ( must be unique, local name ) TJS_EXP_FUNC_DEF(ttstr, TVPGetAppPath, ()); // retrieve program path, in normalized storage name void TVPPreNormalizeStorageName(ttstr &name); // called by TVPNormalizeStorageName before it process the storage name. // user may pass the OS's native filename to the TVP storage system, // so that this function must convert it to the TVP storage name rules. iTVPStorageMedia * TVPCreateFileMedia(); // create basic default "file:" storage media /* extern void TVPPreNormalizeStorageName(ttstr &name); extern tTJSBinaryStream * TVPOpenStream(const ttstr & name, tjs_uint32 flags); // open a storage and return a tTJSBinaryStream instance. // name does not contain in-archive storage name but // is normalized. extern bool TVPCheckExistentStorage(const ttstr &name); // check file existence extern void TVPGetStorageListAt(const ttstr &name, std::vector & list); extern ttstr TVPGetMediaCurrent(const ttstr & name); extern void TVPSetMediaCurrent(const ttstr & name, const ttstr & dir); extern ttstr TVPGetNativeName(const ttstr &name); // retrieve OS native name extern ttstr TVPGetLocallyAccessibleName(const ttstr &name); // check wether given name is easily accessible from local OS filesystem. // if true, returns local OS native name. otherwise returns an empty string. */ extern bool TVPRemoveFile(const ttstr &name); // remove local file ( "name" is a local *native* name ) // this must not throw an exception ( return false if error ) extern bool TVPRemoveFolder(const ttstr &name); // remove local directory ( "name" is a local *native* name ) // this must not throw an exception ( return false if error ) bool TVPCreateFolders(const ttstr &folder); // create folder along with the argument recursively (like mkdir -p). // 'folder' must be a local native name. //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // implementation in this unit //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(void, TVPRegisterStorageMedia, (iTVPStorageMedia *media)); // register storage media TJS_EXP_FUNC_DEF(void, TVPUnregisterStorageMedia, (iTVPStorageMedia *media)); // remove storage media extern tTJSBinaryStream * TVPCreateStream(const ttstr & name, tjs_uint32 flags = 0); // open "name" and return tTJSBinaryStream instance. // name will be local storage, network storage, in-archive storage, etc... TJS_EXP_FUNC_DEF(bool, TVPIsExistentStorageNoSearch, (const ttstr &name)); // if "name" is exists, return true. otherwise return false. // this does not search any auto search path. TJS_EXP_FUNC_DEF(bool, TVPIsExistentStorageNoSearchNoNormalize, (const ttstr &name)); TJS_EXP_FUNC_DEF(ttstr, TVPNormalizeStorageName, (const ttstr & name)); TJS_EXP_FUNC_DEF(void, TVPSetCurrentDirectory, (const ttstr & name)); // set system current directory. // directory must end with path delimiter '/', // or archive delimiter '>'. TJS_EXP_FUNC_DEF(void, TVPGetLocalName, (ttstr &name)); ttstr TVPGetLocallyAccessibleName(const ttstr &name); TJS_EXP_FUNC_DEF(ttstr, TVPExtractStorageExt, (const ttstr & name)); // extract "name"'s extension and return it. TJS_EXP_FUNC_DEF(ttstr, TVPExtractStorageName, (const ttstr & name)); // extract "name"'s storage name ( excluding path ) and return it. TJS_EXP_FUNC_DEF(ttstr, TVPExtractStoragePath, (const ttstr & name)); // extract "name"'s path ( including last delimiter ) and return it. TJS_EXP_FUNC_DEF(ttstr, TVPChopStorageExt, (const ttstr & name)); // chop storage's extension and return it. // extensition delimiter '.' will not be held. TJS_EXP_FUNC_DEF(void, TVPAddAutoPath, (const ttstr & name)); // add given path to auto search path TJS_EXP_FUNC_DEF(void, TVPRemoveAutoPath, (const ttstr &name)); // remove given path from auto search path TJS_EXP_FUNC_DEF(ttstr, TVPGetPlacedPath, (const ttstr & name)); // search path and return the path which the "name" is placed. extern ttstr TVPSearchPlacedPath(const ttstr & name); // the same as TVPGetPlacedPath, except for rising exception when the storage // is not found. TJS_EXP_FUNC_DEF(bool, TVPIsExistentStorage, (const ttstr &name)); // if "name" is exists, return true. otherwise return false. // this searches auto search path. TJS_EXP_FUNC_DEF(void, TVPClearStorageCaches, ()); // clear all internal storage related caches. void TVPRemoveFromStorageCache(const ttstr &name); extern tjs_uint TVPSegmentCacheLimit; // XP3 segment cache limit, in bytes. //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTJSNC_Storages : TJS Storages class //--------------------------------------------------------------------------- class tTJSNC_Storages : public tTJSNativeClass { typedef tTJSNativeClass inherited; public: tTJSNC_Storages(); static tjs_uint32 ClassID; protected: tTJSNativeInstance *CreateNativeInstance(); }; //--------------------------------------------------------------------------- extern tTJSNativeClass * TVPCreateNativeClass_Storages(); //--------------------------------------------------------------------------- class tTVPStorageMedia : public iTVPStorageMedia { protected: tjs_int refCount; tTVPStorageMedia() : refCount(1) {} virtual void TJS_INTF_METHOD AddRef() override { refCount++; } virtual void TJS_INTF_METHOD Release() override { if (refCount == 1) { delete this; } else { refCount--; } } virtual void TJS_INTF_METHOD NormalizeDomainName(ttstr &name) override {} virtual void TJS_INTF_METHOD NormalizePathName(ttstr &name) override {} virtual void TJS_INTF_METHOD GetLocallyAccessibleName(ttstr &name) override {} }; class TArchiveStream : public tTJSBinaryStream { tTVPArchive *Owner; tjs_int64 CurrentPos; tjs_uint64 StartPos, DataLength; tTJSBinaryStream *_instr; public: TArchiveStream(tTVPArchive *owner, tjs_uint64 off, tjs_uint64 len); virtual ~TArchiveStream(); virtual tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence) { switch (whence) { case TJS_BS_SEEK_SET: CurrentPos = offset; break; case TJS_BS_SEEK_CUR: CurrentPos = offset + CurrentPos; break; case TJS_BS_SEEK_END: CurrentPos = offset + DataLength; break; } if (CurrentPos < 0) CurrentPos = 0; else if (CurrentPos > (tjs_int64)DataLength) CurrentPos = DataLength; _instr->SetPosition(CurrentPos + StartPos); return CurrentPos; } virtual tjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size) { if (CurrentPos + read_size >= (tjs_int64)DataLength) { read_size = (tjs_uint)(DataLength - CurrentPos); } _instr->ReadBuffer(buffer, read_size); CurrentPos += read_size; return read_size; } virtual tjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size) { return 0; } virtual tjs_uint64 TJS_INTF_METHOD GetSize() { return DataLength; } }; #endif ================================================ FILE: src/core/base/SysInitIntf.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // System Initialization and Uninitialization //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include #include #include #include "tjsUtils.h" #include "SysInitIntf.h" #include "ScriptMgnIntf.h" #include "tvpgl.h" // #include "Protect.h" //--------------------------------------------------------------------------- // global data //--------------------------------------------------------------------------- ttstr TVPProjectDir; // project directory (in unified storage name) ttstr TVPDataPath; // data directory (in unified storage name) //--------------------------------------------------------------------------- extern void TVPGL_C_Init(); //--------------------------------------------------------------------------- // TVPSystemInit : Entire System Initialization //--------------------------------------------------------------------------- void TVPSystemInit(void) { #if CC_TARGET_PLATFORM != CC_PLATFORM_WIN32 #ifndef CC_TARGET_OS_IPHONE if (!TVPProtectInit()) return; #endif //#else #ifdef USING_PROTECT while (!TVPProtectInit()) { TVPUpdateLicense(); } #endif #endif TVPBeforeSystemInit(); TVPInitScriptEngine(); TVPInitTVPGL(); // TVPGL_C_Init(); TVPAfterSystemInit(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPSystemUninit : System shutdown, cleanup, etc... //--------------------------------------------------------------------------- static void TVPCauseAtExit(); bool TVPSystemUninitCalled = false; void TVPSystemUninit(void) { if(TVPSystemUninitCalled) return; TVPSystemUninitCalled = true; TVPBeforeSystemUninit(); TVPUninitTVPGL(); try { TVPUninitScriptEngine(); } catch(...) { // ignore errors } TVPAfterSystemUninit(); TVPCauseAtExit(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPAddAtExitHandler related //--------------------------------------------------------------------------- struct tTVPAtExitInfo { tTVPAtExitInfo(tjs_int pri, void(*handler)()) { Priority = pri, Handler = handler; } tjs_int Priority; void (*Handler)(); bool operator <(const tTVPAtExitInfo & r) const { return this->Priority < r.Priority; } bool operator >(const tTVPAtExitInfo & r) const { return this->Priority > r.Priority; } bool operator ==(const tTVPAtExitInfo & r) const { return this->Priority == r.Priority; } }; static std::vector *TVPAtExitInfos = NULL; static bool TVPAtExitShutdown = false; //--------------------------------------------------------------------------- void TVPAddAtExitHandler(tjs_int pri, void (*handler)()) { if(TVPAtExitShutdown) return; if(!TVPAtExitInfos) TVPAtExitInfos = new std::vector(); TVPAtExitInfos->push_back(tTVPAtExitInfo(pri, handler)); } //--------------------------------------------------------------------------- static void TVPCauseAtExit() { if(TVPAtExitShutdown) return; TVPAtExitShutdown = true; std::sort(TVPAtExitInfos->begin(), TVPAtExitInfos->end()); // descending sort std::vector::iterator i; for(i = TVPAtExitInfos->begin(); i!=TVPAtExitInfos->end(); i++) { i->Handler(); } delete TVPAtExitInfos; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/SysInitIntf.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // System Initialization and Uninitialization //--------------------------------------------------------------------------- #ifndef SysInitIntfH #define SysInitIntfH //--------------------------------------------------------------------------- // System initialization and uninitialization //--------------------------------------------------------------------------- //-- global data extern ttstr TVPProjectDir; // project directory extern ttstr TVPDataPath; // data directory //-- implementation in this unit extern void TVPSystemInit(void); extern void TVPSystemUninit(void); //-- implement in each platform extern void TVPBeforeSystemInit(); // this must set TVPProjectDir extern void TVPAfterSystemInit(); extern void TVPBeforeSystemUninit(); extern void TVPAfterSystemUninit(); extern void TVPTerminateAsync(int code=0); // do acynchronous teminating of application extern void TVPTerminateSync(int code=0); // do synchronous teminating of application(never return) extern void TVPMainWindowClosed(); // called from WindowIntf.cpp, caused by closing main window. // this function must shutdown the application, unless the controller window is visible. //--------------------------------------------------------------------------- extern bool TVPSystemUninitCalled; // whether TVPSystemUninit is called or not //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // AtExit related //--------------------------------------------------------------------------- void TVPAddAtExitHandler(tjs_int pri, void (*handler)()); struct tTVPAtExit { tTVPAtExit(tjs_int pri, void (*handler)()) { TVPAddAtExitHandler(pri, handler); } }; #define TVP_ATEXIT_PRI_PREPARE 10 #define TVP_ATEXIT_PRI_SHUTDOWN 100 #define TVP_ATEXIT_PRI_RELEASE 1000 #define TVP_ATEXIT_PRI_CLEANUP 10000 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Command line parameter operations (implement in each platform) //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(bool, TVPGetCommandLine, (const tjs_char * name, tTJSVariant *value = NULL)); // retrieves command line parameter named "name". // command line parameter format must be "-name=value" // returns false if the the parameter is not exist, otherwise // sets the value to "value" and returns true. TJS_EXP_FUNC_DEF(tjs_int, TVPGetCommandLineArgumentGeneration, ()); // retrieves command line argument generation count. you can check // whether the command line options has changed, by comparing this value // to your value which is remembered when of previous call of this. TJS_EXP_FUNC_DEF(void, TVPSetCommandLine, (const tjs_char * name, const ttstr & value)); // sets command line to the specified value. // note that this function does not check any consistency or correctness of the value. //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/SystemIntf.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // "System" class interface //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include "tjsMessage.h" #include "SystemIntf.h" #include "SysInitIntf.h" #include "SysInitImpl.h" #include "MsgIntf.h" #include "GraphicsLoaderIntf.h" #include "EventIntf.h" #include "LayerIntf.h" #include "LayerBitmapIntf.h" #include "Random.h" #include "ScriptMgnIntf.h" #include "DebugIntf.h" #include "ConfigManager/LocaleConfigManager.h" #include "Platform.h" extern bool TVPStartupSuccess; //--------------------------------------------------------------------------- // TVPFireOnApplicationActivateEvent //--------------------------------------------------------------------------- void TVPFireOnApplicationActivateEvent(bool activate_or_deactivate) { // get the script engine tTJS *engine = TVPGetScriptEngine(); if(!engine) return; // the script engine had been shutdown // get System.onActivate or System.onDeactivate // and call it. iTJSDispatch2 * global = TVPGetScriptEngine()->GetGlobalNoAddRef(); if(!global) return; tTJSVariant val; tTJSVariant val2; tTJSVariantClosure clo; tTJSVariantClosure func; try { tjs_error er; er = global->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("System"), NULL, &val, global); if(TJS_FAILED(er)) return; if(val.Type() != tvtObject) return; clo = val.AsObjectClosureNoAddRef(); if(clo.Object == NULL) return; clo.PropGet(TJS_MEMBERMUSTEXIST, activate_or_deactivate? TJS_W("onActivate"): TJS_W("onDeactivate"), NULL, &val2, NULL); if(val2.Type() != tvtObject) return; func = val2.AsObjectClosureNoAddRef(); } catch(const eTJS &e) { // the system should not throw exceptions during retrieving the function TVPAddLog( TVPFormatMessage( TVPErrorInRetrievingSystemOnActivateOnDeactivate, e.GetMessage() ) ); return; } if(func.Object != NULL) func.FuncCall(0, NULL, NULL, NULL, 0, NULL, NULL); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTJSNC_System //--------------------------------------------------------------------------- tjs_uint32 tTJSNC_System::ClassID = -1; tTJSNC_System::tTJSNC_System() : inherited(TJS_W("System")) { // registration of native members TJS_BEGIN_NATIVE_MEMBERS(System) TJS_DECL_EMPTY_FINALIZE_METHOD //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_CONSTRUCTOR_DECL_NO_INSTANCE(/*TJS class name*/System) { return TJS_S_OK; } TJS_END_NATIVE_CONSTRUCTOR_DECL(/*TJS class name*/System) //---------------------------------------------------------------------- //-- methods //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/terminate) { int code = numparams > 0 ? param[0]->AsInteger() : 0; if (!TVPStartupSuccess) { ; } else { TVPTerminateAsync(code); } return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/terminate) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/exit) { // this method does not return int code = numparams > 0 ? param[0]->AsInteger() : 0; if (!TVPStartupSuccess) { ; } else { TVPTerminateSync(code); } return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/exit) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/inputString) { if(numparams < 3) return TJS_E_BADPARAMCOUNT; ttstr value = *param[2]; // bool b = TVPInputQuery(*param[0], *param[1], value); ttstr caption = *param[0], prompt = *param[1]; // this shows a dialog box which let user to input a string. // return false if the user selects "cancel", otherwise return true. // implement in each platform. std::vector btns; btns.emplace_back(LocaleConfigManager::GetInstance()->GetText("msgbox_ok")); btns.emplace_back(LocaleConfigManager::GetInstance()->GetText("cancel")); int ret = TVPShowSimpleInputBox(value, caption, prompt, btns); bool b = ret == 0; // the left button clicked if(result) { if(b) *result = value; else result->Clear(); } return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/inputString) //--------------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/addContinuousHandler) { // add function to continus handler list if(numparams < 1) return TJS_E_BADPARAMCOUNT; tTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef(); TVPAddContinuousHandler(clo); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/addContinuousHandler) //--------------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/removeContinuousHandler) { // remove function from continuous handler list if(numparams < 1) return TJS_E_BADPARAMCOUNT; tTJSVariantClosure clo = param[0]->AsObjectClosureNoAddRef(); TVPRemoveContinuousHandler(clo); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/removeContinuousHandler) //--------------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/toActualColor) { // convert color codes to 0xRRGGBB format. if(numparams < 1) return TJS_E_BADPARAMCOUNT; if(result) { tjs_uint32 color = (tjs_int)(*param[0]); color = TVPToActualColor(color); *result = (tjs_int)color; } return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/toActualColor) //--------------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/clearGraphicCache) { // clear graphic cache TVPClearGraphicCache(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/clearGraphicCache) //--------------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/touchImages) { // try to cache graphics if(numparams < 1) return TJS_E_BADPARAMCOUNT; std::vector storages; tTJSVariantClosure array = param[0]->AsObjectClosureNoAddRef(); tjs_int count = 0; while(true) { tTJSVariant val; if(TJS_FAILED(array.Object->PropGetByNum(0, count, &val, array.ObjThis))) break; if(val.Type() == tvtVoid) break; storages.push_back(ttstr(val)); count++; } tjs_int64 limit = 0; tjs_uint64 timeout = 0; if(numparams >= 2 && param[1]->Type() != tvtVoid) limit = (tjs_int64)*param[1]; if(numparams >= 3 && param[2]->Type() != tvtVoid) timeout = (tjs_int64)*param[2]; TVPTouchImages(storages, limit, timeout); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/touchImages) //--------------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/createUUID) { // create UUID // return UUID string in form of "43abda37-c597-4646-a279-c27a1373af90" tjs_uint8 uuid[16]; TVPGetRandomBits128(uuid); uuid[8] &= 0x3f; uuid[8] |= 0x80; // override clock_seq uuid[6] &= 0x0f; uuid[6] |= 0x40; // override version tjs_char buf[40]; TJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"), uuid[ 0], uuid[ 1], uuid[ 2], uuid[ 3], uuid[ 4], uuid[ 5], uuid[ 6], uuid[ 7], uuid[ 8], uuid[ 9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]); if(result) *result = tTJSVariant(buf); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/createUUID) //--------------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/assignMessage) { // assign system message if(numparams < 2) return TJS_E_BADPARAMCOUNT; ttstr id(*param[0]); ttstr msg(*param[1]); bool res = TJSAssignMessage(id.c_str(), msg.c_str()); if(result) *result = tTJSVariant((tjs_int)res); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/assignMessage) //--------------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/doCompact) { // compact memory usage tjs_int level = TVP_COMPACT_LEVEL_MAX; if(numparams >= 1 && param[0]->Type() != tvtVoid) level = (tjs_int)*param[0]; TVPDeliverCompactEvent(level); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL(/*func. name*/doCompact) //---------------------------------------------------------------------- //--properties //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(versionString) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetVersionString(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(versionString) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(versionInformation) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetVersionInformation(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(versionInformation) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(eventDisabled) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetSystemEventDisabledState(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_BEGIN_NATIVE_PROP_SETTER { TVPSetSystemEventDisabledState(param->operator bool()); return TJS_S_OK; } TJS_END_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(eventDisabled) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(graphicCacheLimit) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = (tjs_int)TVPGetGraphicCacheLimit(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_BEGIN_NATIVE_PROP_SETTER { TVPSetGraphicCacheLimit((tjs_int)*param); return TJS_S_OK; } TJS_END_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(graphicCacheLimit) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(platformName) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetPlatformName(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(platformName) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(osName) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetOSName(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(osName) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(exitOnWindowClose) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPTerminateOnWindowClose; return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_BEGIN_NATIVE_PROP_SETTER { TVPTerminateOnWindowClose = 0!=(tjs_int)*param; return TJS_S_OK; } TJS_END_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(exitOnWindowClose) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(drawThreadNum) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPDrawThreadNum; return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_BEGIN_NATIVE_PROP_SETTER { TVPDrawThreadNum = (tjs_int)*param; return TJS_S_OK; } TJS_END_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(drawThreadNum) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(processorNum) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetProcessorNum(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(processorNum) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(exeBits) { TJS_BEGIN_NATIVE_PROP_GETTER { #ifdef TJS_64BIT_OS *result = 64; #else *result = 32; #endif return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(exeBits) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(osBits) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetOSBits(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(osBits) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(exitOnNoWindowStartup) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPTerminateOnNoWindowStartup; return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_BEGIN_NATIVE_PROP_SETTER { TVPTerminateOnNoWindowStartup = 0!=(tjs_int)*param; return TJS_S_OK; } TJS_END_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL(exitOnNoWindowStartup) //---------------------------------------------------------------------- TJS_END_NATIVE_MEMBERS // register default "exceptionHandler" member tTJSVariant val((iTJSDispatch2*)NULL, (iTJSDispatch2*)NULL); PropSet(TJS_MEMBERENSURE, TJS_W("exceptionHandler"), NULL, &val, this); // and onActivate, onDeactivate PropSet(TJS_MEMBERENSURE, TJS_W("onActivate"), NULL, &val, this); PropSet(TJS_MEMBERENSURE, TJS_W("onDeactivate"), NULL, &val, this); } //--------------------------------------------------------------------------- tTJSNativeInstance * tTJSNC_System::CreateNativeInstance() { // this class cannot create an instance TVPThrowExceptionMessage(TVPCannotCreateInstance); return NULL; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/SystemIntf.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // "System" class interface //--------------------------------------------------------------------------- #ifndef SystemIntfH #define SystemIntfH #include "tjsNative.h" //--------------------------------------------------------------------------- // tTJSNC_System : TJS System class //--------------------------------------------------------------------------- class tTJSNC_System : public tTJSNativeClass { typedef tTJSNativeClass inherited; public: tTJSNC_System(); static tjs_uint32 ClassID; protected: tTJSNativeInstance *CreateNativeInstance(); }; //--------------------------------------------------------------------------- extern tTJSNativeClass * TVPCreateNativeClass_System(); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(ttstr, TVPGetPlatformName, ()); // retrieve platform name (eg. "Win32") // implement in each platform. TJS_EXP_FUNC_DEF(ttstr, TVPGetOSName, ()); // retrieve OS name // implement in each platform. extern void TVPFireOnApplicationActivateEvent(bool activate_or_deactivate); extern tjs_int TVPGetOSBits(); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/TARArchive.cpp ================================================ #include "tjsCommHead.h" #include "StorageIntf.h" #include "UtilStreams.h" #include "Platform.h" #include "MsgIntf.h" #include void TVPFreeArchiveHandlePoolByPointer(void * pointer); void TVPReleaseCachedArchiveHandle(void * pointer, tTJSBinaryStream * stream); void storeFilename(ttstr &name, const char *narrowName, const ttstr &filename) { tjs_int len = TJS_narrowtowidelen(narrowName); if (len == -1) { ttstr msg("Filename is not encoded in UTF8 in archive:\n"); TVPShowSimpleMessageBox(msg + filename, TJS_W("Error")); TVPThrowExceptionMessage(TJS_W("Invalid archive entry name")); } tjs_char *p = name.AllocBuffer(len); p[TJS_narrowtowide(p, narrowName, len)] = 0; name.FixLen(); } //--------------------------------------------------------------------------- // tar archive //--------------------------------------------------------------------------- tjs_uint64 parseOctNum(const char *oct, int length) { tjs_uint64 num = 0; for (int i = 0; i < length; i++){ char c = oct[i]; if ('0' <= c && c <= '9'){ num = num * 8 + (c - '0'); } } return num; } #include "tar.h" class TARArchive : public tTVPArchive { struct EntryInfo { ttstr filename; tjs_uint64 offset; tjs_uint64 size; }; std::vector filelist; friend class TARArchiveStream; public: TARArchive(const ttstr & arcname) : tTVPArchive(arcname) { } ~TARArchive() { TVPFreeArchiveHandlePoolByPointer(this); } bool init(tTJSBinaryStream * _instr, bool normalizeFileName) { if (_instr) { tjs_uint64 archiveSize = _instr->GetSize(); TAR_HEADER tar_header; // check first header if (_instr->Read(&tar_header, sizeof(tar_header)) != sizeof(tar_header)) { //delete _instr; return false; } unsigned int checksum = parseOctNum(tar_header.dbuf.chksum, sizeof(tar_header.dbuf.chksum)); if (checksum != tar_header.compsum() && (int)checksum != tar_header.compsum_oldtar()) { //delete _instr; return false; } _instr->SetPosition(0); while (_instr->GetPosition() <= archiveSize - sizeof(tar_header)) { if (_instr->Read(&tar_header, sizeof(tar_header)) != sizeof(tar_header)) break; tjs_uint64 original_size = parseOctNum(tar_header.dbuf.size, sizeof(tar_header.dbuf.size)); std::vector filename; if (tar_header.dbuf.typeflag == LONGLINK) { // tar_header.dbuf.name == "././@LongLink" unsigned int readsize = (original_size + (TBLOCK - 1)) & ~(TBLOCK - 1); filename.resize(readsize + 1); //TODO:size lost if (_instr->Read(&filename[0], readsize) != readsize) break; filename[readsize] = 0; if (_instr->Read(&tar_header, sizeof(tar_header)) != sizeof(tar_header)) break; original_size = parseOctNum(tar_header.dbuf.size, sizeof(tar_header.dbuf.size)); } if (tar_header.dbuf.typeflag != REGTYPE) continue; // only accept regular file if (filename.empty()) { filename.resize(101); memcpy(&filename[0], tar_header.dbuf.name, sizeof(tar_header.dbuf.name)); filename[100] = 0; } EntryInfo item; storeFilename(item.filename, &filename[0], ArchiveName); if (normalizeFileName) NormalizeInArchiveStorageName(item.filename); item.size = original_size; item.offset = _instr->GetPosition(); filelist.emplace_back(item); tjs_uint64 readsize = (original_size + (TBLOCK - 1)) & ~(TBLOCK - 1); _instr->SetPosition(item.offset + readsize); } if (normalizeFileName) { std::sort(filelist.begin(), filelist.end(), [](const EntryInfo& a, const EntryInfo& b) { return a.filename < b.filename; }); } TVPReleaseCachedArchiveHandle(this, _instr); return true; } return false; } virtual tjs_uint GetCount() { return filelist.size(); } virtual ttstr GetName(tjs_uint idx) { return filelist[idx].filename; } virtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx); }; tTJSBinaryStream * TARArchive::CreateStreamByIndex(tjs_uint idx) { const EntryInfo &info = filelist[idx]; return new TArchiveStream(this, info.offset, info.size); } tTVPArchive * TVPOpenTARArchive(const ttstr & name, tTJSBinaryStream * st, bool normalizeFileName) { TARArchive *arc = new TARArchive(name); if (!arc->init(st, normalizeFileName)) { delete arc; return nullptr; } return arc; } ================================================ FILE: src/core/base/TextStream.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Text read/write stream //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include #include "TextStream.h" #include "MsgIntf.h" #include "DebugIntf.h" #include "EventIntf.h" #include "UtilStreams.h" #include "tjsError.h" #include "CharacterSet.h" extern "C" int sjis_mbtowc(unsigned short *wc, const unsigned char *s); extern "C" int gbk_mbtowc(unsigned short *wc, const unsigned char *s); int utf8_mbtowc(unsigned short *pwc, const unsigned char *s) { unsigned char c = s[0]; if (c < 0x80) { *pwc = c; return 1; } else if (c < 0xc2) { return -1; } else if (c < 0xe0) { if (!((s[1] ^ 0x80) < 0x40)) return -1; *pwc = ((unsigned short)(c & 0x1f) << 6) | (unsigned short)(s[1] ^ 0x80); return 2; } else if (c < 0xf0) { if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 && (c >= 0xe1 || s[1] >= 0xa0))) return -1; *pwc = ((unsigned short)(c & 0x0f) << 12) | ((unsigned short)(s[1] ^ 0x80) << 6) | (unsigned short)(s[2] ^ 0x80); return 3; } else return -1; } int(*mbtowc_for_text_stream)(unsigned short *wc, const unsigned char *s) = nullptr; static size_t _TextStream_mbstowcs(int(*func_mbtowc)(unsigned short *, const unsigned char *), tjs_char *pwcs, const tjs_nchar *s, size_t n) { if(!s) return -1; if(pwcs && n == 0) return 0; size_t count = 0; int cl; if(!pwcs) { while(*s) { unsigned short wc; cl = func_mbtowc(&wc, (const unsigned char*)s); if(cl <= 0) return -1; s += cl; ++count; } } else { while(*s && n > 0) { cl = func_mbtowc((unsigned short *)pwcs, (const unsigned char*)s); if(cl <= 0) return -1; n --; s += cl; pwcs++; ++count; } } return count; } /* Text stream is used by TJS's Array.save, Dictionary.saveStruct etc. to input/output text files. */ extern size_t TextStream_mbstowcs(tjs_char *pwcs, const tjs_nchar *s, size_t n) { if (mbtowc_for_text_stream) { return _TextStream_mbstowcs(mbtowc_for_text_stream, pwcs, s, n); } // trying every encoding available size_t ret = _TextStream_mbstowcs(sjis_mbtowc, pwcs, s, n); if (ret == (size_t)-1) { ret = _TextStream_mbstowcs(utf8_mbtowc, pwcs, s, n); if (ret != (size_t)-1) { mbtowc_for_text_stream = utf8_mbtowc; return ret; } ret = _TextStream_mbstowcs(gbk_mbtowc, pwcs, s, n); if (ret != (size_t)-1) { mbtowc_for_text_stream = gbk_mbtowc; return ret; } } return ret; } static ttstr enc_utf8 = TJS_W("utf8"), enc_utf8_2 = TJS_W("utf-8"), enc_utf16 = TJS_W("utf16"), enc_utf16_2 = TJS_W("utf-16"), enc_gbk = TJS_W("gbk"), enc_jis = TJS_W("sjis"), enc_jis_2 = TJS_W("shiftjis"), enc_jis_3 = TJS_W("shift_jis"), enc_jis_4 = TJS_W("shift-jis"); bool TVPStringDecode(const void *p, int len, ttstr& result, ttstr encoding /*= "utf8"*/) { if (encoding == enc_utf8 || encoding == enc_utf8_2) { int n = (int)TJS_mbstowcs(NULL, (char*)p, len); if (n == -1) return false; TJS_mbstowcs(result.AllocBuffer(n), (char*)p, len); } else if (encoding == enc_utf16 || encoding == enc_utf16_2) { memcpy(result.AllocBuffer(len / 2), p, len); result.FixLen(); } else if (encoding == enc_jis || encoding == enc_jis_2 || encoding == enc_jis_3 || encoding == enc_jis_4) { int n = _TextStream_mbstowcs(sjis_mbtowc, NULL, (char*)p, len); if (n == -1) return false; _TextStream_mbstowcs(sjis_mbtowc, result.AllocBuffer(n), (char*)p, len); } else if (encoding == enc_gbk) { int n = _TextStream_mbstowcs(gbk_mbtowc, NULL, (char*)p, len); if (n == -1) return false; _TextStream_mbstowcs(gbk_mbtowc, result.AllocBuffer(n), (char*)p, len); } else { return false; } return true; } bool TVPStringEncode(const ttstr &src, std::string &result, ttstr encoding /*= "utf8"*/) { if (encoding == enc_utf8 || encoding == enc_utf8_2) { result = src.AsNarrowStdString(); } else if (encoding == enc_utf16 || encoding == enc_utf16_2) { result.resize(src.length() * 2); memcpy((char*)result.c_str(), src.c_str(), src.length() * 2); // } else if (encoding == enc_jis || encoding == enc_jis_2 || encoding == enc_jis_3 || encoding == enc_jis_4) { // } else if (encoding == enc_gbk) { // unsupported yet } else { return false; } return true; } #ifdef TVP_TEXT_READ_ANSI_MBCS static ttstr DefaultReadEncoding = TJS_W("Shift_JIS"); #else static ttstr DefaultReadEncoding = TJS_W("UTF-8"); #endif //--------------------------------------------------------------------------- // Interface to tTJSTextStream //--------------------------------------------------------------------------- /* note: encryption of mode 0 or 1 ( simple crypt ) does never intend data pretection security. */ class tTVPTextReadStream : public iTJSTextReadStream { tTJSBinaryStream * Stream; bool DirectLoad; tjs_char *Buffer; size_t BufferLen; tjs_char *BufferPtr; tjs_int CryptMode; public: tTVPTextReadStream(const ttstr & name, const ttstr & modestr) { // following syntax of modestr is currently supported. // oN: read from binary offset N (in bytes) #ifndef TVP_NO_CHECK_WIDE_CHAR_SIZE if(sizeof(tjs_char) != 2) TVPThrowExceptionMessage( TVPTheHostIsNotA16BitUnicodeSystem ); #endif Stream = NULL; Buffer = NULL; DirectLoad = false; CryptMode = -1; // check o mode Stream = TVPCreateStream(name, TJS_BS_READ); tjs_uint64 ofs = 0; const tjs_char * o_ofs; o_ofs = TJS_strchr(modestr.c_str(), TJS_W('o')); if(o_ofs != NULL) { // seek to offset o_ofs++; tjs_char buf[256]; int i; for(i = 0; i < 255; i++) { if(o_ofs[i] >= TJS_W('0') && o_ofs[i] <= TJS_W('9')) buf[i] = o_ofs[i]; else break; } buf[i] = 0; ofs = ttstr(buf).AsInteger(); Stream->SetPosition(ofs); } // check first of the file - whether the file is unicode try { tjs_uint8 mark[3] = {0,0}; Stream->Read(mark, 3); if(mark[0] == 0xff && mark[1] == 0xfe) { // unicode Stream->SetPosition(ofs + 2); DirectLoad = true; } else if(mark[0] == 0xfe && mark[1] == 0xfe) { // ciphered text or compressed tjs_uint8 mode = mark[2]; if(mode != 0 && mode != 1 && mode != 2) TVPThrowExceptionMessage(TVPUnsupportedCipherMode, name); // currently only mode0 and mode1, and compressed (mode2) are supported CryptMode = mode; DirectLoad = CryptMode != 2; Stream->Read(mark, 2); // original bom code comes here (is not compressed) if(mark[0] != 0xff || mark[1] != 0xfe) TVPThrowExceptionMessage(TVPUnsupportedCipherMode, name); if(CryptMode == 2) { // compressed text stream tjs_uint64 compressed = Stream->ReadI64LE(); tjs_uint64 uncompressed = Stream->ReadI64LE(); if(compressed != (unsigned long)compressed || uncompressed != (unsigned long)uncompressed) TVPThrowExceptionMessage(TVPUnsupportedCipherMode, name); // too large stream unsigned long destlen ; tjs_uint8 *nbuf = new tjs_uint8[(unsigned long)compressed + 1]; try { Stream->ReadBuffer(nbuf, (unsigned long)compressed); Buffer = new tjs_char [ (BufferLen = (destlen = (unsigned long)uncompressed) / 2) + 1]; int result = uncompress( /* uncompress from zlib */ (unsigned char*)Buffer, &destlen, (unsigned char*)nbuf, (unsigned long)compressed); if(result != Z_OK || destlen != (unsigned long)uncompressed) TVPThrowExceptionMessage(TVPUnsupportedCipherMode, name); // uncompression failed. } catch(...) { delete [] nbuf; throw; } delete [] nbuf; Buffer[BufferLen] = 0; BufferPtr = Buffer; } } else { // check UTF-8 BOM if(mark[0] == 0xef && mark[1] == 0xbb && mark[2] == 0xbf) { // UTF-8 BOM tjs_uint size = (tjs_uint)(Stream->GetSize() - 3) - ofs; tjs_uint8 *nbuf = new tjs_uint8[size + 1]; try { Stream->ReadBuffer(nbuf, size); nbuf[size] = 0; // terminater BufferLen = TVPUtf8ToWideCharString((const char*)nbuf, NULL); if(BufferLen == (size_t)-1) TVPThrowExceptionMessage(TJSNarrowToWideConversionError); Buffer = new tjs_char [ BufferLen +1]; TVPUtf8ToWideCharString((const char*)nbuf, Buffer); } catch(...) { delete [] nbuf; throw; } delete [] nbuf; Buffer[BufferLen] = 0; BufferPtr = Buffer; } else { // ansi/mbcs // read whole and hold it Stream->SetPosition(ofs); tjs_uint size = (tjs_uint)(Stream->GetSize()) - ofs; tjs_uint8 *nbuf = new tjs_uint8[size + 1]; try { Stream->ReadBuffer(nbuf, size); nbuf[size] = 0; // terminater BufferLen = TextStream_mbstowcs(NULL, (tjs_nchar*)nbuf, 0); if (BufferLen == (size_t)-1) { ttstr msg(TVPGetMessageByLocale("err_narrow_to_wide")); TVPThrowExceptionMessage(msg.c_str()); } Buffer = new tjs_char [ BufferLen +1]; TextStream_mbstowcs(Buffer, (tjs_nchar*)nbuf, BufferLen); } catch(...) { delete [] nbuf; throw; } delete [] nbuf; Buffer[BufferLen] = 0; BufferPtr = Buffer; } } } catch(...) { delete Stream; Stream = NULL; throw; } } ~tTVPTextReadStream() { if(Stream) delete Stream; if(Buffer) delete [] Buffer; } tjs_uint TJS_INTF_METHOD Read(tTJSString & targ, tjs_uint size) { if(DirectLoad) { if(sizeof(tjs_char) == 2) { if(size == 0) size = static_cast(Stream->GetSize() - Stream->GetPosition()); if(!size) { targ.Clear(); return 0; } tjs_char *buf = targ.AllocBuffer(size); tjs_uint read = Stream->Read(buf, size * 2); // 2 = BMP unicode size read /= 2; #if TJS_HOST_IS_BIG_ENDIAN // re-order input for(tjs_uint i = 0; i> 8) & 0xff) + ((ch & 0xff) << 8); } #endif if(CryptMode == 0) { // simple crypt for(tjs_uint i = 0; i= 0x20) buf[i] = ch ^ (((ch&0xfe) << 8)^1); } } else if(CryptMode == 1) { // simple crypt for(tjs_uint i = 0; i>1) | ((ch & 0x55555555)<<1); buf[i] = ch; } } buf[read] = 0; targ.FixLen(); return read; } else { // sizeof(tjs_char) is 4 // FIXME: NOT TESTED CODE if(size == 0) size = static_cast(Stream->GetSize() - Stream->GetPosition()); tjs_uint16 *buf = new tjs_uint16[size / 2]; tjs_uint read; try { read = Stream->Read(buf, size * 2); // 2 = BMP unicode size read /= 2; #if TJS_HOST_IS_BIG_ENDIAN // re-order input for(tjs_uint i = 0; i> 8) & 0xff) + ((ch & 0xff) << 8); } #endif if(CryptMode == 0) { // simple crypt (buggy version) for(tjs_uint i = 0; i= 0x20) buf[i] = ch ^ (((ch&0xfe) << 8)^1); } } else if(CryptMode == 1) { // simple crypt for(tjs_uint i = 0; i>1) | ((ch & 0x55555555)<<1); buf[i] = ch; } } buf[read] = 0; } catch(...) { delete [] buf; throw; } targ = TVPStringFromBMPUnicode(buf); delete [] buf; return read; } } else { if(size == 0) size = (tjs_uint)BufferLen; if(size) { tjs_char *buf = targ.AllocBuffer(size); TJS_strncpy(buf, BufferPtr, size); buf[size] = 0; BufferPtr += size; BufferLen -= size; targ.FixLen(); } else { targ.Clear(); } return size; } } void TJS_INTF_METHOD Destruct() { delete this; } }; //--------------------------------------------------------------------------- class tTVPTextWriteStream : public iTJSTextWriteStream { // TODO: 32bit wchar_t support static const tjs_uint COMPRESSION_BUFFER_SIZE = 1024 * 1024; tTJSBinaryStream * Stream; tjs_int CryptMode; // -1 for no-crypt // 0: (unused) (old buggy crypt mode) // 1: simple crypt // 2: complessed int CompressionLevel; // compression level of zlib z_stream_s *ZStream; tjs_uint CompressionSizePosition; tjs_nchar *CompressionBuffer; bool CompressionFailed; public: tTVPTextWriteStream(const ttstr & name, const ttstr &modestr) { // modestr supports following modes: // dN: deflate(compress) at mode N ( currently not implemented ) // cN: write in cipher at mode N ( currently n is ignored ) // zN: write with compress at mode N ( N is compression level ) // oN: write from binary offset N (in bytes) Stream = NULL; CryptMode = -1; CompressionLevel = Z_DEFAULT_COMPRESSION; ZStream = NULL; CompressionSizePosition = 0; CompressionBuffer = NULL; CompressionFailed = false; // check c/z mode const tjs_char *p; if((p = TJS_strchr(modestr.c_str(), TJS_W('c'))) != NULL) { CryptMode = 1; // simple crypt if(p[1] >= TJS_W('0') && p[1] <= TJS_W('9')) CryptMode = p[1] - TJS_W('0'); } if((p = TJS_strchr(modestr.c_str(), TJS_W('z'))) != NULL) { CryptMode = 2; // compressed (cannot be with 'c') if(p[1] >= TJS_W('0') && p[1] <= TJS_W('9')) CompressionLevel = p[1] - TJS_W('0'); } if(CryptMode != -1 && CryptMode != 1 && CryptMode != 2) TVPThrowExceptionMessage(TVPUnsupportedModeString, TJS_W("unsupported cipher mode")); // check o mode const tjs_char * o_ofs; o_ofs = TJS_strchr(modestr.c_str(), TJS_W('o')); if(o_ofs != NULL) { // seek to offset o_ofs++; tjs_char buf[256]; int i; for(i = 0; i < 255; i++) { if(o_ofs[i] >= TJS_W('0') && o_ofs[i] <= TJS_W('9')) buf[i] = o_ofs[i]; else break; } buf[i] = 0; tjs_uint64 ofs = ttstr(buf).AsInteger(); Stream = TVPCreateStream(name, TJS_BS_UPDATE); Stream->SetPosition(ofs); } else { Stream = TVPCreateStream(name, TJS_BS_WRITE); } if(CryptMode == 1 || CryptMode == 2) { // simple crypt or compressed tjs_uint8 crypt_mode_sig[4]; crypt_mode_sig[0] = crypt_mode_sig[1] = 0xfe; crypt_mode_sig[2] = (tjs_uint8)CryptMode; crypt_mode_sig[3] = 0; Stream->WriteBuffer(crypt_mode_sig, 3); } // now output text stream will write unicode texts static tjs_uint8 bommark[4] = { 0xff, 0xfe, 0x00, 0x00/*dummy 2bytes*/ }; Stream->WriteBuffer(bommark, 2); if(CryptMode == 2) { // allocate and initialize zlib straem ZStream = new z_stream_s(); ZStream->zalloc = Z_NULL; ZStream->zfree = Z_NULL; ZStream->opaque = Z_NULL; if (deflateInit(ZStream, CompressionLevel) != Z_OK) { CompressionFailed = true; TVPThrowExceptionMessage(TVPCompressionFailed); } CompressionBuffer = new tjs_nchar[COMPRESSION_BUFFER_SIZE]; ZStream->next_in = NULL; ZStream->avail_in = 0; ZStream->next_out = reinterpret_cast( CompressionBuffer ); ZStream->avail_out = COMPRESSION_BUFFER_SIZE; // Compression Size (write dummy) CompressionSizePosition = static_cast(Stream->GetPosition()); WriteI64LE((tjs_uint64)0); WriteI64LE((tjs_uint64)0); } } ~tTVPTextWriteStream() { if(CryptMode == 2) { if (! CompressionFailed) { try { // close zlib stream int result = 0; do { result = deflate(ZStream, Z_FINISH); if (result != Z_OK && result != Z_STREAM_END) { TVPThrowExceptionMessage(TVPCompressionFailed); } Stream->WriteBuffer(CompressionBuffer, COMPRESSION_BUFFER_SIZE - ZStream->avail_out); ZStream->next_out = reinterpret_cast( CompressionBuffer ); ZStream->avail_out = COMPRESSION_BUFFER_SIZE; } while (result != Z_STREAM_END); // rollback and write compression size. Stream->SetPosition(CompressionSizePosition); WriteI64LE((tjs_uint64)ZStream->total_out); WriteI64LE((tjs_uint64)ZStream->total_in); } catch(...) { // delete zlib compress stream if (ZStream) { deflateEnd(ZStream); delete ZStream; } delete[] CompressionBuffer; delete Stream; throw; } } // delete zlib compress stream if (ZStream) { deflateEnd(ZStream); delete ZStream; } delete[] CompressionBuffer; } if(Stream) delete Stream; } void WriteI64LE(tjs_uint64 v) { // write 64bit little endian value to the file. tjs_uint8 buf[8]; buf[0] = (tjs_uint8)(v >> (0*8)); buf[1] = (tjs_uint8)(v >> (1*8)); buf[2] = (tjs_uint8)(v >> (2*8)); buf[3] = (tjs_uint8)(v >> (3*8)); buf[4] = (tjs_uint8)(v >> (4*8)); buf[5] = (tjs_uint8)(v >> (5*8)); buf[6] = (tjs_uint8)(v >> (6*8)); buf[7] = (tjs_uint8)(v >> (7*8)); Stream->WriteBuffer(buf, 8); } void TJS_INTF_METHOD Write(const ttstr & targ) { tjs_uint16 *buf; tjs_int len = targ.GetLen(); buf = new tjs_uint16 [len + 1]; try { const tjs_char *src = targ.c_str(); tjs_int i; for(i = 0; i < len; i++) { if(src[i] < 0x10000) buf[i] = src[i]; else buf[i] = TJS_W('?'); } buf[i] = 0; #if TJS_HOST_IS_BIG_ENDIAN tjs_uint16 *p; if(CryptMode == 1) { // simple crypt p = buf; if(p) { while(*p) { tjs_char ch = *p; ch = ((ch & 0xaaaaaaaa)>>1) | ((ch & 0x55555555)<<1); *p = ch; p++; } } } // re-order to little endian unicode text p = buf; if(p) { while(*p) { *p = ((*p >> 8) & 0xff) + ((*p & 0xff) << 8); p++; } } WriteRawData(str.c_str(), len * sizeof(tjs_char)); #else if(CryptMode == 1) { // simple crypt tjs_uint16 *p; p = buf; if(p) { while(*p) { tjs_char ch = *p; ch = ((ch & 0xaaaaaaaa)>>1) | ((ch & 0x55555555)<<1); *p = ch; p++; } } WriteRawData(buf, len * sizeof(tjs_uint16)); } else { WriteRawData(buf, len * sizeof(tjs_uint16)); } #endif } catch(...) { delete [] buf; throw; } delete [] buf; } void WriteRawData(void *ptr, size_t size) { if(CryptMode == 2) { // compressed with zlib stream. ZStream->next_in = (Bytef*)ptr; ZStream->avail_in = (uInt)size; while (ZStream->avail_in > 0) { int result = deflate(ZStream, Z_NO_FLUSH); if (result != Z_OK) { CompressionFailed = true; TVPThrowExceptionMessage(TVPCompressionFailed); } if (ZStream->avail_out == 0) { Stream->WriteBuffer(CompressionBuffer, COMPRESSION_BUFFER_SIZE); ZStream->next_out = reinterpret_cast( CompressionBuffer ); ZStream->avail_out = COMPRESSION_BUFFER_SIZE; } } } else { Stream->WriteBuffer(ptr, (tjs_uint)size); // write directly } } void TJS_INTF_METHOD Destruct() { delete this; } }; //--------------------------------------------------------------------------- iTJSTextReadStream * TVPCreateTextStreamForRead(const ttstr & name, const ttstr & modestr) { return new tTVPTextReadStream(name, modestr); } //--------------------------------------------------------------------------- iTJSTextReadStream * TVPCreateTextStreamForReadByEncoding(const ttstr & name, const ttstr & modestr) { return new tTVPTextReadStream(name, modestr); } //--------------------------------------------------------------------------- iTJSTextWriteStream * TVPCreateTextStreamForWrite(const ttstr & name, const ttstr & modestr) { return new tTVPTextWriteStream(name, modestr); } //--------------------------------------------------------------------------- void TVPSetDefaultReadEncoding(const ttstr& encoding) { DefaultReadEncoding = encoding; ttstr codestr = encoding; codestr.ToLowerCase(); if (codestr == enc_gbk) { mbtowc_for_text_stream = gbk_mbtowc; } else if (codestr == enc_utf8 || codestr == enc_utf8_2) { mbtowc_for_text_stream = utf8_mbtowc; } else if (codestr == enc_jis || codestr == enc_jis_2 || codestr == enc_jis_3 || codestr == enc_jis_4) { mbtowc_for_text_stream = sjis_mbtowc; } else { TVPThrowExceptionMessage(TVPUnsupportedEncoding, encoding); } } //--------------------------------------------------------------------------- const tjs_char* TVPGetDefaultReadEncoding() { return DefaultReadEncoding.c_str(); } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/TextStream.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Text read/write stream //--------------------------------------------------------------------------- #ifndef TextStreamH #define TextStreamH #include "StorageIntf.h" //--------------------------------------------------------------------------- // TextStream Functions //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(iTJSTextReadStream *, TVPCreateTextStreamForRead, (const ttstr &name, const ttstr &modestr)); TJS_EXP_FUNC_DEF(iTJSTextWriteStream *, TVPCreateTextStreamForWrite, (const ttstr &name, const ttstr &modestr)); TJS_EXP_FUNC_DEF(void, TVPSetDefaultReadEncoding, (const ttstr& encoding)); TJS_EXP_FUNC_DEF(const tjs_char*, TVPGetDefaultReadEncoding, ()); bool TVPStringDecode(const void *p, int len, ttstr& result, ttstr encoding = "utf8"); bool TVPStringEncode(const ttstr &s, std::string &result, ttstr encoding = "utf8"); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/UserEvent.h ================================================ #ifndef __USER_EVENT_H__ #define __USER_EVENT_H__ #ifndef WM_APP #define WM_APP 0x10000 #endif #define TVP_EV_TIMER_THREAD (WM_APP + 1) #define TVP_EV_WAVE_SND_BUF_THREAD (TVP_EV_TIMER_THREAD + 1) #define TVP_EV_VSYNC_TIMING_THREAD (TVP_EV_WAVE_SND_BUF_THREAD + 1) #define TVP_EV_CONTINUE_LIMIT_THREAD (TVP_EV_VSYNC_TIMING_THREAD + 1) #define TVP_EV_DELIVER_EVENTS_DUMMY (TVP_EV_CONTINUE_LIMIT_THREAD + 1) #define TVP_EV_KEEP_ALIVE (TVP_EV_DELIVER_EVENTS_DUMMY + 1) #define TVP_EV_IMAGE_LOAD_THREAD (TVP_EV_KEEP_ALIVE + 1) #define TVP_EV_WINDOW_RELEASE (TVP_EV_IMAGE_LOAD_THREAD + 1) #endif // __USER_EVENT_H__ ================================================ FILE: src/core/base/UtilStreams.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Stream related utilities / utility streams //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include "UtilStreams.h" #include "MsgIntf.h" #include "DebugIntf.h" #include "EventIntf.h" #include "StorageIntf.h" #include #include #include #include "Platform.h" #include #include //--------------------------------------------------------------------------- // tTVPLocalTempStorageHolder //--------------------------------------------------------------------------- #define TVP_LOCAL_TEMP_COPY_BLOCK_SIZE 65536*2 tTVPLocalTempStorageHolder::tTVPLocalTempStorageHolder(const ttstr & name) { // name must be normalized !!! FileMustBeDeleted = false; FolderMustBeDeleted = false; LocalName = TVPGetLocallyAccessibleName(name); if(LocalName.IsEmpty()) { // file must be copied to local filesystem // note that the basename is much more important than the directory // which the file is to be in, so we create a temporary folder and // store the file in it. LocalFolder = TVPGetTemporaryName(); LocalName = LocalFolder + TJS_W("/") + TVPExtractStorageName(name); TVPCreateFolders(LocalFolder); // create temporary folder FolderMustBeDeleted = true; FileMustBeDeleted = true; try { // copy to local file tTVPStreamHolder src(name); tTVPStreamHolder dest(LocalName, TJS_BS_WRITE|TJS_BS_DELETE_ON_CLOSE); tjs_uint8 * buffer = new tjs_uint8[TVP_LOCAL_TEMP_COPY_BLOCK_SIZE]; try { tjs_uint read; while(true) { read = src->Read(buffer, TVP_LOCAL_TEMP_COPY_BLOCK_SIZE); if(read == 0) break; dest->WriteBuffer(buffer, read); } } catch(...) { delete [] buffer; throw; } delete [] buffer; } catch(...) { if(FileMustBeDeleted) TVPRemoveFile(LocalName); if(FolderMustBeDeleted) TVPRemoveFolder(LocalFolder); throw; } } } //--------------------------------------------------------------------------- tTVPLocalTempStorageHolder::~tTVPLocalTempStorageHolder() { if(FileMustBeDeleted) TVPRemoveFile(LocalName); if(FolderMustBeDeleted) TVPRemoveFolder(LocalFolder); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPMemoryStream //--------------------------------------------------------------------------- tTVPMemoryStream::tTVPMemoryStream() { Init(); } //--------------------------------------------------------------------------- tTVPMemoryStream::tTVPMemoryStream(const void * block, tjs_uint size) { Init(); Block = (void*)block; if(!Block) { Block = Alloc(size); if(!Block) TVPThrowExceptionMessage(TVPInsufficientMemory); } else { Reference = true; // memory block was given } Size = size; AllocSize = size; CurrentPos = 0; } //--------------------------------------------------------------------------- tTVPMemoryStream::~tTVPMemoryStream() { if(Block && !Reference) Free(Block); } //--------------------------------------------------------------------------- tjs_uint64 TJS_INTF_METHOD tTVPMemoryStream::Seek(tjs_int64 offset, tjs_int whence) { tjs_int64 newpos; switch(whence) { case TJS_BS_SEEK_SET: if(offset >= 0) { if(offset <= Size) CurrentPos = static_cast(offset); } return CurrentPos; case TJS_BS_SEEK_CUR: if((newpos = offset + (tjs_int64)CurrentPos) >= 0) { tjs_uint np = (tjs_uint)newpos; if(np <= Size) CurrentPos = np; } return CurrentPos; case TJS_BS_SEEK_END: if((newpos = offset + (tjs_int64)Size) >= 0) { tjs_uint np = (tjs_uint)newpos; if(np <= Size) CurrentPos = np; } return CurrentPos; } return CurrentPos; } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPMemoryStream::Read(void *buffer, tjs_uint read_size) { if(CurrentPos + read_size >= Size) { read_size = Size - CurrentPos; } memcpy(buffer, (tjs_uint8*)Block + CurrentPos, read_size); CurrentPos += read_size; return read_size; } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPMemoryStream::Write(const void *buffer, tjs_uint write_size) { // writing may increase the internal buffer size. if(Reference) TVPThrowExceptionMessage(TVPWriteError); tjs_uint newpos = CurrentPos + write_size; if(newpos >= AllocSize) { // exceeds AllocSize tjs_uint onesize; if(AllocSize < 64*1024) onesize = 4*1024; else if(AllocSize < 512*1024) onesize = 16*1024; else if(AllocSize < 4096*1024) onesize = 256*1024; else onesize = 2024*1024; AllocSize += onesize; if(CurrentPos + write_size >= AllocSize) // still insufficient ? { AllocSize = CurrentPos + write_size; } Block = Realloc(Block, AllocSize); if(AllocSize && !Block) TVPThrowExceptionMessage(TVPInsufficientMemory); // this exception cannot be repaird; a fatal error. } memcpy((tjs_uint8*)Block + CurrentPos, buffer, write_size); CurrentPos = newpos; if(CurrentPos > Size) Size = CurrentPos; return write_size; } //--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPMemoryStream::SetEndOfStorage() { if(Reference) TVPThrowExceptionMessage(TVPWriteError); Size = CurrentPos; AllocSize = Size; Block = Realloc(Block, Size); if(Size && !Block) TVPThrowExceptionMessage(TVPInsufficientMemory); } //--------------------------------------------------------------------------- void tTVPMemoryStream::Clear(void) { if(Block && !Reference) Free(Block); Init(); } //--------------------------------------------------------------------------- void tTVPMemoryStream::SetSize(tjs_uint size) { if(Reference) TVPThrowExceptionMessage(TVPWriteError); if(Size > size) { // decrease Size = size; AllocSize = size; Block = Realloc(Block, size); if(CurrentPos > Size) CurrentPos = Size; if(size && !Block) TVPThrowExceptionMessage(TVPInsufficientMemory); } else { // increase AllocSize = size; Size = size; Block = Realloc(Block, size); if(size && !Block) TVPThrowExceptionMessage(TVPInsufficientMemory); } } //--------------------------------------------------------------------------- void tTVPMemoryStream::Init() { Block = NULL; Reference = false; Size = 0; AllocSize = 0; CurrentPos = 0; } //--------------------------------------------------------------------------- void * tTVPMemoryStream::Alloc(size_t size) { return TJS_malloc(size); } //--------------------------------------------------------------------------- void * tTVPMemoryStream::Realloc(void *orgblock, size_t size) { return TJS_realloc(orgblock, size); } //--------------------------------------------------------------------------- void tTVPMemoryStream::Free(void *block) { TJS_free(block); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPPartialStream //--------------------------------------------------------------------------- tTVPPartialStream::tTVPPartialStream(tTJSBinaryStream *stream, tjs_uint64 start, tjs_uint64 size) { // the stream given as a argument here will be owned by this instance, // and freed at the destruction. Stream = stream; Start = start; Size = size; CurrentPos = 0; try { Stream->SetPosition(Start); } catch(...) { delete Stream; Stream = NULL; throw; } } //--------------------------------------------------------------------------- tTVPPartialStream::~tTVPPartialStream() { if(Stream) delete Stream; } //--------------------------------------------------------------------------- tjs_uint64 TJS_INTF_METHOD tTVPPartialStream::Seek(tjs_int64 offset, tjs_int whence) { tjs_int64 newpos; switch(whence) { case TJS_BS_SEEK_SET: newpos = offset; if(offset >= 0 && offset <= static_cast(Size) ) { newpos += Start; CurrentPos = Stream->Seek(newpos, TJS_BS_SEEK_SET) - Start; } return CurrentPos; case TJS_BS_SEEK_CUR: newpos = offset + CurrentPos; if(offset >= 0 && offset <= static_cast(Size) ) { newpos += Start; CurrentPos = Stream->Seek(newpos, TJS_BS_SEEK_SET) - Start; } return CurrentPos; case TJS_BS_SEEK_END: newpos = offset + Size; if(offset >= 0 && offset <= static_cast(Size) ) { newpos += Start; CurrentPos = Stream->Seek(newpos, TJS_BS_SEEK_SET) - Start; } return CurrentPos; } return CurrentPos; } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPPartialStream::Read(void *buffer, tjs_uint read_size) { if(CurrentPos + read_size >= Size) { read_size = static_cast(Size - CurrentPos); } tjs_uint read = Stream->Read(buffer, read_size); CurrentPos += read; return read; } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPPartialStream::Write(const void *buffer, tjs_uint write_size) { return 0; } //--------------------------------------------------------------------------- tjs_uint64 TJS_INTF_METHOD tTVPPartialStream::GetSize() { return Size; } //--------------------------------------------------------------------------- extern "C" { #include "libarchive/archive.h" #include "libarchive/archive_entry.h" } #if 0 class LibArchive_Archive : public tTVPArchive { struct archive *_arc; tTJSBinaryStream *_stream; static const int BUFFER_SIZE = 16 * 1024; tjs_uint8 *_buffer = new tjs_uint8[BUFFER_SIZE]; std::vector > _filelist; void Clear() { if (_arc) { archive_read_free(_arc); _arc = nullptr; } for (std::pair &it : _filelist) { archive_entry_free(it.second); } _filelist.clear(); } public: LibArchive_Archive(const ttstr & name, tTJSBinaryStream *st) : tTVPArchive(name), _stream(st) { _arc = archive_read_new(); } ~LibArchive_Archive() { Clear(); if (_stream) delete _stream; if (_buffer) delete[] _buffer; } virtual tjs_uint GetCount() { return _filelist.size(); } virtual ttstr GetName(tjs_uint idx) { return _filelist[idx].first; } virtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx) { struct archive_entry * entry = _filelist[idx].second; tjs_uint64 fileSize = archive_entry_size(entry); if (fileSize <= 0) return new tTVPMemoryStream(); return nullptr; } bool Open(bool normalizeFileName) { archive_read_support_filter_all(_arc); archive_read_support_format_all(_arc); archive_read_set_seek_callback(_arc, seek_callback); archive_read_open2(_arc, this, nullptr, read_callback, nullptr, nullptr); struct archive_entry *entry = archive_entry_new2(_arc); while (archive_read_next_header2(_arc, entry) == ARCHIVE_OK) { ttstr filename(archive_entry_pathname_utf8(entry)); if (normalizeFileName) NormalizeInArchiveStorageName(filename); _filelist.emplace_back(filename, entry); entry = archive_entry_new2(_arc); } archive_entry_free(entry); if (normalizeFileName) { std::sort(_filelist.begin(), _filelist.end(), [](const std::pair& a, const std::pair& b) { return a.first < b.first; }); } } void Detach() { Clear(); _stream = nullptr; } static la_ssize_t read_callback(struct archive *, void *_client_data, const void **_buffer) { LibArchive_Archive *_this = (LibArchive_Archive *)_client_data; *_buffer = _this->_buffer; return _this->_stream->Read(_this->_buffer, BUFFER_SIZE); } static la_int64_t seek_callback(struct archive *, void *_client_data, la_int64_t offset, int whence) { LibArchive_Archive *_this = (LibArchive_Archive *)_client_data; return _this->_stream->Seek(offset, whence); } static la_int64_t skip_callback(struct archive *, void *_client_data, la_int64_t request) { LibArchive_Archive *_this = (LibArchive_Archive *)_client_data; return _this->_stream->Seek(request, TJS_BS_SEEK_CUR); } }; tTVPArchive *TVPOpenLibArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) { LibArchive_Archive *arc = new LibArchive_Archive(name, st); if (arc->Open(normalizeFileName)) { return arc; } arc->Detach(); delete arc; return nullptr; } #endif static FILE *_fileopen(const std::string &strpath) { FILE *fp = fopen(strpath.c_str(), "wb"); if (!fp) { // make dirs ttstr path = TVPExtractStoragePath(strpath); TVPCreateFolders(path); fp = fopen(strpath.c_str(), "wb"); } return fp; } class tTVPUnpackArchiveThread { std::thread *ThreadObj; std::mutex Mutex; std::condition_variable Cond; tTVPUnpackArchive *Owner; void Entry() { { std::unique_lock lk(Mutex); Cond.wait(lk); } Owner->Process(); } public: tTVPUnpackArchiveThread(tTVPUnpackArchive *owner) : Owner(owner) { ThreadObj = new std::thread(&tTVPUnpackArchiveThread::Entry, this); } ~tTVPUnpackArchiveThread() { if (ThreadObj->joinable()) { ThreadObj->join(); } delete ThreadObj; } void Start() { Cond.notify_all(); } }; class tTVPUnpackArchiveImplWrap : public iTVPUnpackArchiveImpl { tTVPArchive *pTVPArc = nullptr; tjs_int64 _totalSize = 0; int _totalFileCount = 0; public: virtual ~tTVPUnpackArchiveImplWrap() { if (pTVPArc) pTVPArc->Release(); } virtual bool Open(const std::string &path) override { pTVPArc = TVPOpenArchive(path, false); int file_count = 0; if (pTVPArc) { file_count = pTVPArc->GetCount(); _totalSize = 0; for (int i = 0; i < file_count; ++i) { tTJSBinaryStream *str = pTVPArc->CreateStreamByIndex(i); if (str) { _totalSize += str->GetSize(); delete str; } } _totalFileCount = file_count; return true; } return false; } virtual int GetFileCount() override { return _totalFileCount; } virtual tjs_int64 GetTotalSize() override { return _totalSize; } virtual void ExtractTo(const std::string &OutPath) { tjs_uint64 total_size = 0; int file_count = pTVPArc->GetCount(); std::vector buffer; buffer.resize(4 * 1024 * 1024); for (int index = 0; index < file_count && !StopRequired; ++index) { tjs_uint64 file_size = 0; std::string filename = pTVPArc->GetName(index).AsStdString(); if (filename.size() > 600) continue; std::string fullpath = OutPath + filename; FILE *fp = _fileopen(fullpath); if (!fp) { _callbacks->FuncOnError(ARCHIVE_FAILED, "Cannot open output file"); break; } tTJSBinaryStream *str = pTVPArc->CreateStreamByIndex(index); if (!str) { _callbacks->FuncOnError(ARCHIVE_FAILED, "Cannot open archive stream"); fclose(fp); break; } _callbacks->FuncOnNewFile(index, filename.c_str(), str->GetSize()); while (!StopRequired) { tjs_uint readed = str->Read(&buffer.front(), buffer.size()); if (readed == 0) break; if (readed != fwrite(&buffer.front(), 1, readed, fp)) { _callbacks->FuncOnError(ARCHIVE_FAILED, "Fail to write file.\nPlease check the disk space."); break; } file_size += readed; total_size += readed; _callbacks->FuncOnProgress(total_size, file_size); if (readed < buffer.size()) break; } delete str; fclose(fp); } pTVPArc->Release(); pTVPArc = nullptr; _callbacks->FuncOnEnded(); } }; class tTVPUnpackArchiveImplLibArchive : public iTVPUnpackArchiveImpl { protected: struct archive* ArcObj = nullptr; tjs_int64 _totalSize = 0; int _totalFileCount = 0; //FILE *FpIn = nullptr; std::string _filepath; static const char * _onPassphraseCallback(struct archive *, void *clientdata); std::string onPassphraseCallback(); public: virtual ~tTVPUnpackArchiveImplLibArchive() { // if (FpIn) { // fclose(FpIn); // FpIn = nullptr; // } if (ArcObj) { archive_read_free(ArcObj); ArcObj = nullptr; } } virtual bool Open(const std::string &path) override { //FpIn = fopen(path.c_str(), "rb"); _filepath = path; int file_count = 0; tjs_uint64 size_count = 0; ArcObj = archive_read_new(); archive_read_support_filter_all(ArcObj); archive_read_support_format_all(ArcObj); archive_read_set_passphrase_callback(ArcObj, this, _onPassphraseCallback); #ifdef _MSC_VER int r = archive_read_open_filename_w(ArcObj, ttstr(path).c_str(), 32768); #else int r = archive_read_open_filename(ArcObj, path.c_str(), 32768); #endif if (r < ARCHIVE_OK) { // fclose(FpIn); // FpIn = nullptr; archive_read_free(ArcObj); ArcObj = nullptr; return false; } if (archive_read_has_encrypted_entries(ArcObj) > 0) { std::string psw = onPassphraseCallback(); if (psw.empty()) { return false; } archive_read_add_passphrase(ArcObj, psw.c_str()); } r = 0; while (true) { struct archive_entry *entry; int r = archive_read_next_header(ArcObj, &entry); if (r == ARCHIVE_EOF) { r = ARCHIVE_OK; break; } if (r < ARCHIVE_OK) _callbacks->FuncOnError(r, archive_error_string(ArcObj)); if (r < ARCHIVE_WARN) break; ++file_count; size_count += archive_entry_size(entry); } _totalSize = size_count; _totalFileCount = file_count; archive_read_close(ArcObj); archive_read_free(ArcObj); ArcObj = nullptr; return true; } virtual int GetFileCount() override { return _totalFileCount; } virtual tjs_int64 GetTotalSize() override { return _totalSize; } virtual void ExtractTo(const std::string &OutPath) { tjs_uint64 total_size = 0; // fseek(FpIn, 0, SEEK_SET); ArcObj = archive_read_new(); archive_read_support_filter_all(ArcObj); archive_read_support_format_all(ArcObj); #ifdef _MSC_VER int r = archive_read_open_filename_w(ArcObj, ttstr(_filepath).c_str(), 32768); #else int r = archive_read_open_filename(ArcObj, _filepath.c_str(), 32768); #endif if (r < ARCHIVE_OK) { _callbacks->FuncOnError(r, archive_error_string(ArcObj)); _callbacks->FuncOnEnded(); return; } for (int index = 0; !StopRequired; ++index) { struct archive_entry *entry; int r = archive_read_next_header(ArcObj, &entry); if (r == ARCHIVE_EOF) { r = ARCHIVE_OK; break; } if (r < ARCHIVE_OK) _callbacks->FuncOnError(r, archive_error_string(ArcObj)); if (r < ARCHIVE_WARN) break; const char *sfilename = archive_entry_pathname_utf8(entry); std::string filename; if (sfilename) { filename = sfilename; } else { const wchar_t* wfilename = archive_entry_pathname_w(entry); std::wstring_convert > cvt; filename = cvt.to_bytes(wfilename); } if (filename.back() == '/' || filename.back() == '\\') { // skip folder continue; } std::string fullpath = OutPath + filename; FILE *fp = _fileopen(fullpath); if (!fp) { _callbacks->FuncOnError(ARCHIVE_FAILED, "Cannot open output file"); break; } _callbacks->FuncOnNewFile(index, filename, archive_entry_size(entry)); const void *buff; size_t size; la_int64_t offset; tjs_uint64 file_size = 0; const char *errmsg; while (!StopRequired) { r = archive_read_data_block(ArcObj, &buff, &size, &offset); if (r == ARCHIVE_EOF) { r = ARCHIVE_OK; break; } if (r < ARCHIVE_OK) { errmsg = archive_error_string(ArcObj); break; } if (size != fwrite(buff, 1, size, fp)) { r = ARCHIVE_FAILED; errmsg = "Fail to write file.\nPlease check the disk space."; break; } file_size += size; total_size += size; _callbacks->FuncOnProgress(total_size, file_size); } fclose(fp); if (r < ARCHIVE_OK) _callbacks->FuncOnError(r, errmsg); if (r < ARCHIVE_WARN) break; if (archive_entry_mtime_is_set(entry)) { TVP_utime(fullpath.c_str(), archive_entry_mtime(entry)); } } archive_read_close(ArcObj); _callbacks->FuncOnEnded(); } }; std::string tTVPUnpackArchiveImplLibArchive::onPassphraseCallback() { return _callbacks->FuncPassword(); } const char * tTVPUnpackArchiveImplLibArchive::_onPassphraseCallback(struct archive *, void *clientdata) { static std::string psw = ((tTVPUnpackArchiveImplLibArchive*)clientdata)->onPassphraseCallback(); return psw.c_str(); } extern "C" { #include "p7zip/C/7z.h" #include "p7zip/C/7zFile.h" #include "p7zip/C/7zCrc.h" } #include #include #include "win32io.h" static ISzAlloc allocImp = { [](void *p, size_t size) -> void * { return malloc(size); }, [](void *p, void *addr) { free(addr); } }; class tTVPUnpackArchiveImpl7Zip : public tTVPUnpackArchiveImplLibArchive { int _stream; CLookToRead lookStream; struct CSeekInStream : public ISeekInStream { tTVPUnpackArchiveImpl7Zip *Host; } archiveStream; SRes StreamRead(void *buf, size_t *size) { *size = read(_stream, buf, *size); return SZ_OK; } SRes StreamSeek(Int64 *pos, ESzSeek origin) { int whence = SEEK_SET; switch (origin) { case SZ_SEEK_CUR: whence = SEEK_CUR; break; case SZ_SEEK_END: whence = SEEK_END; break; case SZ_SEEK_SET: whence = SEEK_SET; break; default: break; } *pos = lseek64(_stream, *pos, whence); return SZ_OK; } public: tTVPUnpackArchiveImpl7Zip() { archiveStream.Host = this; archiveStream.Read = [](void *p, void *buf, size_t *size)->SRes {return ((CSeekInStream*)p)->Host->StreamRead(buf, size); }; archiveStream.Seek = [](void *p, Int64 *pos, ESzSeek origin)->SRes {return ((CSeekInStream*)p)->Host->StreamSeek(pos, origin); }; LookToRead_CreateVTable(&lookStream, false); lookStream.realStream = &archiveStream; if (!g_CrcTable[1]) CrcGenerateTable(); } virtual bool Open(const std::string &path) override { // FpIn = fopen(path.c_str(), "rb"); _filepath = path; CSzArEx db; SzArEx_Init(&db); _stream = open(path.c_str(), O_RDONLY, 0666); if (!_stream) return false; SRes res = SzArEx_Open(&db, &lookStream.s, &allocImp, &allocImp); if (res != SZ_OK) return false; _totalFileCount = 0; _totalSize = 0; for (int i = 0; i < db.NumFiles; i++) { size_t offset = 0; size_t outSizeProcessed = 0; bool isDir = SzArEx_IsDir(&db, i); if (isDir) continue; ++_totalFileCount; _totalSize += SzArEx_GetFileSize(&db, i); } SzArEx_Free(&db, &allocImp); close(_stream); return true; } }; #include "unrar/raros.hpp" #include "unrar/dll.hpp" class tTVPUnpackArchiveImplUnRAR : public iTVPUnpackArchiveImpl { std::string _archivePath; tjs_int _filecount; tjs_int64 _totalSize, _totalProcessedBytes, _curProcessedBytes; std::string _lastUsedPassword; std::mutex _mutex; std::condition_variable _cond; bool _reqBreak = false; struct RARArc { RAROpenArchiveDataEx _archiveData; void *_handle = nullptr; RARArc() {} ~RARArc() { Close(); } bool Open(const std::string &path, int mode) { memset(&_archiveData, 0, sizeof(_archiveData)); #ifdef _MSC_VER ttstr _path(path); _archiveData.ArcNameW = (wchar_t*)_path.c_str(); #else _archiveData.ArcName = (char *)path.c_str(); #endif _archiveData.OpenMode = mode; _handle = RAROpenArchiveEx(&_archiveData); return !!_handle; } void Close() { if (_handle) RARCloseArchive(_handle); _handle = nullptr; } }; int OnCallback(UINT msg, LPARAM P1, LPARAM P2) { switch (msg) { case UCM_CHANGEVOLUME: case UCM_CHANGEVOLUMEW: return -1; // manual change multi-volume file name is not supported yet case UCM_NEEDPASSWORD: { bool hasPsw = !_lastUsedPassword.empty(); if (!hasPsw) { _lastUsedPassword = _callbacks->FuncPassword(); } if (_lastUsedPassword.empty()) { return -1; } int len = _lastUsedPassword.size(); if (len > P2) len = P2; strncpy((char*)P1, _lastUsedPassword.c_str(), len); if (hasPsw) _lastUsedPassword.clear(); return 0; } case UCM_PROCESSDATA: _totalProcessedBytes += P2; _curProcessedBytes += P2; _callbacks->FuncOnProgress(_totalProcessedBytes, _curProcessedBytes); return _reqBreak ? -1 : 0; } return -1; } public: virtual ~tTVPUnpackArchiveImplUnRAR() { } virtual bool Open(const std::string &path) override { _archivePath = path; RARArc arc; if (!arc.Open(_archivePath, RAR_OM_LIST)) { return false; } RARSetCallback(arc._handle, [](UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2)->int { return ((tTVPUnpackArchiveImplUnRAR*)UserData)->OnCallback(msg, P1, P2); }, (LPARAM)this); arc._handle; RARHeaderData headerData; _totalSize = 0; _filecount = 0; while (1) { RARHeaderDataEx headerData; memset(&headerData, 0, sizeof(headerData)); int result = RARReadHeaderEx(arc._handle, &headerData); if (result != 0) { if (result != ERAR_END_ARCHIVE) { return false; } break; } _totalSize += ((tjs_int64)headerData.UnpSizeHigh << 32) | headerData.UnpSize; ++_filecount; // Find next file result = RARProcessFile(arc._handle, RAR_SKIP, NULL, NULL); if (result != 0) { return false; } } return true; } virtual int GetFileCount() override { return _filecount; } virtual tjs_int64 GetTotalSize() override { return _totalSize; } virtual void ExtractTo(const std::string &path) override { RARArc arc; if (!arc.Open(_archivePath, RAR_OM_EXTRACT)) { _callbacks->FuncOnError(1001, "Cannot open file"); return; } RARSetCallback(arc._handle, [](UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2)->int { return ((tTVPUnpackArchiveImplUnRAR*)UserData)->OnCallback(msg, P1, P2); }, (LPARAM)this); RARHeaderData headerData; for (int counter = 0; ;++counter) { RARHeaderDataEx headerData; memset(&headerData, 0, sizeof(headerData)); int result = RARReadHeaderEx(arc._handle, &headerData); if (result != 0) { if (result != ERAR_END_ARCHIVE) { _callbacks->FuncOnError(result, "Extraction Fail"); return; } break; } // _filelist.emplace_back(headerData.FileName); _callbacks->FuncOnNewFile(counter, headerData.FileName, ((tjs_int64)headerData.UnpSizeHigh << 32) | headerData.UnpSize); _curProcessedBytes = 0; // Find next file #ifdef _MSC_VER ttstr _path(path); result = RARProcessFileW(arc._handle, RAR_EXTRACT, (wchar_t*)_path.c_str(), NULL); #else result = RARProcessFile(arc._handle, RAR_EXTRACT, (char*)path.c_str(), NULL); #endif if (result != 0) { _callbacks->FuncOnError(result, "Extraction Fail"); return; } } _callbacks->FuncOnEnded(); } }; int tTVPUnpackArchive::Prepare(const std::string &path, const std::string &_outpath, tjs_uint64 *totalSize) { FILE *FpIn = fopen(path.c_str(), "rb"); if (!FpIn) return -1; char signature[4]; if (fread(signature, 1, 4, FpIn) != 4) { fclose(FpIn); return -2; } OutPath = _outpath + "/"; fclose(FpIn); if (!memcmp(signature, "Rar!", 4)) { _impl = new tTVPUnpackArchiveImplUnRAR(); } else if (!memcmp(signature, "PK", 2)) { _impl = new tTVPUnpackArchiveImplLibArchive(); } else if (!memcmp(signature, "7z", 2)) { // _impl = new tTVPUnpackArchiveImpl7Zip(); _impl = new tTVPUnpackArchiveImplLibArchive(); } else { _impl = new tTVPUnpackArchiveImplWrap(); // xp3, etc _impl->SetCallback(this); if (!_impl->Open(path)) { Close(); _impl = new tTVPUnpackArchiveImplLibArchive(); } } _impl->SetCallback(this); if (!_impl->Open(path)) { Close(); return -2; } if (totalSize) *totalSize = _impl->GetTotalSize(); int file_count = _impl->GetFileCount(); if (file_count) { ArcThread = new tTVPUnpackArchiveThread(this); } return file_count; } void tTVPUnpackArchive::Start() { _impl->StopRequired = false; ArcThread->Start(); } void tTVPUnpackArchive::Stop() { _impl->StopRequired = true; ArcThread->Start(); } void tTVPUnpackArchive::Close() { if (_impl) delete _impl; _impl = nullptr; } void tTVPUnpackArchive::Process() { if (_impl->StopRequired) return; _impl->ExtractTo(OutPath); } tTVPUnpackArchive::tTVPUnpackArchive() { } tTVPUnpackArchive::~tTVPUnpackArchive() { if (ArcThread) delete ArcThread; } ================================================ FILE: src/core/base/UtilStreams.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Stream related utilities / utility streams //--------------------------------------------------------------------------- #ifndef UtilStreamsH #define UtilStreamsH #include "StorageIntf.h" #include //--------------------------------------------------------------------------- // tTVPStreamHolder //--------------------------------------------------------------------------- class tTVPStreamHolder { tTJSBinaryStream *Stream; public: tTVPStreamHolder() { Stream = NULL; } tTVPStreamHolder(const ttstr& name, tjs_uint32 mode = 0) { Stream = TVPCreateStream(name, mode); } ~tTVPStreamHolder() { if(Stream) delete Stream; } tTJSBinaryStream * operator ->() const { return Stream; } tTJSBinaryStream * Get() const { return Stream; } void Close() { if(Stream) { delete Stream; Stream = NULL; } } void Disown() { Stream = NULL; } void Open(const ttstr & name, tjs_uint32 flag = 0) { if(Stream) delete Stream, Stream = NULL; Stream = TVPCreateStream(name, flag); } }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPLocalTempStorageHolder //--------------------------------------------------------------------------- // this class holds storage as local filesystem file ( does not open it ). // storage is copied to local fliesystem if needed. class tTVPLocalTempStorageHolder { bool FileMustBeDeleted; bool FolderMustBeDeleted; ttstr LocalName; ttstr LocalFolder; public: tTVPLocalTempStorageHolder(const ttstr & name); ~tTVPLocalTempStorageHolder(); bool IsTemporaryFile() const { return FileMustBeDeleted; } const ttstr & GetLocalName() const { return LocalName; } }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPMemoryStream //--------------------------------------------------------------------------- /* this class provides a tTJSBinaryStream based access method for a memory block. */ class tTVPMemoryStream : public tTJSBinaryStream { protected: void * Block; bool Reference; tjs_uint Size; tjs_uint AllocSize; tjs_uint CurrentPos; public: tTVPMemoryStream(); tTVPMemoryStream(const void * block, tjs_uint size); ~tTVPMemoryStream(); tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence); tjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size); tjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size); void TJS_INTF_METHOD SetEndOfStorage(); tjs_uint64 TJS_INTF_METHOD GetSize() { return Size; } // non-tTJSBinaryStream based methods void * GetInternalBuffer() const { return Block; } void Clear(void); void SetSize(tjs_uint size); protected: void Init(); protected: virtual void * Alloc(size_t size); virtual void * Realloc(void *orgblock, size_t size); virtual void Free(void *block); }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPPartialStream //--------------------------------------------------------------------------- /* this class offers read-only accesses for a partial of the other stream, limited by given start position for original stream and given limited size. */ //--------------------------------------------------------------------------- class tTVPPartialStream : public tTJSBinaryStream { private: tTJSBinaryStream *Stream; tjs_uint64 Start; tjs_uint64 Size; tjs_uint64 CurrentPos; public: tTVPPartialStream(tTJSBinaryStream *stream, tjs_uint64 start, tjs_uint64 size); ~tTVPPartialStream(); tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence); tjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size); tjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size); // void SetEndOfStorage(); // use default behavior tjs_uint64 TJS_INTF_METHOD GetSize(); }; //--------------------------------------------------------------------------- struct tTVPUnpackArchiveCallbacks { std::function FuncOnEnded; std::function FuncOnError; std::function FuncOnProgress; std::function FuncOnNewFile; std::function FuncPassword; }; class tTVPUnpackArchiveThread; class iTVPUnpackArchiveImpl { protected: const tTVPUnpackArchiveCallbacks *_callbacks = nullptr; public: bool StopRequired = false; virtual ~iTVPUnpackArchiveImpl() {} void SetCallback(const tTVPUnpackArchiveCallbacks* cb) { _callbacks = cb; } virtual bool Open(const std::string &path) = 0; virtual int GetFileCount() = 0; // -1 for unknown file count virtual tjs_int64 GetTotalSize() = 0; // -1 for unknown size virtual void ExtractTo(const std::string &path) = 0; }; class tTVPUnpackArchive : public tTVPUnpackArchiveCallbacks { public: tTVPUnpackArchive(); virtual ~tTVPUnpackArchive(); // must ve deconstructed from main thread int Prepare(const std::string &path, const std::string &_outpath, tjs_uint64 *totalSize); void Start(); void Stop(); void Close(); void SetCallback( const std::function &funcOnEnded, const std::function &funcOnError, const std::function &funcOnProgress, const std::function &funcOnNewFile, const std::function& funcPassword) { FuncOnEnded = funcOnEnded; FuncOnError = funcOnError; FuncOnProgress = funcOnProgress; FuncOnNewFile = funcOnNewFile; FuncPassword = funcPassword; } protected: // these callbacks are not in main thread ! virtual void OnEnded() { if (FuncOnEnded) FuncOnEnded(); } virtual void OnProgress(tjs_uint64 total_size, tjs_uint64 file_size) { if (FuncOnProgress) FuncOnProgress(total_size, file_size); } virtual void OnNewFile(int idx, const char * utf8name, tjs_uint64 file_size) { if (FuncOnNewFile) FuncOnNewFile(idx, utf8name, file_size); } private: void Process(); iTVPUnpackArchiveImpl *_impl = nullptr; std::string OutPath; friend class tTVPUnpackArchiveThread; tTVPUnpackArchiveThread *ArcThread = nullptr; }; #endif ================================================ FILE: src/core/base/XP3Archive.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // XP3 virtual file system support //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include "XP3Archive.h" #include "MsgIntf.h" #include "DebugIntf.h" #include "EventIntf.h" #include "UtilStreams.h" #include "SysInitIntf.h" #include #include bool TVPAllowExtractProtectedStorage = true; //--------------------------------------------------------------------------- // archive filter related //--------------------------------------------------------------------------- tTVPXP3ArchiveExtractionFilter TVPXP3ArchiveExtractionFilter = NULL; void TVPSetXP3ArchiveExtractionFilter(tTVPXP3ArchiveExtractionFilter filter) { TVPXP3ArchiveExtractionFilter = filter; } //--------------------------------------------------------------------------- static tTVPXP3ArchiveContentFilter TVPXP3ArchiveContentFilter = nullptr; void TVPSetXP3ArchiveContentFilter(tTVPXP3ArchiveContentFilter filter) { TVPXP3ArchiveContentFilter = filter; } //--------------------------------------------------------------------------- // tTVPXP3ArchiveHandleCache //--------------------------------------------------------------------------- #define TVP_MAX_ARCHIVE_HANDLE_CACHE 8 static tjs_uint TVPArchiveHandleCacheAge = 0; struct tTVPArchiveHandleCacheItem { void * Pointer; tTJSBinaryStream * Stream; tjs_uint Age; }; //--------------------------------------------------------------------------- static tTVPArchiveHandleCacheItem * TVPArchiveHandleCachePool = NULL; static bool TVPArchiveHandleCacheInit = false; static bool TVPArchiveHandleCacheShutdown = false; static tTJSCriticalSection TVPArchiveHandleCacheCS; //--------------------------------------------------------------------------- tTJSBinaryStream * TVPGetCachedArchiveHandle(void * pointer, const ttstr & name) { // get cached archive file handle from the pool if(TVPArchiveHandleCacheShutdown) { // the pool has shutdown return TVPCreateStream(name); } tTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS); if(!TVPArchiveHandleCacheInit) { // initialize the pool TVPArchiveHandleCachePool = new tTVPArchiveHandleCacheItem[TVP_MAX_ARCHIVE_HANDLE_CACHE]; for(tjs_int i =0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++) { TVPArchiveHandleCachePool[i].Pointer = NULL; TVPArchiveHandleCachePool[i].Stream = NULL; TVPArchiveHandleCachePool[i].Age = 0; } TVPArchiveHandleCacheInit = true; } // linear search wiil be enough here because the // TVP_MAX_ARCHIVE_HANDLE_CACHE is relatively small for(tjs_int i =0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++) { tTVPArchiveHandleCacheItem *item = TVPArchiveHandleCachePool + i; if(item->Stream && item->Pointer == pointer) { // found in the pool tTJSBinaryStream * stream = item->Stream; item->Stream = NULL; return stream; } } // not found in the pool // simply create a stream and return it return TVPCreateStream(name); } //--------------------------------------------------------------------------- /*static*/ void TVPReleaseCachedArchiveHandle(void * pointer, tTJSBinaryStream * stream) { // release archive file handle if(TVPArchiveHandleCacheShutdown) return; if(!TVPArchiveHandleCacheInit) return; tTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS); // search empty cell in the pool tjs_uint oldest_age = 0; tjs_int oldest = 0; for(tjs_int i = 0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++) { tTVPArchiveHandleCacheItem *item = TVPArchiveHandleCachePool + i; if(item->Stream == NULL) { // found the empty cell; fill it item->Pointer = pointer; item->Stream = stream; item->Age = ++TVPArchiveHandleCacheAge; // counter overflow in TVPArchiveHandleCacheAge // is not so a big problem. // counter overflow can worsen the cache performance, // but it occurs only when the counter is overflowed // (it's too far less than usual) return; } if(i == 0 || oldest_age > item->Age) { oldest_age = item->Age; oldest = i; } } // empty cell not found // free oldest cell and fill it tTVPArchiveHandleCacheItem *oldest_item = TVPArchiveHandleCachePool + oldest; delete oldest_item->Stream, oldest_item->Stream = NULL; oldest_item->Pointer = pointer; oldest_item->Stream = stream; oldest_item->Age = ++TVPArchiveHandleCacheAge; } //--------------------------------------------------------------------------- /*static*/ void TVPFreeArchiveHandlePoolByPointer(void * pointer) { // free all streams which have specified pointer if(TVPArchiveHandleCacheShutdown) return; if(!TVPArchiveHandleCacheInit) return; tTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS); for(tjs_int i = 0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++) { tTVPArchiveHandleCacheItem *item = TVPArchiveHandleCachePool + i; if(item->Stream && item->Pointer == pointer) { delete item->Stream, item->Stream = NULL; item->Pointer = NULL; item->Age = 0; } } } //--------------------------------------------------------------------------- static void TVPFreeArchiveHandlePool() { // free all streams if(TVPArchiveHandleCacheShutdown) return; if(!TVPArchiveHandleCacheInit) return; tTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS); for(tjs_int i = 0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++) { tTVPArchiveHandleCacheItem *item = TVPArchiveHandleCachePool + i; if(item->Stream) { delete item->Stream, item->Stream = NULL; item->Pointer = NULL; item->Age = 0; } } } //--------------------------------------------------------------------------- static void TVPShutdownArchiveHandleCache() { // free all stream and shutdown the pool tTJSCriticalSectionHolder cs_holder(TVPArchiveHandleCacheCS); TVPArchiveHandleCacheShutdown = true; if(!TVPArchiveHandleCacheInit) return; for(tjs_int i =0; i < TVP_MAX_ARCHIVE_HANDLE_CACHE; i++) { if(TVPArchiveHandleCachePool[i].Stream) delete TVPArchiveHandleCachePool[i].Stream; } delete [] TVPArchiveHandleCachePool; } //--------------------------------------------------------------------------- static tTVPAtExit TVPShutdownArchiveCacheAtExit (TVP_ATEXIT_PRI_CLEANUP, TVPShutdownArchiveHandleCache); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPXP3Archive //--------------------------------------------------------------------------- /* TVP XPK3 virtual file system support. (in short : XP3) TVP supports no longer archive type of "XPK1/XPK2" ( XPK1/XPK2 is used by TVP ver under 0.9x ). here word "in-archive" is used for the storages which are contained in archive. */ //--------------------------------------------------------------------------- bool TVPGetXP3ArchiveOffset(tTJSBinaryStream *st, const ttstr name, tjs_uint64 & offset, bool raise) { st->SetPosition(0); tjs_uint8 mark[11+1]; static tjs_uint8 XP3Mark1[] = { 0x58/*'X'*/, 0x50/*'P'*/, 0x33/*'3'*/, 0x0d/*'\r'*/, 0x0a/*'\n'*/, 0x20/*' '*/, 0x0a/*'\n'*/, 0x1a/*EOF*/, 0xff /* sentinel */ }; static tjs_uint8 XP3Mark2[] = { 0x8b, 0x67, 0x01, 0xff/* sentinel */ }; // XP3 header mark contains: // 1. line feed and carriage return to detect corruption by unnecessary // line-feeds convertion // 2. 1A EOF mark which indicates file's text readable header ending. // 3. 8B67 KANJI-CODE to detect curruption by unnecessary code convertion // 4. 01 file structure version and character coding // higher 4 bits are file structure version, currently 0. // lower 4 bits are character coding, currently 1, is BMP 16bit Unicode. static tjs_uint8 XP3Mark[11+1]; // +1: I was warned by CodeGuard that the code will do // access overrun... because a number of 11 is not aligned by DWORD, // and the processor may read the value of DWORD at last of this array // from offset 8. Then the last 1 byte would cause a fail. static bool DoInit = true; if(DoInit) { // the XP3 header above is splitted into two part; to avoid // mis-finding of the header in the program's initialized data area. DoInit = false; memcpy(XP3Mark, XP3Mark1, 8); memcpy(XP3Mark + 8, XP3Mark2, 3); // here joins it. } mark[0] = 0; // sentinel st->ReadBuffer(mark, 11); if(mark[0] == 0x4d/*'M'*/ && mark[1] == 0x5a/*'Z'*/) { // "MZ" is a mark of Win32/DOS executables, // TVP searches the first mark of XP3 archive // in the executeble file. bool found = false; offset = 16; st->SetPosition(16); // XP3 mark must be aligned by a paragraph ( 16 bytes ) const tjs_uint one_read_size = 256*1024; tjs_uint read; tjs_uint8 *buffer = new tjs_uint8[one_read_size]; // read 256kbytes at once while(0!=(read = st->Read(buffer, one_read_size))) { tjs_uint p = 0; while(pSetPosition(11 + offset); // read all XP3 indices while(true) { if(indexdata) delete [] indexdata; tjs_uint64 index_ofs = st->ReadI64LE(); st->SetPosition(index_ofs + offset); // read index to memory tjs_uint8 index_flag; st->ReadBuffer(&index_flag, 1); tjs_uint index_size; if((index_flag & TVP_XP3_INDEX_ENCODE_METHOD_MASK) == TVP_XP3_INDEX_ENCODE_ZLIB) { // compressed index tjs_uint64 compressed_size = st->ReadI64LE(); tjs_uint64 r_index_size = st->ReadI64LE(); if((tjs_uint)compressed_size != compressed_size || (tjs_uint)r_index_size != r_index_size) TVPThrowExceptionMessage(TVPReadError); // too large to handle, or corrupted index_size = (tjs_int)r_index_size; indexdata = new tjs_uint8[index_size]; tjs_uint8 *compressed = new tjs_uint8[(tjs_uint)compressed_size]; try { st->ReadBuffer(compressed, (tjs_uint)compressed_size); unsigned long destlen = (unsigned long)index_size; int result = uncompress( /* uncompress from zlib */ (unsigned char *)indexdata, &destlen, (unsigned char*)compressed, (unsigned long)compressed_size); if(result != Z_OK || destlen != (unsigned long)index_size) TVPThrowExceptionMessage(TVPUncompressionFailed); } catch(...) { delete [] compressed; throw; } delete [] compressed; } else if((index_flag & TVP_XP3_INDEX_ENCODE_METHOD_MASK) == TVP_XP3_INDEX_ENCODE_RAW) { // uncompressed index tjs_uint64 r_index_size = st->ReadI64LE(); if((tjs_uint)r_index_size != r_index_size) TVPThrowExceptionMessage(TVPReadError); // too large to handle or corrupted index_size = (tjs_uint)r_index_size; indexdata = new tjs_uint8[index_size]; st->ReadBuffer(indexdata, index_size); } else { // unknown encode method TVPThrowExceptionMessage(TVPReadError); } // read index information from memory tjs_uint ch_file_start = 0; tjs_uint ch_file_size = index_size; //Count = 0; for(;;) { // find 'File' chunk if(!FindChunk(indexdata, cn_File, ch_file_start, ch_file_size)) break; // not found // find 'info' sub-chunk tjs_uint ch_info_start = ch_file_start; tjs_uint ch_info_size = ch_file_size; if(!FindChunk(indexdata, cn_info, ch_info_start, ch_info_size)) TVPThrowExceptionMessage(TVPReadError); // read info sub-chunk tArchiveItem item; tjs_uint32 flags = ReadI32FromMem(indexdata + ch_info_start + 0); if(!TVPAllowExtractProtectedStorage && (flags & TVP_XP3_FILE_PROTECTED)) TVPThrowExceptionMessage( TVPSpecifiedStorageHadBeenProtected ); item.OrgSize = ReadI64FromMem(indexdata + ch_info_start + 4); item.ArcSize = ReadI64FromMem(indexdata + ch_info_start + 12); tjs_int len = ReadI16FromMem(indexdata + ch_info_start + 20); ttstr name = TVPStringFromBMPUnicode( (const tjs_uint16 *)(indexdata + ch_info_start + 22), len); item.Name = name; if (normalizeName) NormalizeInArchiveStorageName(item.Name); // find 'segm' sub-chunk // Each of in-archive storages can be splitted into some segments. // Each segment can be compressed or uncompressed independently. // segments can share partial area of archive storage. ( this is used for // OggVorbis' VQ code book sharing ) tjs_uint ch_segm_start = ch_file_start; tjs_uint ch_segm_size = ch_file_size; if(!FindChunk(indexdata, cn_segm, ch_segm_start, ch_segm_size)) TVPThrowExceptionMessage(TVPReadError); // read segm sub-chunk tjs_int segment_count = ch_segm_size / 28; tjs_uint64 offset_in_archive = 0; for(tjs_int i = 0; i= ItemVector.size()) TVPThrowExceptionMessage(TVPReadError); tArchiveItem &item = ItemVector[idx]; tTJSBinaryStream *stream = TVPGetCachedArchiveHandle(this, ArchiveName); tTVPXP3ArchiveStream *out; try { out = new tTVPXP3ArchiveStream(this, idx, &(item.Segments), stream, item.OrgSize); if (TVPXP3ArchiveContentFilter) { tjs_int result = TVPXP3ArchiveContentFilter(item.Name, ArchiveName, item.OrgSize, &out->GetFilterContext()); #define XP3_CONTENT_FILTER_FETCH_FULLDATA 1 if (result == XP3_CONTENT_FILTER_FETCH_FULLDATA) { tTVPMemoryStream *memstr = new tTVPMemoryStream(); memstr->SetSize(item.OrgSize); out->ReadBuffer(memstr->GetInternalBuffer(), item.OrgSize); delete out; return memstr; } } } catch(...) { TVPReleaseCachedArchiveHandle(this, stream); throw; } return out; } //--------------------------------------------------------------------------- bool tTVPXP3Archive::FindChunk(const tjs_uint8 *data, const tjs_uint8 * name, tjs_uint &start, tjs_uint &size) { tjs_uint start_save = start; tjs_uint size_save = size; tjs_uint pos = 0; while(pos < size) { bool found = !memcmp(data + start, name, 4); start += 4; tjs_uint64 r_size = ReadI64FromMem(data + start); start += 8; tjs_uint size_chunk = (tjs_uint)r_size; if(size_chunk != r_size) TVPThrowExceptionMessage(TVPReadError); if(found) { // found size = size_chunk; return true; } start += size_chunk; pos += size_chunk + 4 + 8; } start = start_save; size = size_save; return false; } //--------------------------------------------------------------------------- tjs_int16 tTVPXP3Archive::ReadI16FromMem(const tjs_uint8 *mem) { tjs_uint16 ret = (tjs_uint16)mem[0] | ((tjs_uint16)mem[1] << 8); return (tjs_int16)ret; } //--------------------------------------------------------------------------- tjs_int32 tTVPXP3Archive::ReadI32FromMem(const tjs_uint8 *mem) { tjs_uint32 ret = (tjs_uint32)mem[0] | ((tjs_uint32)mem[1] << 8) | ((tjs_uint32)mem[2] << 16) | ((tjs_uint32)mem[3] << 24); return (tjs_int32)ret; } //--------------------------------------------------------------------------- tjs_int64 tTVPXP3Archive::ReadI64FromMem(const tjs_uint8 *mem) { tjs_uint64 ret = (tjs_uint64)mem[0] | ((tjs_uint64)mem[1] << 8) | ((tjs_uint64)mem[2] << 16) | ((tjs_uint64)mem[3] << 24) | ((tjs_uint64)mem[4] << 32) | ((tjs_uint64)mem[5] << 40) | ((tjs_uint64)mem[6] << 48) | ((tjs_uint64)mem[7] << 56); return (tjs_int64)ret; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Compressed segment cache related //--------------------------------------------------------------------------- #define TVP_SEGCACHE_ONE_LIMIT (1024*1024) // max size limit for each segment #define TVP_SEGCACHE_TOTAL_LIMIT (1024*1024) // total segment cache size tjs_uint TVPSegmentCacheLimit = TVP_SEGCACHE_TOTAL_LIMIT; //--------------------------------------------------------------------------- struct tTVPSegmentCacheSearchData { ttstr Name; // archive name tjs_int StorageIndex; // storage index in archive tjs_int SegmentIndex; // segment index in storage bool operator == (const tTVPSegmentCacheSearchData &rhs) const { return Name == rhs.Name && StorageIndex == rhs.StorageIndex && SegmentIndex == rhs.SegmentIndex; } }; //--------------------------------------------------------------------------- class tTVPSegmentCacheSearchHashFunc { public: static tjs_uint32 Make(const tTVPSegmentCacheSearchData &val) { tjs_uint32 v = tTJSHashFunc::Make(val.Name); v ^= val.StorageIndex; v ^= (val.SegmentIndex<<2); return v; } }; //--------------------------------------------------------------------------- class tTVPSegmentData { tjs_int RefCount; tjs_uint Size; tjs_uint8 *Data; public: tTVPSegmentData() { RefCount = 1; Size = 0; Data = NULL; } ~tTVPSegmentData() { if(Data) delete [] Data; } void SetData(unsigned long outsize, tTJSBinaryStream *instream, unsigned long insize) { // uncompress data tjs_uint8 * indata = new tjs_uint8 [insize]; try { instream->Read(indata, insize); Data = new tjs_uint8 [outsize]; unsigned long destlen = outsize; int result = uncompress( (unsigned char*)Data, &outsize, (unsigned char*)indata, insize); if(result != Z_OK || destlen != outsize) TVPThrowExceptionMessage(TVPUncompressionFailed); Size = outsize; } catch(...) { delete [] indata; throw; } delete [] indata; } const tjs_uint8 * GetData() const { return Data; } tjs_uint GetSize() const { return Size; } void AddRef() { RefCount ++; } void Release() { if(RefCount == 1) { delete this; } else { RefCount--; } } }; //--------------------------------------------------------------------------- typedef tTJSRefHolder tTVPSegmentDataHolder; typedef tTJSHashTable tTVPSegmentCache; static tTVPSegmentCache TVPSegmentCache; static tjs_uint TVPSegmentCacheTotalBytes = 0; static tTJSCriticalSection TVPSegmentCacheCS; //--------------------------------------------------------------------------- static void TVPCheckSegmentCacheLimit() { tTJSCriticalSectionHolder cs_holder(TVPSegmentCacheCS); while(TVPSegmentCacheTotalBytes > TVPSegmentCacheLimit) { // chop last segment tTVPSegmentCache::tIterator i; i = TVPSegmentCache.GetLast(); if(!i.IsNull()) { tjs_uint size = i.GetValue().GetObjectNoAddRef()->GetSize(); TVPSegmentCacheTotalBytes -= size; TVPSegmentCache.ChopLast(1); } else { break; } } } //--------------------------------------------------------------------------- void TVPClearXP3SegmentCache() { tTJSCriticalSectionHolder cs_holder(TVPSegmentCacheCS); TVPSegmentCache.Clear(); TVPSegmentCacheTotalBytes = 0; } //--------------------------------------------------------------------------- struct tTVPClearSegmentCacheCallback : public tTVPCompactEventCallbackIntf { virtual void TJS_INTF_METHOD OnCompact(tjs_int level) { if(level >= TVP_COMPACT_LEVEL_DEACTIVATE) { // clear the segment cache on application deactivate TVPClearXP3SegmentCache(); // also free archive handle pool TVPFreeArchiveHandlePool(); } } } static TVPClearSegmentCacheCallback; static bool TVPClearSegmentCacheCallbackInit = false; //--------------------------------------------------------------------------- static tTVPSegmentData * TVPSearchFromSegmentCache( const tTVPSegmentCacheSearchData &sdata, tjs_uint32 hash) { tTJSCriticalSectionHolder cs_holder(TVPSegmentCacheCS); tTVPSegmentDataHolder * ptr = TVPSegmentCache.FindAndTouchWithHash(sdata, hash); if(ptr) { // found in cache return ptr->GetObject(); // add-refed } return NULL; // not found in cache } //--------------------------------------------------------------------------- static void TVPPushToSegmentCache(const tTVPSegmentCacheSearchData &sdata, tjs_uint32 hash, tTVPSegmentData *data) { if(!TVPClearSegmentCacheCallbackInit) { TVPAddCompactEventHook(&TVPClearSegmentCacheCallback); TVPClearSegmentCacheCallbackInit = true; } tTJSCriticalSectionHolder cs_holder(TVPSegmentCacheCS); tTVPSegmentDataHolder holder(data); TVPSegmentCache.AddWithHash(sdata, hash, holder); TVPSegmentCacheTotalBytes += data->GetSize(); TVPCheckSegmentCacheLimit(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPXP3ArchiveStream : stream class for in-archive storage //--------------------------------------------------------------------------- tTVPXP3ArchiveStream::tTVPXP3ArchiveStream(tTVPXP3Archive *owner, tjs_int storageindex, std::vector *segments, tTJSBinaryStream * stream, tjs_uint64 orgsize) { StorageIndex = storageindex; Segments = segments; SegmentData = NULL; CurSegmentNum = 0; CurSegment = &(Segments->operator [](0)); SegmentPos = 0; SegmentRemain = CurSegment->OrgSize; SegmentOpened = false; CurPos = 0; LastOpenedSegmentNum = -1; Owner = owner; Owner->AddRef(); // hook Stream = stream; OrgSize = orgsize; } //--------------------------------------------------------------------------- tTVPXP3ArchiveStream::~tTVPXP3ArchiveStream() { TVPReleaseCachedArchiveHandle(Owner, Stream); Owner->Release(); // unhook if(SegmentData) SegmentData->Release(); } //--------------------------------------------------------------------------- void tTVPXP3ArchiveStream::EnsureSegment() { // ensure accessing to current segment if(SegmentOpened) return; if(LastOpenedSegmentNum == CurSegmentNum) { if(!CurSegment->IsCompressed) Stream->SetPosition(CurSegment->Start + SegmentPos); return; } // erase buffer if(SegmentData) SegmentData->Release(), SegmentData = NULL; // is compressed segment ? if(CurSegment->IsCompressed) { // a compressed segment if(CurSegment->OrgSize >= TVP_SEGCACHE_ONE_LIMIT) { // too large to cache Stream->SetPosition(CurSegment->Start); SegmentData = new tTVPSegmentData; SegmentData->SetData((tjs_uint)CurSegment->OrgSize, Stream, (tjs_uint)CurSegment->ArcSize); } else { // search thru segment cache tTVPSegmentCacheSearchData sdata; sdata.Name = Owner->GetName(); sdata.StorageIndex = StorageIndex; sdata.SegmentIndex = CurSegmentNum; tjs_uint32 hash; hash = tTVPSegmentCacheSearchHashFunc::Make(sdata); SegmentData = TVPSearchFromSegmentCache(sdata, hash); if(!SegmentData) { // not found in cache Stream->SetPosition(CurSegment->Start); SegmentData = new tTVPSegmentData; SegmentData->SetData((tjs_uint)CurSegment->OrgSize, Stream, (tjs_uint)CurSegment->ArcSize); // add to cache TVPPushToSegmentCache(sdata, hash, SegmentData); } } } else { // not a compressed segment Stream->SetPosition(CurSegment->Start + SegmentPos); } SegmentOpened = true; LastOpenedSegmentNum = CurSegmentNum; } //--------------------------------------------------------------------------- void tTVPXP3ArchiveStream::SeekToPosition(tjs_uint64 pos) { // open segment at 'pos' and seek // pos must between zero thru OrgSize if(CurPos == pos) return; // do binary search to determine current segment number tjs_int st = 0; tjs_int et = (tjs_int)Segments->size(); tjs_int seg_num; while(true) { if(et-st <= 1) { seg_num = st; break; } tjs_int m = st + (et-st)/2; if(Segments->operator[](m).Offset > pos) et = m; else st = m; } CurSegmentNum = seg_num; CurSegment = &(Segments->operator [](CurSegmentNum)); SegmentOpened = false; SegmentPos = pos - CurSegment->Offset; SegmentRemain = CurSegment->OrgSize - SegmentPos; CurPos = pos; } //--------------------------------------------------------------------------- bool tTVPXP3ArchiveStream::OpenNextSegment() { // open next segment if(CurSegmentNum == (tjs_int)(Segments->size() -1)) return false; // no more segments CurSegmentNum ++; CurSegment = &(Segments->operator [](CurSegmentNum)); SegmentOpened = false; SegmentPos = 0; SegmentRemain = CurSegment->OrgSize; CurPos = CurSegment->Offset; EnsureSegment(); return true; } //--------------------------------------------------------------------------- tjs_uint64 TJS_INTF_METHOD tTVPXP3ArchiveStream::Seek(tjs_int64 offset, tjs_int whence) { tjs_int64 newpos; switch(whence) { case TJS_BS_SEEK_SET: newpos = offset; if(newpos >= 0 && newpos <= static_cast(OrgSize) ) { SeekToPosition(newpos); } return CurPos; case TJS_BS_SEEK_CUR: newpos = offset + CurPos; if(newpos >= 0 && newpos <= static_cast(OrgSize) ) { SeekToPosition(newpos); } return CurPos; case TJS_BS_SEEK_END: newpos = offset + OrgSize; if(newpos >= 0 && newpos <= static_cast(OrgSize) ) { SeekToPosition(newpos); } return CurPos; } return CurPos; } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPXP3ArchiveStream::Read(void *buffer, tjs_uint read_size) { EnsureSegment(); tjs_uint write_size = 0; while(read_size) { while(SegmentRemain == 0) { // must go next segment if(!OpenNextSegment()) // open next segment return write_size; // could not read more } tjs_uint one_size = read_size > SegmentRemain ? (tjs_uint)SegmentRemain : read_size; if(CurSegment->IsCompressed) { // compressed segment; read from uncompressed data in memory memcpy((tjs_uint8*)buffer + write_size, SegmentData->GetData() + (tjs_uint)SegmentPos, one_size); } else { // read directly from stream Stream->ReadBuffer((tjs_uint8*)buffer + write_size, one_size); } // execute filter (for encryption method) if(TVPXP3ArchiveExtractionFilter) { tTVPXP3ExtractionFilterInfo info(CurPos, (tjs_uint8*)buffer + write_size, one_size, Owner->GetFileHash(StorageIndex), Owner->GetName(StorageIndex)); TVPXP3ArchiveExtractionFilter ( (tTVPXP3ExtractionFilterInfo*) &info, &FilterContext ); } // adjust members SegmentPos += one_size; CurPos += one_size; SegmentRemain -= one_size; read_size -= one_size; write_size += one_size; } return write_size; } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPXP3ArchiveStream::Write(const void *buffer, tjs_uint write_size) { return 0; } //--------------------------------------------------------------------------- tjs_uint64 TJS_INTF_METHOD tTVPXP3ArchiveStream::GetSize() { return OrgSize; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Archive extraction utility //--------------------------------------------------------------------------- #define TVP_LOCAL_TEMP_COPY_BLOCK_SIZE 65536*2 #if 0 // this routine is obsoleted because the Releaser includes over 256-characters // file name if the user specifies "protect over the archive" option. // Windows cannot handle such too long filename. void TVPExtractArchive(const ttstr & name, const ttstr & _destdir, bool allowextractprotected) { // extract file to bool TVPAllowExtractProtectedStorage_save = TVPAllowExtractProtectedStorage; TVPAllowExtractProtectedStorage = allowextractprotected; try { ttstr destdir(_destdir); tjs_char last = _destdir.GetLastChar(); if(_destdir.GetLen() >= 1 && (last != TJS_W('/') && last != TJS_W('\\'))) destdir += TJS_W('/'); tTVPArchive *arc = TVPOpenArchive(name); try { tjs_int count = arc->GetCount(); for(tjs_int i = 0; i < count; i++) { ttstr name = arc->GetName(i); tTJSBinaryStream *src = arc->CreateStreamByIndex(i); try { tTVPStreamHolder dest(destdir + name, TJS_BS_WRITE); tjs_uint8 * buffer = new tjs_uint8[TVP_LOCAL_TEMP_COPY_BLOCK_SIZE]; try { tjs_uint read; while(true) { read = src->Read(buffer, TVP_LOCAL_TEMP_COPY_BLOCK_SIZE); if(read == 0) break; dest->WriteBuffer(buffer, read); } } catch(...) { delete [] buffer; throw; } delete [] buffer; } catch(...) { // delete src; // throw; } delete src; } } catch(...) { arc->Release(); throw; } arc->Release(); } catch(...) { TVPAllowExtractProtectedStorage = TVPAllowExtractProtectedStorage_save; throw; } TVPAllowExtractProtectedStorage = TVPAllowExtractProtectedStorage_save; } #endif //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/XP3Archive.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // XP3 virtual file system support //--------------------------------------------------------------------------- #ifndef XP3ArchiveH #define XP3ArchiveH #include "StorageIntf.h" /*[*/ //--------------------------------------------------------------------------- // Extraction filter related //--------------------------------------------------------------------------- #pragma pack(push, 4) struct tTVPXP3ExtractionFilterInfo { const tjs_uint SizeOfSelf; // structure size of tTVPXP3ExtractionFilterInfo itself const tjs_uint64 Offset; // offset of the buffer data in uncompressed stream position void * Buffer; // target data buffer const tjs_uint BufferSize; // buffer size in bytes pointed by "Buffer" const tjs_uint32 FileHash; // hash value of the file (since inteface v2) const ttstr &FileName; tTVPXP3ExtractionFilterInfo(tjs_uint64 offset, void *buffer, tjs_uint buffersize, tjs_uint32 filehash, const ttstr& filename) : Offset(offset), Buffer(buffer), BufferSize(buffersize), FileHash(filehash), FileName(filename), SizeOfSelf(sizeof(tTVPXP3ExtractionFilterInfo)) {;} }; #pragma pack(pop) #ifndef TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION #ifdef _WIN32 #define TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION _stdcall #else #define TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION #endif #endif // TVP_tTVPXP3ArchiveExtractionFilter_CONV is _stdcall on win32 platforms, // for backward application compatibility. typedef void (TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION * tTVPXP3ArchiveExtractionFilter)(tTVPXP3ExtractionFilterInfo *info, tTJSVariant *ctx); typedef tjs_int (TVP_tTVPXP3ArchiveExtractionFilter_CONVENTION * tTVPXP3ArchiveContentFilter)(const ttstr &filepath, const ttstr &archivename, tjs_uint64 filesize, tTJSVariant *ctx); /*]*/ //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(void, TVPSetXP3ArchiveExtractionFilter, (tTVPXP3ArchiveExtractionFilter filter)); TJS_EXP_FUNC_DEF(void, TVPSetXP3ArchiveContentFilter, (tTVPXP3ArchiveContentFilter filter)); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPXP3Archive : XP3 ( TVP's native archive format ) Implmentation //--------------------------------------------------------------------------- #define TVP_XP3_INDEX_ENCODE_METHOD_MASK 0x07 #define TVP_XP3_INDEX_ENCODE_RAW 0 #define TVP_XP3_INDEX_ENCODE_ZLIB 1 #define TVP_XP3_INDEX_CONTINUE 0x80 #define TVP_XP3_FILE_PROTECTED (1<<31) #define TVP_XP3_SEGM_ENCODE_METHOD_MASK 0x07 #define TVP_XP3_SEGM_ENCODE_RAW 0 #define TVP_XP3_SEGM_ENCODE_ZLIB 1 //--------------------------------------------------------------------------- extern bool TVPIsXP3Archive(const ttstr &name); // check XP3 archive extern void TVPClearXP3SegmentCache(); // clear XP3 segment cache //--------------------------------------------------------------------------- struct tTVPXP3ArchiveSegment { tjs_uint64 Start; // start position in archive storage tjs_uint64 Offset; // offset in in-archive storage (in uncompressed offset) tjs_uint64 OrgSize; // original segment (uncompressed) size tjs_uint64 ArcSize; // in-archive segment (compressed) size bool IsCompressed; // is compressed ? }; //--------------------------------------------------------------------------- class tTVPXP3Archive : public tTVPArchive { public: struct tArchiveItem { ttstr Name; tjs_uint32 FileHash; tjs_uint64 OrgSize; // original ( uncompressed ) size tjs_uint64 ArcSize; // in-archive size std::vector Segments; bool operator < (const tArchiveItem &rhs) const { return this->Name < rhs.Name; } }; tjs_int Count = 0; std::vector ItemVector; void Init(tTJSBinaryStream *st, tjs_int64 offset, bool normalizeName = true); public: tTVPXP3Archive(const ttstr & name, int) : tTVPArchive(name) {} tTVPXP3Archive(const ttstr & name, tTJSBinaryStream *st = nullptr, tjs_int64 offset = -1, bool normalizeFileName = true); ~tTVPXP3Archive(); static tTVPArchive *Create(const ttstr & name, tTJSBinaryStream *st = nullptr, bool normalizeFileName = true); tjs_uint GetCount() { return Count; } const ttstr & GetName(tjs_uint idx) const { return ItemVector[idx].Name; } tjs_uint32 GetFileHash(tjs_uint idx) const { return ItemVector[idx].FileHash; } ttstr GetName(tjs_uint idx) { return ItemVector[idx].Name; } const ttstr & GetName() const { return ArchiveName; } tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx); private: static bool FindChunk(const tjs_uint8 *data, const tjs_uint8 * name, tjs_uint &start, tjs_uint &size); static tjs_int16 ReadI16FromMem(const tjs_uint8 *mem); static tjs_int32 ReadI32FromMem(const tjs_uint8 *mem); static tjs_int64 ReadI64FromMem(const tjs_uint8 *mem); }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPXP3ArchiveStream : XP3 In-Archive Stream Implmentation //--------------------------------------------------------------------------- class tTVPSegmentData; class tTVPXP3ArchiveStream : public tTJSBinaryStream { tTVPXP3Archive * Owner; tjs_int StorageIndex; // index in archive std::vector * Segments; tTJSBinaryStream * Stream; tjs_uint64 OrgSize; // original storage size tjs_int CurSegmentNum; tTVPXP3ArchiveSegment *CurSegment; // currently opened segment ( NULL for not opened ) tjs_int LastOpenedSegmentNum; tjs_uint64 CurPos; // current position in absolute file position tjs_uint64 SegmentRemain; // remain bytes in current segment tjs_uint64 SegmentPos; // offset from current segment's start tTVPSegmentData *SegmentData; // uncompressed segment data bool SegmentOpened; tTJSVariant FilterContext; public: tTVPXP3ArchiveStream(tTVPXP3Archive *owner, tjs_int storageindex, std::vector *segments, tTJSBinaryStream *stream, tjs_uint64 orgsize); ~tTVPXP3ArchiveStream(); tTJSVariant &GetFilterContext() { return FilterContext; } private: void EnsureSegment(); // ensure accessing to current segment void SeekToPosition(tjs_uint64 pos); // open segment at 'pos' and seek bool OpenNextSegment(); public: tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence); tjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size); tjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size); tjs_uint64 TJS_INTF_METHOD GetSize(); }; //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/ZIPArchive.cpp ================================================ #include "tjsCommHead.h" #include "StorageIntf.h" #include "UtilStreams.h" #include #ifndef NOUNCRYPT #define NOUNCRYPT #endif #include "unzip/ioapi_mem.h" #include "unzip/unzip.h" #undef ZEXPORT #define ZEXPORT //using namespace cocos2d; typedef cocos2d::ZPOS64_T ZPOS64_T; typedef cocos2d::zlib_filefunc64_32_def zlib_filefunc64_32_def; typedef cocos2d::unz_global_info64 unz_global_info64; typedef cocos2d::zlib_filefunc_def zlib_filefunc_def; typedef cocos2d::zlib_filefunc64_def zlib_filefunc64_def; typedef cocos2d::unz_global_info unz_global_info; typedef cocos2d::tm_unz tm_unz; typedef struct unz_file_info_s { uLong version; /* version made by 2 bytes */ uLong version_needed; /* version needed to extract 2 bytes */ uLong flag; /* general purpose bit flag 2 bytes */ uLong compression_method; /* compression method 2 bytes */ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ uLong crc; /* crc-32 4 bytes */ uLong compressed_size; /* compressed size 4 bytes */ uLong uncompressed_size; /* uncompressed size 4 bytes */ uLong size_filename; /* filename length 2 bytes */ uLong size_file_extra; /* extra field length 2 bytes */ uLong size_file_comment; /* file comment length 2 bytes */ ZPOS64_T offset_curfile; uLong disk_num_start; /* disk number start 2 bytes */ uLong internal_fa; /* internal file attributes 2 bytes */ uLong external_fa; /* external file attributes 4 bytes */ tm_unz tmu_date; } unz_file_info; typedef cocos2d::unz_file_pos unz_file_pos; typedef struct unz64_file_pos_s { ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ ZPOS64_T num_of_file; /* # of file */ } unz64_file_pos; #ifdef STDC # include # include # include #endif #ifdef NO_ERRNO_H extern int errno; #else # include #endif #ifndef local # define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ #ifndef CASESENSITIVITYDEFAULT_NO # if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) # define CASESENSITIVITYDEFAULT_NO # endif #endif #ifndef UNZ_BUFSIZE #define UNZ_BUFSIZE (16384) #endif #ifndef UNZ_MAXFILENAMEINZIP #define UNZ_MAXFILENAMEINZIP (256) #endif #ifndef ALLOC # define ALLOC(size) (malloc(size)) #endif #ifndef TRYFREE # define TRYFREE(p) {if (p) free(p);} #endif #define SIZECENTRALDIRITEM (0x2e) #define SIZEZIPLOCALHEADER (0x1e) const char unz_copyright[] = " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; /* unz_file_info_interntal contain internal info about a file in zipfile*/ typedef struct unz_file_info64_internal_s { ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ } unz_file_info64_internal; /* file_in_zip_read_info_s contain internal information about a file in zipfile, when reading and decompress it */ typedef struct { char *read_buffer; /* internal buffer for compressed data */ z_stream stream; /* zLib stream structure for inflate */ #ifdef HAVE_BZIP2 bz_stream bstream; /* bzLib stream structure for bziped */ #endif ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ uLong stream_initialised; /* flag set if stream structure is initialized*/ ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ uInt size_local_extrafield;/* size of the local extra field */ ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ ZPOS64_T total_out_64; uLong crc32; /* crc32 of all data uncompressed */ uLong crc32_wait; /* crc32 we must obtain after decompress all */ ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ //zlib_filefunc64_32_def z_filefunc; voidpf filestream; /* io structure of the zipfile */ uLong compression_method; /* compression method (0==store) */ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ int raw; } file_in_zip64_read_info_s; /* unz_file_info contain information about a file in the zipfile */ typedef struct unz_file_info64_s { uLong version; /* version made by 2 bytes */ uLong version_needed; /* version needed to extract 2 bytes */ uLong flag; /* general purpose bit flag 2 bytes */ uLong compression_method; /* compression method 2 bytes */ uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ uLong crc; /* crc-32 4 bytes */ ZPOS64_T compressed_size; /* compressed size 8 bytes */ ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ uLong size_filename; /* filename length 2 bytes */ uLong size_file_extra; /* extra field length 2 bytes */ uLong size_file_comment; /* file comment length 2 bytes */ ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ uLong disk_num_start; /* disk number start 2 bytes */ uLong internal_fa; /* internal file attributes 2 bytes */ uLong external_fa; /* external file attributes 4 bytes */ tm_unz tmu_date; } unz_file_info64; /* unz64_s contain internal information about the zipfile */ typedef struct { //zlib_filefunc64_32_def z_filefunc; int is64bitOpenFunction; voidpf filestream; /* io structure of the zipfile */ unz_global_info64 gi; /* public global information */ ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ ZPOS64_T num_file; /* number of the current file in the zipfile*/ ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ ZPOS64_T central_pos; /* position of the beginning of the central dir*/ ZPOS64_T size_central_dir; /* size of the central directory */ ZPOS64_T offset_central_dir; /* offset of start of central directory with respect to the starting disk number */ unz_file_info64 cur_file_info; /* public info about the current file in zip*/ unz_file_info64_internal cur_file_info_internal; /* private info about it*/ file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current file if we are decompressing it */ int encrypted; int isZip64; # ifndef NOUNCRYPT unsigned long keys[3]; /* keys defining the pseudo-random sequence */ const unsigned long* pcrc_32_tab; # endif } unz64_s; #ifndef NOUNCRYPT #include "crypt.h" #endif static voidpf zip_open64file(voidpf opaque, const void * filename, int mode) { if (mode == (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING)) return (voidpf)filename; return nullptr; } static uLong zip_readfile(voidpf, voidpf s, void *buf, uLong size); static uLong zip_writefile(voidpf, voidpf s, const void *buf, uLong size); static ZPOS64_T zip_tell64file(voidpf, voidpf s); static long zip_seek64file(voidpf, voidpf s, ZPOS64_T offset, int origin); static int zip_closefile(voidpf, voidpf s) { // delete ((tTJSBinaryStream*)s); return 0; } static zlib_filefunc64_32_def zipfunc = { { zip_open64file, zip_readfile, zip_writefile, zip_tell64file, zip_seek64file, zip_closefile, nullptr, nullptr }, nullptr, nullptr, nullptr }; /* =========================================================================== Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. IN assertion: the stream s has been successfully opened for reading. */ local int unz64local_getByte OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) { unsigned char c; int err = (int)zip_readfile(nullptr,filestream,&c,1); if (err==1) { *pi = (int)c; return UNZ_OK; } else { // if (ZERROR64(nullptr,filestream)) // return UNZ_ERRNO; // else return UNZ_EOF; } } /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ local int unz64local_getShort OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX) { uLong x ; int i = 0; int err; err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((uLong)i)<<8; if (err==UNZ_OK) *pX = x; else *pX = 0; return err; } local int unz64local_getLong OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX) { uLong x ; int i = 0; int err; err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x = (uLong)i; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((uLong)i)<<8; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((uLong)i)<<16; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x += ((uLong)i)<<24; if (err==UNZ_OK) *pX = x; else *pX = 0; return err; } local int unz64local_getLong64 OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) { ZPOS64_T x ; int i = 0; int err; err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x = (ZPOS64_T)i; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<8; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<16; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<24; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<32; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<40; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<48; if (err==UNZ_OK) err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); x |= ((ZPOS64_T)i)<<56; if (err==UNZ_OK) *pX = x; else *pX = 0; return err; } /* My own strcmpi / strcasecmp */ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) { for (;;) { char c1=*(fileName1++); char c2=*(fileName2++); if ((c1>='a') && (c1<='z')) c1 -= 0x20; if ((c2>='a') && (c2<='z')) c2 -= 0x20; if (c1=='\0') return ((c2=='\0') ? 0 : -1); if (c2=='\0') return 1; if (c1c2) return 1; } } #ifdef CASESENSITIVITYDEFAULT_NO #define CASESENSITIVITYDEFAULTVALUE 2 #else #define CASESENSITIVITYDEFAULTVALUE 1 #endif #ifndef STRCMPCASENOSENTIVEFUNCTION #define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal #endif /* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparison is case sensitivity (like strcmp) If iCaseSenisivity = 2, comparison is not case sensitivity (like strcmpi or strcasecmp) If iCaseSenisivity = 0, case sensitivity is default of your operating system (like 1 on Unix, 2 on Windows) */ int ZEXPORT unzStringFileNameCompare (const char* fileName1, const char* fileName2, int iCaseSensitivity) { if (iCaseSensitivity==0) iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; if (iCaseSensitivity==1) return strcmp(fileName1,fileName2); return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); } #ifndef BUFREADCOMMENT #define BUFREADCOMMENT (0x400) #endif /* Locate the Central directory of a zipfile (at the end, just before the global comment) */ local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ ZPOS64_T uPosFound=0; if (zip_seek64file(nullptr, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) return 0; uSizeFile = zip_tell64file(nullptr, filestream); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; while (uBackReaduMaxBack) uBackRead = uMaxBack; else uBackRead+=BUFREADCOMMENT; uReadPos = uSizeFile-uBackRead ; uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); if (zip_seek64file(nullptr, filestream, uReadPos, ZLIB_FILEFUNC_SEEK_SET) != 0) break; if (zip_readfile(nullptr, filestream, buf, uReadSize) != uReadSize) break; for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) { uPosFound = uReadPos+i; break; } if (uPosFound!=0) break; } TRYFREE(buf); return uPosFound; } /* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */ local ZPOS64_T unz64local_SearchCentralDir64 OF(( const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { unsigned char* buf; ZPOS64_T uSizeFile; ZPOS64_T uBackRead; ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ ZPOS64_T uPosFound=0; uLong uL; ZPOS64_T relativeOffset; if (zip_seek64file(nullptr,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) return 0; uSizeFile = zip_tell64file(nullptr,filestream); if (uMaxBack>uSizeFile) uMaxBack = uSizeFile; buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); if (buf==NULL) return 0; uBackRead = 4; while (uBackReaduMaxBack) uBackRead = uMaxBack; else uBackRead+=BUFREADCOMMENT; uReadPos = uSizeFile-uBackRead ; uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); if (zip_seek64file(nullptr,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) break; if (zip_readfile(nullptr,filestream,buf,uReadSize)!=uReadSize) break; for (i=(int)uReadSize-3; (i--)>0;) if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) { uPosFound = uReadPos+i; break; } if (uPosFound!=0) break; } TRYFREE(buf); if (uPosFound == 0) return 0; /* Zip64 end of central directory locator */ if (zip_seek64file(nullptr,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) return 0; /* the signature, already checked */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; /* number of the disk with the start of the zip64 end of central directory */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; if (uL != 0) return 0; /* relative offset of the zip64 end of central directory record */ if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) return 0; /* total number of disks */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; if (uL != 1) return 0; /* Goto end of central directory record */ if (zip_seek64file(nullptr,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) return 0; /* the signature */ if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) return 0; if (uL != 0x06064b50) return 0; return relativeOffset; } int ZEXPORT unzGoToFirstFile64(unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize); /* Open a Zip file. path contain the full pathname (by example, on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer "zlib/zlib114.zip". If the zipfile cannot be opened (file doesn't exist or in not valid), the return value is NULL. Else, the return value is a unzFile Handle, usable with other function of this unzip package. */ local unzFile unzOpenInternal (const void *path, zlib_filefunc64_32_def* pzlib_filefunc64_32_def, int is64bitOpenFunction) { unz64_s us; unz64_s *s; ZPOS64_T central_pos; uLong uL; uLong number_disk; /* number of the current dist, used for spanning ZIP, unsupported, always 0*/ uLong number_disk_with_CD; /* number the the disk with central dir, used for spanning ZIP, unsupported, always 0*/ ZPOS64_T number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ int err=UNZ_OK; if (unz_copyright[0]!=' ') return NULL; // us.z_filefunc.zseek32_file = NULL; // us.z_filefunc.ztell32_file = NULL; // us.z_filefunc = *pzlib_filefunc64_32_def; us.is64bitOpenFunction = is64bitOpenFunction; us.filestream = zip_open64file(nullptr, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING); if (us.filestream==NULL) return NULL; central_pos = unz64local_SearchCentralDir64(nullptr,us.filestream); if (central_pos) { uLong uS; ZPOS64_T uL64; us.isZip64 = 1; if (zip_seek64file(nullptr, us.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) err=UNZ_ERRNO; /* the signature, already checked */ if (unz64local_getLong(nullptr, us.filestream, &uL) != UNZ_OK) err=UNZ_ERRNO; /* size of zip64 end of central directory record */ if (unz64local_getLong64(nullptr, us.filestream,&uL64)!=UNZ_OK) err=UNZ_ERRNO; /* version made by */ if (unz64local_getShort(nullptr, us.filestream,&uS)!=UNZ_OK) err=UNZ_ERRNO; /* version needed to extract */ if (unz64local_getShort(nullptr, us.filestream,&uS)!=UNZ_OK) err=UNZ_ERRNO; /* number of this disk */ if (unz64local_getLong(nullptr, us.filestream,&number_disk)!=UNZ_OK) err=UNZ_ERRNO; /* number of the disk with the start of the central directory */ if (unz64local_getLong(nullptr, us.filestream,&number_disk_with_CD)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central directory on this disk */ if (unz64local_getLong64(nullptr, us.filestream,&us.gi.number_entry)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central directory */ if (unz64local_getLong64(nullptr, us.filestream,&number_entry_CD)!=UNZ_OK) err=UNZ_ERRNO; if ((number_entry_CD!=us.gi.number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=UNZ_BADZIPFILE; /* size of the central directory */ if (unz64local_getLong64(nullptr, us.filestream,&us.size_central_dir)!=UNZ_OK) err=UNZ_ERRNO; /* offset of start of central directory with respect to the starting disk number */ if (unz64local_getLong64(nullptr, us.filestream,&us.offset_central_dir)!=UNZ_OK) err=UNZ_ERRNO; us.gi.size_comment = 0; } else { central_pos = unz64local_SearchCentralDir(nullptr,us.filestream); if (central_pos==0) err=UNZ_ERRNO; us.isZip64 = 0; if (zip_seek64file(nullptr, us.filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) err=UNZ_ERRNO; /* the signature, already checked */ if (unz64local_getLong(nullptr, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; /* number of this disk */ if (unz64local_getShort(nullptr, us.filestream,&number_disk)!=UNZ_OK) err=UNZ_ERRNO; /* number of the disk with the start of the central directory */ if (unz64local_getShort(nullptr, us.filestream,&number_disk_with_CD)!=UNZ_OK) err=UNZ_ERRNO; /* total number of entries in the central dir on this disk */ if (unz64local_getShort(nullptr, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; us.gi.number_entry = uL; /* total number of entries in the central dir */ if (unz64local_getShort(nullptr, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; number_entry_CD = uL; if ((number_entry_CD!=us.gi.number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) err=UNZ_BADZIPFILE; /* size of the central directory */ if (unz64local_getLong(nullptr, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; us.size_central_dir = uL; /* offset of start of central directory with respect to the starting disk number */ if (unz64local_getLong(nullptr, us.filestream,&uL)!=UNZ_OK) err=UNZ_ERRNO; us.offset_central_dir = uL; /* zipfile comment length */ if (unz64local_getShort(nullptr, us.filestream,&us.gi.size_comment)!=UNZ_OK) err=UNZ_ERRNO; } if ((central_pospfile_in_zip_read!=NULL) unzCloseCurrentFile(file); zip_closefile(nullptr, s->filestream); TRYFREE(s); return UNZ_OK; } /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) { unz64_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; *pglobal_info=s->gi; return UNZ_OK; } int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) { unz64_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; /* to do : check if number_entry is not truncated */ pglobal_info32->number_entry = (uLong)s->gi.number_entry; pglobal_info32->size_comment = s->gi.size_comment; return UNZ_OK; } /* Translate date/time from Dos format to tm_unz (readable more easily) */ local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) { ZPOS64_T uDate; uDate = (ZPOS64_T)(ulDosDate>>16); ptm->tm_mday = (uInt)(uDate&0x1f) ; ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; } /* Get Info about the current file in the zipfile, with internal only info */ local int unz64local_GetCurrentFileInfoInternal (unzFile file, unz_file_info64 *pfile_info, unz_file_info64_internal *pfile_info_internal, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize) { unz64_s* s; unz_file_info64 file_info; unz_file_info64_internal file_info_internal; int err=UNZ_OK; uLong uMagic; long lSeek=0; uLong uL; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; if (zip_seek64file(nullptr, s->filestream, s->pos_in_central_dir+s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET)!=0) err=UNZ_ERRNO; /* we check the magic */ if (err==UNZ_OK) { if (unz64local_getLong(nullptr, s->filestream,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x02014b50) err=UNZ_BADZIPFILE; } if (unz64local_getShort(nullptr, s->filestream,&file_info.version) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(nullptr, s->filestream,&file_info.version_needed) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(nullptr, s->filestream,&file_info.flag) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(nullptr, s->filestream,&file_info.compression_method) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getLong(nullptr, s->filestream,&file_info.dosDate) != UNZ_OK) err=UNZ_ERRNO; unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); if (unz64local_getLong(nullptr, s->filestream,&file_info.crc) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getLong(nullptr, s->filestream,&uL) != UNZ_OK) err=UNZ_ERRNO; file_info.compressed_size = uL; if (unz64local_getLong(nullptr, s->filestream,&uL) != UNZ_OK) err=UNZ_ERRNO; file_info.uncompressed_size = uL; if (unz64local_getShort(nullptr, s->filestream,&file_info.size_filename) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(nullptr, s->filestream,&file_info.size_file_extra) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(nullptr, s->filestream,&file_info.size_file_comment) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(nullptr, s->filestream,&file_info.disk_num_start) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(nullptr, s->filestream,&file_info.internal_fa) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getLong(nullptr, s->filestream,&file_info.external_fa) != UNZ_OK) err=UNZ_ERRNO; // relative offset of local header if (unz64local_getLong(nullptr, s->filestream,&uL) != UNZ_OK) err=UNZ_ERRNO; file_info_internal.offset_curfile = uL; lSeek+=file_info.size_filename; if ((err==UNZ_OK) && (szFileName!=NULL)) { uLong uSizeRead ; if (file_info.size_filename0) && (fileNameBufferSize>0)) if (zip_readfile(nullptr, s->filestream, szFileName, uSizeRead) != uSizeRead) err=UNZ_ERRNO; lSeek -= uSizeRead; } // Read extrafield if ((err==UNZ_OK) && (extraField!=NULL)) { ZPOS64_T uSizeRead ; if (file_info.size_file_extrafilestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) lSeek=0; else err=UNZ_ERRNO; } if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) if (zip_readfile(nullptr, s->filestream, extraField, (uLong)uSizeRead) != uSizeRead) err=UNZ_ERRNO; lSeek += file_info.size_file_extra - (uLong)uSizeRead; } else lSeek += file_info.size_file_extra; if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) { uLong acc = 0; // since lSeek now points to after the extra field we need to move back lSeek -= file_info.size_file_extra; if (lSeek!=0) { if (zip_seek64file(nullptr, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) lSeek=0; else err=UNZ_ERRNO; } while(acc < file_info.size_file_extra) { uLong headerId; uLong dataSize; if (unz64local_getShort(nullptr, s->filestream,&headerId) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(nullptr, s->filestream,&dataSize) != UNZ_OK) err=UNZ_ERRNO; /* ZIP64 extra fields */ if (headerId == 0x0001) { uLong uL2; if (file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1) { if (unz64local_getLong64(nullptr, s->filestream,&file_info.uncompressed_size) != UNZ_OK) err=UNZ_ERRNO; } if (file_info.compressed_size == (ZPOS64_T)(unsigned long)-1) { if (unz64local_getLong64(nullptr, s->filestream,&file_info.compressed_size) != UNZ_OK) err=UNZ_ERRNO; } if (file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1) { /* Relative Header offset */ if (unz64local_getLong64(nullptr, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) err=UNZ_ERRNO; } if(file_info.disk_num_start == (unsigned long)-1) { /* Disk Start Number */ if (unz64local_getLong(nullptr, s->filestream, &uL2) != UNZ_OK) err=UNZ_ERRNO; } } else { if (zip_seek64file(nullptr, s->filestream, dataSize, ZLIB_FILEFUNC_SEEK_CUR) != 0) err=UNZ_ERRNO; } acc += 2 + 2 + dataSize; } } if ((err==UNZ_OK) && (szComment!=NULL)) { uLong uSizeRead ; if (file_info.size_file_commentfilestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) { //lSeek=0; } else err=UNZ_ERRNO; } if ((file_info.size_file_comment>0) && (commentBufferSize>0)) if (zip_readfile(nullptr, s->filestream,szComment,uSizeRead)!=uSizeRead) err=UNZ_ERRNO; //lSeek+=file_info.size_file_comment - uSizeRead; } //else // lSeek+=file_info.size_file_comment; if ((err == UNZ_OK) && (pfile_info != NULL)) { *pfile_info = file_info; pfile_info->offset_curfile = file_info_internal.offset_curfile + s->byte_before_the_zipfile; } if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) *pfile_info_internal=file_info_internal; return err; } /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, unz_file_info64 * pfile_info, char * szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char* szComment, uLong commentBufferSize) { return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, szFileName,fileNameBufferSize, extraField,extraFieldBufferSize, szComment,commentBufferSize); } int ZEXPORT unzGetCurrentFileInfo (unzFile file, unz_file_info * pfile_info, char * szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize) { int err; unz_file_info64 file_info64; err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, szFileName,fileNameBufferSize, extraField,extraFieldBufferSize, nullptr,0); if (err==UNZ_OK) { pfile_info->version = file_info64.version; pfile_info->version_needed = file_info64.version_needed; pfile_info->flag = file_info64.flag; pfile_info->compression_method = file_info64.compression_method; pfile_info->dosDate = file_info64.dosDate; pfile_info->crc = file_info64.crc; pfile_info->size_filename = file_info64.size_filename; pfile_info->size_file_extra = file_info64.size_file_extra; pfile_info->size_file_comment = file_info64.size_file_comment; pfile_info->disk_num_start = file_info64.disk_num_start; pfile_info->internal_fa = file_info64.internal_fa; pfile_info->external_fa = file_info64.external_fa; pfile_info->tmu_date = file_info64.tmu_date, pfile_info->offset_curfile = file_info64.offset_curfile; pfile_info->compressed_size = (uLong)file_info64.compressed_size; pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; } return err; } /* Set the current file of the zipfile to the first file with retrieving an information about the file. return UNZ_OK if there is no problem */ int ZEXPORT unzGoToFirstFile64 (unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize) { int err=UNZ_OK; unz64_s* s; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; s->pos_in_central_dir=s->offset_central_dir; s->num_file=0; err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, szFileName,fileNameBufferSize,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); if (pfile_info) *pfile_info = s->cur_file_info; return err; } /* Set the current file of the zipfile to the next file with retrieving an information about the file. return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ int ZEXPORT unzGoToNextFile64 (unzFile file, unz_file_info64 *pfile_info, char *szFileName, uLong fileNameBufferSize) { unz64_s* s; int err; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ if (s->num_file+1==s->gi.number_entry) return UNZ_END_OF_LIST_OF_FILE; s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; s->num_file++; err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, szFileName,fileNameBufferSize,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); if (pfile_info) *pfile_info = s->cur_file_info; return err; } /* /////////////////////////////////////////// // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) // I need random access // // Further optimization could be realized by adding an ability // to cache the directory in memory. The goal being a single // comprehensive file read to put the file I need in a memory. */ /* typedef struct unz_file_pos_s { ZPOS64_T pos_in_zip_directory; // offset in file ZPOS64_T num_of_file; // # of file } unz_file_pos; */ int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) { unz64_s* s; if (file==NULL || file_pos==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; if (!s->current_file_ok) return UNZ_END_OF_LIST_OF_FILE; file_pos->pos_in_zip_directory = s->pos_in_central_dir; file_pos->num_of_file = s->num_file; return UNZ_OK; } int ZEXPORT unzGetFilePos( unzFile file, unz_file_pos* file_pos) { unz64_file_pos file_pos64; int err = unzGetFilePos64(file,&file_pos64); if (err==UNZ_OK) { file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; file_pos->num_of_file = (uLong)file_pos64.num_of_file; } return err; } int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) { unz64_s* s; int err; if (file==NULL || file_pos==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; /* jump to the right spot */ s->pos_in_central_dir = file_pos->pos_in_zip_directory; s->num_file = file_pos->num_of_file; /* set the current file */ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); /* return results */ s->current_file_ok = (err == UNZ_OK); return err; } int ZEXPORT unzGoToFilePos( unzFile file, unz_file_pos* file_pos) { unz64_file_pos file_pos64; if (file_pos == NULL) return UNZ_PARAMERROR; file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; file_pos64.num_of_file = file_pos->num_of_file; return unzGoToFilePos64(file,&file_pos64); } /* // Unzip Helper Functions - should be here? /////////////////////////////////////////// */ /* Read the local header of the current zipfile Check the coherency of the local header and info in the end of central directory about this file store in *piSizeVar the size of extra info in local header (filename and size of extra field data) */ local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, ZPOS64_T * poffset_local_extrafield, uInt * psize_local_extrafield) { uLong uMagic,uData,uFlags; uLong size_filename; uLong size_extra_field; int err=UNZ_OK; *piSizeVar = 0; *poffset_local_extrafield = 0; *psize_local_extrafield = 0; if (zip_seek64file(nullptr, s->filestream,s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (err==UNZ_OK) { if (unz64local_getLong(nullptr, s->filestream,&uMagic) != UNZ_OK) err=UNZ_ERRNO; else if (uMagic!=0x04034b50) err=UNZ_BADZIPFILE; } if (unz64local_getShort(nullptr, s->filestream,&uData) != UNZ_OK) err=UNZ_ERRNO; /* else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) err=UNZ_BADZIPFILE; */ if (unz64local_getShort(nullptr, s->filestream,&uFlags) != UNZ_OK) err=UNZ_ERRNO; if (unz64local_getShort(nullptr, s->filestream,&uData) != UNZ_OK) err=UNZ_ERRNO; else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) err=UNZ_BADZIPFILE; if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && /* #ifdef HAVE_BZIP2 */ (s->cur_file_info.compression_method!=Z_BZIP2ED) && /* #endif */ (s->cur_file_info.compression_method!=Z_DEFLATED)) err=UNZ_BADZIPFILE; if (unz64local_getLong(nullptr, s->filestream,&uData) != UNZ_OK) /* date/time */ err=UNZ_ERRNO; if (unz64local_getLong(nullptr, s->filestream,&uData) != UNZ_OK) /* crc */ err=UNZ_ERRNO; else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; if (unz64local_getLong(nullptr, s->filestream,&uData) != UNZ_OK) /* size compr */ err=UNZ_ERRNO; else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; if (unz64local_getLong(nullptr, s->filestream,&uData) != UNZ_OK) /* size uncompr */ err=UNZ_ERRNO; else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) err=UNZ_BADZIPFILE; if (unz64local_getShort(nullptr, s->filestream,&size_filename) != UNZ_OK) err=UNZ_ERRNO; else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) err=UNZ_BADZIPFILE; *piSizeVar += (uInt)size_filename; if (unz64local_getShort(nullptr, s->filestream,&size_extra_field) != UNZ_OK) err=UNZ_ERRNO; *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + size_filename; *psize_local_extrafield = (uInt)size_extra_field; *piSizeVar += (uInt)size_extra_field; return err; } /* Open for reading data the current file in the zipfile. If there is no error and the file is opened, the return value is UNZ_OK. */ int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, int* level, int raw, const char* password) { int err=UNZ_OK; uInt iSizeVar; unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ uInt size_local_extrafield; /* size of the local extra field */ # ifndef NOUNCRYPT char source[12]; # else if (password != NULL) return UNZ_PARAMERROR; # endif if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; if (!s->current_file_ok) return UNZ_PARAMERROR; if (s->pfile_in_zip_read != NULL) unzCloseCurrentFile(file); if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) return UNZ_BADZIPFILE; pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); if (pfile_in_zip_read_info==NULL) return UNZ_INTERNALERROR; pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; pfile_in_zip_read_info->pos_local_extrafield=0; pfile_in_zip_read_info->raw=raw; if (pfile_in_zip_read_info->read_buffer==NULL) { TRYFREE(pfile_in_zip_read_info); return UNZ_INTERNALERROR; } pfile_in_zip_read_info->stream_initialised=0; if (method!=NULL) *method = (int)s->cur_file_info.compression_method; if (level!=NULL) { *level = 6; switch (s->cur_file_info.flag & 0x06) { case 6 : *level = 1; break; case 4 : *level = 2; break; case 2 : *level = 9; break; } } if ((s->cur_file_info.compression_method!=0) && /* #ifdef HAVE_BZIP2 */ (s->cur_file_info.compression_method!=Z_BZIP2ED) && /* #endif */ (s->cur_file_info.compression_method!=Z_DEFLATED)) { //err=UNZ_BADZIPFILE; } pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; pfile_in_zip_read_info->crc32=0; pfile_in_zip_read_info->total_out_64=0; pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; pfile_in_zip_read_info->filestream=s->filestream; //pfile_in_zip_read_info->z_filefunc=s->z_filefunc; pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; pfile_in_zip_read_info->stream.total_out = 0; if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) { #ifdef HAVE_BZIP2 pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; pfile_in_zip_read_info->bstream.bzfree = (free_func)0; pfile_in_zip_read_info->bstream.opaque = (voidpf)0; pfile_in_zip_read_info->bstream.state = (voidpf)0; pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; pfile_in_zip_read_info->stream.zfree = (free_func)0; pfile_in_zip_read_info->stream.opaque = (voidpf)0; pfile_in_zip_read_info->stream.next_in = (voidpf)0; pfile_in_zip_read_info->stream.avail_in = 0; err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); if (err == Z_OK) pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; else { TRYFREE(pfile_in_zip_read_info); return err; } #else pfile_in_zip_read_info->raw=1; #endif } else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) { pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; pfile_in_zip_read_info->stream.zfree = (free_func)0; pfile_in_zip_read_info->stream.opaque = (voidpf)0; pfile_in_zip_read_info->stream.next_in = 0; pfile_in_zip_read_info->stream.avail_in = 0; err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); if (err == Z_OK) pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; else { TRYFREE(pfile_in_zip_read_info); return err; } /* windowBits is passed < 0 to tell that there is no zlib header. * Note that in this case inflate *requires* an extra "dummy" byte * after the compressed stream in order to complete decompression and * return Z_STREAM_END. * In unzip, i don't wait absolutely Z_STREAM_END because I known the * size of both compressed and uncompressed data */ } pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size ; pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size ; pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar; pfile_in_zip_read_info->stream.avail_in = (uInt)0; s->pfile_in_zip_read = pfile_in_zip_read_info; s->encrypted = 0; # ifndef NOUNCRYPT if (password != NULL) { int i; s->pcrc_32_tab = get_crc_table(); init_keys(password,s->keys,s->pcrc_32_tab); if (zip_seek64file(s->z_filefunc, s->filestream, s->pfile_in_zip_read->pos_in_zipfile + s->pfile_in_zip_read->byte_before_the_zipfile, SEEK_SET)!=0) return UNZ_INTERNALERROR; if(zip_readfile(s->z_filefunc, s->filestream,source, 12)<12) return UNZ_INTERNALERROR; for (i = 0; i<12; i++) zdecode(s->keys,s->pcrc_32_tab,source[i]); s->pfile_in_zip_read->pos_in_zipfile+=12; s->encrypted=1; } # endif return UNZ_OK; } int ZEXPORT unzOpenCurrentFile (unzFile file) { return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); } /** Addition for GDAL : START */ ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; s=(unz64_s*)file; if (file==NULL) return 0; //UNZ_PARAMERROR; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return 0; //UNZ_PARAMERROR; return pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile; } /** Addition for GDAL : END */ /* Read bytes from the current file. buf contain buffer where data must be copied len the size of buf. return the number of byte copied if some bytes are copied return 0 if the end of file was reached return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) { int err=UNZ_OK; uInt iRead = 0; unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; if (pfile_in_zip_read_info->read_buffer == NULL) return UNZ_END_OF_LIST_OF_FILE; if (len==0) return 0; pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; pfile_in_zip_read_info->stream.avail_out = (uInt)len; if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && (!(pfile_in_zip_read_info->raw))) pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_uncompressed; if ((len>pfile_in_zip_read_info->rest_read_compressed+ pfile_in_zip_read_info->stream.avail_in) && (pfile_in_zip_read_info->raw)) pfile_in_zip_read_info->stream.avail_out = (uInt)pfile_in_zip_read_info->rest_read_compressed+ pfile_in_zip_read_info->stream.avail_in; while (pfile_in_zip_read_info->stream.avail_out>0) { if ((pfile_in_zip_read_info->stream.avail_in==0) && (pfile_in_zip_read_info->rest_read_compressed>0)) { uInt uReadThis = UNZ_BUFSIZE; if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; if (uReadThis == 0) return UNZ_EOF; if (zip_seek64file(nullptr, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->pos_in_zipfile + pfile_in_zip_read_info->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (zip_readfile(nullptr, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->read_buffer, uReadThis)!=uReadThis) return UNZ_ERRNO; # ifndef NOUNCRYPT if(s->encrypted) { uInt i; for(i=0;iread_buffer[i] = zdecode(s->keys,s->pcrc_32_tab, pfile_in_zip_read_info->read_buffer[i]); } # endif pfile_in_zip_read_info->pos_in_zipfile += uReadThis; pfile_in_zip_read_info->rest_read_compressed-=uReadThis; pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->read_buffer; pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; } if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) { uInt uDoCopy,i ; if ((pfile_in_zip_read_info->stream.avail_in == 0) && (pfile_in_zip_read_info->rest_read_compressed == 0)) return (iRead==0) ? UNZ_EOF : iRead; if (pfile_in_zip_read_info->stream.avail_out < pfile_in_zip_read_info->stream.avail_in) uDoCopy = pfile_in_zip_read_info->stream.avail_out ; else uDoCopy = pfile_in_zip_read_info->stream.avail_in ; for (i=0;istream.next_out+i) = *(pfile_in_zip_read_info->stream.next_in+i); pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, pfile_in_zip_read_info->stream.next_out, uDoCopy); pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; pfile_in_zip_read_info->stream.avail_in -= uDoCopy; pfile_in_zip_read_info->stream.avail_out -= uDoCopy; pfile_in_zip_read_info->stream.next_out += uDoCopy; pfile_in_zip_read_info->stream.next_in += uDoCopy; pfile_in_zip_read_info->stream.total_out += uDoCopy; iRead += uDoCopy; } else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) { #ifdef HAVE_BZIP2 uLong uTotalOutBefore,uTotalOutAfter; const Bytef *bufBefore; uLong uOutThis; pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; pfile_in_zip_read_info->bstream.total_in_hi32 = 0; pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; pfile_in_zip_read_info->bstream.total_out_hi32 = 0; uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; uOutThis = uTotalOutAfter-uTotalOutBefore; pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; if (err==BZ_STREAM_END) return (iRead==0) ? UNZ_EOF : iRead; if (err!=BZ_OK) break; #endif } // end Z_BZIP2ED else { ZPOS64_T uTotalOutBefore,uTotalOutAfter; const Bytef *bufBefore; ZPOS64_T uOutThis; int flush=Z_SYNC_FLUSH; uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; bufBefore = pfile_in_zip_read_info->stream.next_out; /* if ((pfile_in_zip_read_info->rest_read_uncompressed == pfile_in_zip_read_info->stream.avail_out) && (pfile_in_zip_read_info->rest_read_compressed == 0)) flush = Z_FINISH; */ err=inflate(&pfile_in_zip_read_info->stream,flush); if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) err = Z_DATA_ERROR; uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; uOutThis = uTotalOutAfter-uTotalOutBefore; pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); if (err==Z_STREAM_END) return (iRead==0) ? UNZ_EOF : iRead; if (err!=Z_OK) break; } } if (err==Z_OK) return iRead; return err; } /* Give the current position in uncompressed data */ z_off_t ZEXPORT unztell (unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; return (z_off_t)pfile_in_zip_read_info->stream.total_out; } ZPOS64_T ZEXPORT unztell64 (unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return (ZPOS64_T)-1; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return (ZPOS64_T)-1; return pfile_in_zip_read_info->total_out_64; } /* return 1 if the end of file was reached, 0 elsewhere */ int ZEXPORT unzeof (unzFile file) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; if (pfile_in_zip_read_info->rest_read_uncompressed == 0) return 1; else return 0; } /* Read extra field from the current file (opened by unzOpenCurrentFile) This is the local-header version of the extra field (sometimes, there is more info in the local-header version than in the central-header) if buf==NULL, it return the size of the local extra field that can be read if buf!=NULL, len is the size of the buffer, the extra header is copied in buf. the return value is the number of bytes copied in buf, or (if <0) the error code */ int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) { unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; uInt read_now; ZPOS64_T size_to_read; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; size_to_read = (pfile_in_zip_read_info->size_local_extrafield - pfile_in_zip_read_info->pos_local_extrafield); if (buf==NULL) return (int)size_to_read; if (len>size_to_read) read_now = (uInt)size_to_read; else read_now = (uInt)len ; if (read_now==0) return 0; if (zip_seek64file(nullptr, pfile_in_zip_read_info->filestream, pfile_in_zip_read_info->offset_local_extrafield + pfile_in_zip_read_info->pos_local_extrafield, ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (zip_readfile(nullptr, pfile_in_zip_read_info->filestream, buf,read_now)!=read_now) return UNZ_ERRNO; return (int)read_now; } /* Close the file in zip opened with unzipOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ int ZEXPORT unzCloseCurrentFile (unzFile file) { int err=UNZ_OK; unz64_s* s; file_in_zip64_read_info_s* pfile_in_zip_read_info; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; pfile_in_zip_read_info=s->pfile_in_zip_read; if (pfile_in_zip_read_info==NULL) return UNZ_PARAMERROR; if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && (!pfile_in_zip_read_info->raw)) { if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) err=UNZ_CRCERROR; } TRYFREE(pfile_in_zip_read_info->read_buffer); pfile_in_zip_read_info->read_buffer = NULL; if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) inflateEnd(&pfile_in_zip_read_info->stream); #ifdef HAVE_BZIP2 else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); #endif pfile_in_zip_read_info->stream_initialised = 0; TRYFREE(pfile_in_zip_read_info); s->pfile_in_zip_read=NULL; return err; } /* Get the global comment string of the ZipFile, in the szComment buffer. uSizeBuf is the size of the szComment buffer. return the number of byte copied or an error code <0 */ int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) { unz64_s* s; uLong uReadThis ; if (file==NULL) return (int)UNZ_PARAMERROR; s=(unz64_s*)file; uReadThis = uSizeBuf; if (uReadThis>s->gi.size_comment) uReadThis = s->gi.size_comment; if (zip_seek64file(nullptr,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) return UNZ_ERRNO; if (uReadThis>0) { *szComment='\0'; if (zip_readfile(nullptr, s->filestream, szComment, uReadThis) != uReadThis) return UNZ_ERRNO; } if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) *(szComment+s->gi.size_comment)='\0'; return (int)uReadThis; } /* Additions by RX '2004 */ ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) { unz64_s* s; if (file==NULL) return 0; //UNZ_PARAMERROR; s=(unz64_s*)file; if (!s->current_file_ok) return 0; if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) if (s->num_file==s->gi.number_entry) return 0; return s->pos_in_central_dir; } uLong ZEXPORT unzGetOffset (unzFile file) { ZPOS64_T offset64; if (file==NULL) return 0; //UNZ_PARAMERROR; offset64 = unzGetOffset64(file); return (uLong)offset64; } int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) { unz64_s* s; int err; if (file==NULL) return UNZ_PARAMERROR; s=(unz64_s*)file; s->pos_in_central_dir = pos; s->num_file = s->gi.number_entry; /* hack */ err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, &s->cur_file_info_internal, NULL,0,NULL,0,NULL,0); s->current_file_ok = (err == UNZ_OK); return err; } int ZEXPORT unzSetOffset (unzFile file, uLong pos) { return unzSetOffset64(file,pos); } class ZipArchive : public tTVPArchive { unzFile uf; typedef std::pair FileEntry; std::vector filelist; public: ~ZipArchive(); ZipArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName); bool isValid() { return uf != nullptr; } virtual tjs_uint GetCount() { return filelist.size(); } virtual ttstr GetName(tjs_uint idx) { return filelist[idx].first; } virtual tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx); tTJSBinaryStream *_st = nullptr; }; static uLong zip_readfile(voidpf, voidpf s, void *buf, uLong size) { return ((ZipArchive*)s)->_st->Read(buf, size); } static uLong zip_writefile(voidpf, voidpf s, const void *buf, uLong size) { return ((ZipArchive*)s)->_st->Write(buf, size); } static ZPOS64_T zip_tell64file(voidpf, voidpf s) { return ((ZipArchive*)s)->_st->GetPosition(); } static long zip_seek64file(voidpf, voidpf s, ZPOS64_T offset, int origin) { ((ZipArchive*)s)->_st->Seek(offset, origin); return 0; } tTVPArchive * TVPOpenZIPArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) { tjs_uint64 pos = st->GetPosition(); bool checkZIP = st->ReadI16LE() == 0x4B50; // 'PK' st->SetPosition(pos); if (!checkZIP) return nullptr; ZipArchive *arc = new ZipArchive(name, st, normalizeFileName); if (!arc->isValid()) { arc->_st = nullptr; delete arc; return nullptr; } return arc; } tTJSBinaryStream * ZipArchive::CreateStreamByIndex(tjs_uint idx) { if (unzGoToFilePos64(uf, &filelist[idx].second) != UNZ_OK) return nullptr; // decompress and hold in memory for random access unz_file_info file_info; if (unzGetCurrentFileInfo(uf, &file_info, NULL, 0, NULL, 0) != UNZ_OK) return nullptr; if (file_info.compression_method == 0) { // uncompressed uInt iSizeVar; ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ uInt size_local_extrafield; /* size of the local extra field */ if (unz64local_CheckCurrentFileCoherencyHeader((unz64_s*)uf, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK) return nullptr; return new TArchiveStream(this, file_info.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar, file_info.uncompressed_size); } else { if (unzOpenCurrentFile(uf) != UNZ_OK) return nullptr; tTVPMemoryStream *mem = new tTVPMemoryStream(); mem->SetSize(file_info.uncompressed_size); unzReadCurrentFile(uf, mem->GetInternalBuffer(), file_info.uncompressed_size); unzCloseCurrentFile(uf); return mem; } } ZipArchive::~ZipArchive() { if (uf) { unzClose(uf); uf = NULL; } if (_st) { delete _st; _st = nullptr; } } void storeFilename(ttstr &name, const char *narrowName, const ttstr &filename); ZipArchive::ZipArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) : tTVPArchive(name) { if (!st) st = TVPCreateStream(name); _st = st; if ((uf = unzOpenInternal(this, &zipfunc, 1)) != NULL) { //unzGoToFirstFile64(uf, NULL, NULL, 0); unz_file_info file_info; do { unz64_file_pos entry; if (unzGetFilePos64(uf, &entry) == UNZ_OK) { ttstr filename; char filename_inzip[1024]; if (unzGetCurrentFileInfo(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0) == UNZ_OK) { storeFilename(filename, filename_inzip, name); if (normalizeFileName) NormalizeInArchiveStorageName(filename); filelist.emplace_back(filename, entry); } } } while (unzGoToNextFile64(uf, NULL, NULL, 0) == UNZ_OK); if (normalizeFileName) { std::sort(filelist.begin(), filelist.end(), [](const FileEntry& a, const FileEntry& b) { return a.first < b.first; }); } } } ================================================ FILE: src/core/base/common.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000-2007 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // TVP2 common header file //--------------------------------------------------------------------------- #ifndef __CommonH__ #define __CommonH__ #include "tjsConfig.h" #include "config.h" #include using namespace TJS; typedef std::basic_string stdstring; typedef std::basic_string stdnstring; #endif ================================================ FILE: src/core/base/tar.h ================================================ #ifndef __TAR_H #define __TAR_H /* * tar header block definition * * From IEEE Std 1003.1-1988, pp.156 */ //POSIX magic #define TMAGIC "ustar" #define TMAGLEN 6 //GNU magic+version: #define TOMAGIC "ustar " #define TOMAGLEN 8 //POSIX version #define TVERSION "00" #define TVERSLEN 2 #define REGTYPE '0' /* Regular file */ #define AREGTYPE '\0' /* Regular file; old V7 format */ #define LNKTYPE '1' /* Link */ #define SYMTYPE '2' /* Symbolic link */ #define CHRTYPE '3' /* Character special */ #define BLKTYPE '4' /* Block special */ #define DIRTYPE '5' /* Directory */ #define FIFOTYPE '6' /* FIFO special */ #define CONTTYPE '7' /* Continguous file */ #define LONGLINK 'L' /* Long name Link by tantan*/ #define PAX_ENTRTY 'x' /* PAX header block for file entry : added by claybird 2011.11.29 */ #define PAX_GLOBAL 'g' /* PAX global extended header : added by claybird 2011.11.29 */ #define MULTYPE 'M' /* Added by GNUtar, not POSIX */ #define VOLTYPE 'V' /* Added by GNUtar, not POSIX */ #define TSUID 04000 /* Set UID on execution */ #define TSGID 02000 /* Set GID on execution */ #define TSVTX 01000 /* Reserved */ /* File permissions */ #define TUREAD 00400 /* read by owner */ #define TUWRITE 00200 /* write by owner */ #define TUEXEC 00100 /* execute/search by owner */ #define TGREAD 00040 /* read by group */ #define TGWRITE 00020 /* write by group */ #define TGEXEC 00010 /* execute/search by group */ #define TOREAD 00004 /* read by other */ #define TOWRITE 00002 /* write by other */ #define TOEXEC 00001 /* execute/search by other */ #define TBLOCK 512 #define NAMSIZ 100 //added by claybird(2009.12.05) #define TAR_FORMAT_GNU 0 #define TAR_FORMAT_POSIX 1 typedef union hblock { char dummy[TBLOCK]; struct { char name[NAMSIZ]; char mode[8]; char uid[8]; char gid[8]; char size[12]; char mtime[12]; char chksum[8]; char typeflag; char linkname[NAMSIZ]; char magic[6]; char version[2]; char uname[32]; char gname[32]; char devmajor[8]; char devminor[8]; union _exthead{ //header extension struct _POSIX{ //POSIX ustar format char prefix[155]; char pad[12]; }posix; struct _GNU{ //GNUtar format /* Following fields were added by GNUtar */ char atime[12]; char ctime[12]; char offset[12]; }gnu; }exthead; } dbuf; unsigned int compsum(){ unsigned int sum = 0; int i; for(i=0;i and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Script Event Handling and Dispatching //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include "EventImpl.h" #include "SystemControl.h" #include "ThreadIntf.h" #include "TickCount.h" #include "TimerIntf.h" #include "SysInitIntf.h" #include "DebugIntf.h" #include "WindowImpl.h" //#include #include "Application.h" #include "NativeEventQueue.h" #include "UserEvent.h" //--------------------------------------------------------------------------- // TVPInvokeEvents //--------------------------------------------------------------------------- bool TVPEventInvoked = false; void TVPInvokeEvents() { if(TVPEventInvoked) return; TVPEventInvoked = true; if(TVPSystemControl) { TVPSystemControl->InvokeEvents(); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPEventReceived //--------------------------------------------------------------------------- void TVPEventReceived() { TVPEventInvoked = false; if( TVPSystemControl ) TVPSystemControl->NotifyEventDelivered(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCallDeliverAllEventsOnIdle //--------------------------------------------------------------------------- void TVPCallDeliverAllEventsOnIdle() { if(TVPSystemControl) { TVPSystemControl->CallDeliverAllEventsOnIdle(); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPBreathe //--------------------------------------------------------------------------- static bool TVPBreathing = false; void TVPBreathe() { TVPEventDisabled = true; // not to call TVP events... TVPBreathing = true; try { Application->ProcessMessages(); // do Windows message pumping } catch(...) { TVPBreathing = false; TVPEventDisabled = false; throw; } TVPBreathing = false; TVPEventDisabled = false; } //--------------------------------------------------------------------------- bool TVPGetBreathing() { // return whether now is in event breathing return TVPBreathing; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPSystemEventDisabledState //--------------------------------------------------------------------------- void TVPSetSystemEventDisabledState(bool en) { TVPSystemControl->SetEventEnabled( !en ); if(!en) TVPDeliverAllEvents(); } //--------------------------------------------------------------------------- bool TVPGetSystemEventDisabledState() { return !TVPSystemControl->GetEventEnabled(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPContinuousHandlerCallLimitThread //--------------------------------------------------------------------------- class tTVPContinuousHandlerCallLimitThread : public tTVPThread { tjs_uint64 NextEventTick; tjs_uint64 Interval; tTVPThreadEvent Event; tTJSCriticalSection CS; bool Enabled; NativeEventQueue EventQueue; public: tTVPContinuousHandlerCallLimitThread(); ~tTVPContinuousHandlerCallLimitThread(); protected: void Execute(); void WndProc(NativeEvent& ev) { EventQueue.HandlerDefault(ev); } public: void SetEnabled(bool enabled); void SetInterval(tjs_uint64 interval) { Interval = interval; } } static * TVPContinuousHandlerCallLimitThread = NULL; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- tTVPContinuousHandlerCallLimitThread::tTVPContinuousHandlerCallLimitThread() : tTVPThread(true), EventQueue(this,&tTVPContinuousHandlerCallLimitThread::WndProc) { NextEventTick = 0; Interval = (1<> TVP_SUBMILLI_FRAC_BITS) + ((sleeptime_64 & ((1<BeginContinuousEvent(); } else { // has limit if(!TVPContinuousHandlerCallLimitThread) TVPContinuousHandlerCallLimitThread = new tTVPContinuousHandlerCallLimitThread(); TVPContinuousHandlerCallLimitThread->SetInterval( (1<SetEnabled(true); } } // TVPEnsureVSyncTimingThread(); // if we wait vsync, the continuous handler will be executed at the every timing of // vsync. } //--------------------------------------------------------------------------- void TVPEndContinuousEvent() { // anyway if(TVPContinuousHandlerCallLimitThread) TVPContinuousHandlerCallLimitThread->SetEnabled(false); // anyway if(TVPSystemControl) TVPSystemControl->EndContinuousEvent(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- static void TVPReleaseContinuousHandlerCallLimitThread() { if(TVPContinuousHandlerCallLimitThread) delete TVPContinuousHandlerCallLimitThread, TVPContinuousHandlerCallLimitThread = NULL; } // to release TVPContinuousHandlerCallLimitThread at exit static tTVPAtExit TVPTimerThreadUninitAtExit(TVP_ATEXIT_PRI_SHUTDOWN, TVPReleaseContinuousHandlerCallLimitThread); //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/win32/EventImpl.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Script Event Handling and Dispatching //--------------------------------------------------------------------------- #ifndef EventImplH #define EventImplH #include "EventIntf.h" //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/win32/FileSelector.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // File Selector dialog box //--------------------------------------------------------------------------- #include "tjsCommHead.h" // #include // #include #include "MsgIntf.h" #include "StorageImpl.h" #include "WindowImpl.h" #include "SysInitIntf.h" #include "DebugIntf.h" #include "TVPScreen.h" std::string TVPShowFileSelector( const std::string &title, const std::string &filename, std::string initdir, bool issave ); //--------------------------------------------------------------------------- // TVPSelectFile related //--------------------------------------------------------------------------- #define TVP_OLD_OFN_STRUCT_SIZE 76 //--------------------------------------------------------------------------- #if 0 static tjs_int TVPLastScreenWidth = 0; static tjs_int TVPLastScreenHeight = 0; static tjs_int TVPLastOFNLeft = -30000; static tjs_int TVPLastOFNTop = -30000; static UINT_PTR APIENTRY TVPOFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) { if(uiMsg == WM_INITDIALOG) { int left, top; HWND parent = GetParent(hdlg); if((TVPLastOFNLeft == -30000 && TVPLastOFNTop == -30000) || TVPLastScreenWidth != tTVPScreen::GetWidth() || TVPLastScreenHeight != tTVPScreen::GetHeight() ) { // center the window RECT rect; GetWindowRect(parent, &rect); left = ((tTVPScreen::GetWidth() - rect.right + rect.left) / 2); top = ((tTVPScreen::GetHeight() - rect.bottom + rect.top) / 3); } else { // set last position left = TVPLastOFNLeft; top = TVPLastOFNTop; } TVPLastScreenWidth = tTVPScreen::GetWidth(); TVPLastScreenHeight = tTVPScreen::GetHeight(); SetWindowPos(parent, 0, left, top, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); } else if(uiMsg == WM_DESTROY || (uiMsg == WM_NOTIFY && ((OFNOTIFY*)lParam)->hdr.code == CDN_FILEOK)) { HWND parent = GetParent(hdlg); RECT rect; GetWindowRect(parent, &rect); TVPLastOFNLeft = rect.left; TVPLastOFNTop = rect.top; } return 0; } //--------------------------------------------------------------------------- static void TVPPushFilterPair(std::vector &filters, std::wstring filter) { std::wstring::size_type vpos = filter.find_first_of(L"|"); if( vpos != std::wstring::npos ) { std::wstring name = filter.substr(0, vpos); std::wstring wild = filter.c_str() + vpos+1; filters.push_back(name); filters.push_back(wild); } else { filters.push_back(filter); filters.push_back(filter); } } #endif //--------------------------------------------------------------------------- bool TVPSelectFile(iTJSDispatch2 *params) { // show open dialog box // NOTE: currently this only shows ANSI version of file open dialog. tTJSVariant val; std::string initialdir; std::string title; std::string defaultext; #if 0 wchar_t* filter = NULL; wchar_t* filename = NULL; BOOL result; try { // prepare OPENFILENAME structure OPENFILENAME ofn; memset(&ofn, 0, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = TVPGetModalWindowOwnerHandle(); if( ofn.hwndOwner == INVALID_HANDLE_VALUE ) { ofn.hwndOwner = NULL; } ofn.hInstance = NULL; // set application window position to current window position // get filter ofn.lpstrFilter = NULL; if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("filter"), 0, &val, params))) { std::vector filterlist; if(val.Type() != tvtObject) { TVPPushFilterPair(filterlist, ttstr(val).AsStdString()); } else { iTJSDispatch2 * array = val.AsObjectNoAddRef(); tjs_int count; tTJSVariant tmp; if(TJS_SUCCEEDED(array->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("count"), 0, &tmp, array))) count = tmp; else count = 0; for(tjs_int i = 0; i < count; i++) { if(TJS_SUCCEEDED(array->PropGetByNum(TJS_MEMBERMUSTEXIST, i, &tmp, array))) { TVPPushFilterPair(filterlist, ttstr(tmp).AsStdString()); } } } // create filter buffer tjs_int bufsize = 2; for(std::vector::iterator i = filterlist.begin(); i != filterlist.end(); i++) { bufsize += (tjs_int)(i->length() + 1); } filter = new wchar_t[bufsize]; wchar_t* p = filter; for(std::vector::iterator i = filterlist.begin(); i != filterlist.end(); i++) { TJS_strcpy(p, i->c_str()); p += i->length() + 1; } *(p++) = 0; *(p++) = 0; ofn.lpstrFilter = filter; } ofn.lpstrCustomFilter = NULL; ofn.nMaxCustFilter = 0; if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("filterIndex"), 0, &val, params))) ofn.nFilterIndex = (tjs_int)val; else ofn.nFilterIndex = 0; // filenames filename = new wchar_t[MAX_PATH + 1]; filename[0] = 0; if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("name"), 0, &val, params))) { ttstr lname(val); if(!lname.IsEmpty()) { lname = TVPNormalizeStorageName(lname); TVPGetLocalName(lname); std::wstring name = lname.AsStdString(); TJS_strncpy(filename, name.c_str(), MAX_PATH); filename[MAX_PATH] = 0; } } ofn.lpstrFile = filename; ofn.nMaxFile = MAX_PATH + 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; // initial dir ofn.lpstrInitialDir = NULL; if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("initialDir"), 0, &val, params))) { ttstr lname(val); if(!lname.IsEmpty()) { lname = TVPNormalizeStorageName(lname); TVPGetLocalName(lname); initialdir = lname.AsStdString(); ofn.lpstrInitialDir = initialdir.c_str(); } } // title if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("title"), 0, &val, params))) { title = ttstr(val).AsStdString(); ofn.lpstrTitle = title.c_str(); } else { ofn.lpstrTitle = NULL; } // flags bool issave = false; if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("save"), 0, &val, params))) issave = val.operator bool(); ofn.Flags = OFN_ENABLEHOOK|OFN_EXPLORER|OFN_NOCHANGEDIR| OFN_PATHMUSTEXIST|OFN_HIDEREADONLY|OFN_ENABLESIZING; if(!issave) ofn.Flags |= OFN_FILEMUSTEXIST; else ofn.Flags |= OFN_OVERWRITEPROMPT; // default extension if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("defaultExt"), 0, &val, params))) { defaultext = ttstr(val).AsStdString(); ofn.lpstrDefExt = defaultext.c_str(); } else { ofn.lpstrDefExt = NULL; } // hook proc ofn.lpfnHook = TVPOFNHookProc; // show dialog box if(!issave) result = GetOpenFileName(&ofn); else result = GetSaveFileName(&ofn); if(!result && CommDlgExtendedError() == CDERR_STRUCTSIZE) { // for old windows // set lStructSize to old Windows' structure size ofn.lStructSize = TVP_OLD_OFN_STRUCT_SIZE; if(!issave) result = GetOpenFileName(&ofn); else result = GetSaveFileName(&ofn); } if(result) { // returns some informations // filter index val = (tjs_int)ofn.nFilterIndex; params->PropSet(TJS_MEMBERENSURE, TJS_W("filterIndex"), 0, &val, params); // file name val = TVPNormalizeStorageName(ttstr(filename)); params->PropSet(TJS_MEMBERENSURE, TJS_W("name"), 0, &val, params); } } catch(...) { if(filter) delete [] filter; if(filename) delete [] filename; throw; } delete [] filter; delete [] filename; return 0!=result; #endif std::string filename; std::string result; // get filter if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("filter"), 0, &val, params))) { } // if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("filterIndex"), 0, // &val, params))) // ofn.nFilterIndex = (tjs_int)val; // else // ofn.nFilterIndex = 0; // initial dir if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("initialDir"), 0, &val, params))) { ttstr lname(val); if (!lname.IsEmpty()){ TVPGetLocalName(lname); initialdir = tTJSNarrowStringHolder(lname.c_str()); } } // default extension if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("defaultExt"), 0, &val, params))) { defaultext = tTJSNarrowStringHolder(val.AsStringNoAddRef()->operator const tjs_char*()); } // filenames if (TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("name"), 0, &val, params))) { ttstr lname(val); if (!lname.IsEmpty()) { if (lname.IndexOf('/') >= 0) { lname = TVPNormalizeStorageName(lname); TVPGetLocalName(lname); ttstr path = TVPExtractStoragePath(lname); ttstr name = TVPExtractStorageName(lname); lname = name; initialdir = path.AsStdString(); } else { } if (!defaultext.empty() && TVPExtractStorageExt(lname).IsEmpty()) { if (defaultext[0] != '.') lname += TJS_W("."); lname += defaultext.c_str(); } filename = tTJSNarrowStringHolder(lname.c_str()); } } // title if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("title"), 0, &val, params))) { title = tTJSNarrowStringHolder(val.AsStringNoAddRef()->operator const tjs_char*()); } // flags bool issave = false; if(TJS_SUCCEEDED(params->PropGet(TJS_MEMBERMUSTEXIST, TJS_W("save"), 0, &val, params))) issave = val.operator bool(); // show dialog box result = TVPShowFileSelector(title, filename, initialdir, issave); if(!result.empty()) { // returns some informations // filter index val = (tjs_int)0; params->PropSet(TJS_MEMBERENSURE, TJS_W("filterIndex"), 0, &val, params); // file name ttstr tresult = TVPNormalizeStorageName(ttstr(result.c_str())); val = tresult; params->PropSet(TJS_MEMBERENSURE, TJS_W("name"), 0, &val, params); return true; } return false; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/win32/FileSelector.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // File Selector dialog box //--------------------------------------------------------------------------- #ifndef FileSelectorH #define FileSelectorH //--------------------------------------------------------------------------- #include "tjs.h" extern bool TVPSelectFile(iTJSDispatch2 *params); #endif ================================================ FILE: src/core/base/win32/FuncStubs.cpp ================================================ /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000-2009 W.Dee and contributors See details of license at "license.txt" */ /* This file is always generated by makestub.pl . */ /* Modification by hand will be lost. */ #include "tjsCommHead.h" #include "tjsVariant.h" #include "tjsString.h" #include "PluginImpl.h" static void __stdcall TVP_Stub_3d4b725f0b4234d79524822e7c34486b(tTJSVariant * _this, iTJSDispatch2 * objthis) { return _this->ChangeClosureObjThis(objthis); } static void __stdcall TVP_Stub_3fc0c32ee41ea0c515f8fbb681e37982(tTJSVariant * _this) { ::new (_this) tTJSVariant(); } static void __stdcall TVP_Stub_e8dbd4fe012262d9da831e0735aa33b3(tTJSVariant * _this, const tTJSVariant & ref) { ::new (_this) tTJSVariant(ref); } static void __stdcall TVP_Stub_ace6cce1353865d7376caca1f2124216(tTJSVariant * _this, iTJSDispatch2 * ref) { ::new (_this) tTJSVariant(ref); } static void __stdcall TVP_Stub_5055344aa8055bc238b79e5f88fc3300(tTJSVariant * _this, iTJSDispatch2 * obj , iTJSDispatch2 * objthis) { ::new (_this) tTJSVariant(obj, objthis); } static void __stdcall TVP_Stub_8238c542b814acf1a83c00cced57ba26(tTJSVariant * _this, const tjs_char * ref) { ::new (_this) tTJSVariant(ref); } static void __stdcall TVP_Stub_bd2a14ca8c345fd7f151b08d1792fb60(tTJSVariant * _this, const tTJSString & ref) { ::new (_this) tTJSVariant(ref); } static void __stdcall TVP_Stub_16d432f9f86738a7688cbfc9b12441ec(tTJSVariant * _this, const tjs_nchar * ref) { ::new (_this) tTJSVariant(ref); } static void __stdcall TVP_Stub_6dac00582b8ba529e548ef058c4e869e(tTJSVariant * _this, const tjs_uint8 * ref , tjs_uint len) { ::new (_this) tTJSVariant(ref, len); } static void __stdcall TVP_Stub_9193ae470b5efdfe617b5e94cd8f5da6(tTJSVariant * _this, bool ref) { ::new (_this) tTJSVariant(ref); } static void __stdcall TVP_Stub_ec455b6ef0f5da178063db3875973260(tTJSVariant * _this, tjs_int32 ref) { ::new (_this) tTJSVariant(ref); } static void __stdcall TVP_Stub_a56aaf685bd171b63b0ef3c894d80ecf(tTJSVariant * _this, tjs_int64 ref) { ::new (_this) tTJSVariant(ref); } static void __stdcall TVP_Stub_9a5fe199cebb9841f94ac0bb7a4a3b6a(tTJSVariant * _this, tjs_real ref) { ::new (_this) tTJSVariant(ref); } static void __stdcall TVP_Stub_2acb76a1f86e34afc5fe934d406c6c4c(tTJSVariant * _this, const tjs_uint8 * * src) { ::new (_this) tTJSVariant(src); } static void __stdcall TVP_Stub_3a4d914ca7d24989c236ad223c002d49(tTJSVariant * _this) { _this->~tTJSVariant(); } static tTJSVariantType __stdcall TVP_Stub_8fca7d3a123df1eacf228ba89f6a02ff(tTJSVariant * _this) { return _this->Type(); } static void __stdcall TVP_Stub_58be195f96a36c158d638e3b0c79308b(tTJSVariant * _this) { return _this->Clear(); } static tTJSVariantClosure & __stdcall TVP_Stub_eaa4d5b1d186a807a63311ab6d5e16e4(tTJSVariant * _this) { return _this->AsObjectClosure(); } static void __stdcall TVP_Stub_246f30d208c1d3a4e2b558090f403734(tTJSVariant * _this) { return _this->ToObject(); } static iTJSDispatch2 * __stdcall TVP_Stub_3206ef9b7a8013d6572decdea49e7e2e(tTJSVariant * _this) { return _this->operator iTJSDispatch2 *(); } static void __stdcall TVP_Stub_c5a30d297c3a121879b1392bc6c604ef(tTJSVariant * _this) { return _this->ToString(); } static tjs_uint32 * __stdcall TVP_Stub_e398f5aef0ab92bc1323f3b094722fb1(tTJSVariant * _this) { return _this->GetHint(); } static void __stdcall TVP_Stub_0733b0ac80880897d327dc6f3b04ea9e(tTJSVariant * _this) { return _this->ToOctet(); } static void __stdcall TVP_Stub_4cb055ed9d8ef71d1af10898965c940c(tTJSVariant * _this) { return _this->ToInteger(); } static void __stdcall TVP_Stub_ef8d198596b7d3143d02ed4450ccefa1(tTJSVariant * _this) { return _this->ToReal(); } static tTJSVariant & __stdcall TVP_Stub_d48ea419e040ffe8c20c1e86d80c9a5f(tTJSVariant * _this, const tTJSVariant & ref) { return _this->operator =(ref); } static void __stdcall TVP_Stub_679b215ff76a269871d5f325b981e561(tTJSVariant * _this, const tTJSVariant & ref) { return _this->CopyRef(ref); } static tTJSVariant & __stdcall TVP_Stub_1039eff4a4443f9238438485a35a93a7(tTJSVariant * _this, iTJSDispatch2 * ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_2f873b0ee1c6591ba28bc4b9c0e4c954(tTJSVariant * _this, iTJSDispatch2 * ref) { return _this->SetObject(ref); } static tTJSVariant & __stdcall TVP_Stub_a583ffb56cdb2ede691e15053a8a165a(tTJSVariant * _this, iTJSDispatch2 * object , iTJSDispatch2 * objthis) { return _this->SetObject(object, objthis); } static tTJSVariant & __stdcall TVP_Stub_e09ed277802c1b117e1908421448886d(tTJSVariant * _this, tTJSVariantClosure ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_e76dfb9e00f4a9d491117d815f30db7f(tTJSVariant * _this, tTJSVariantString * ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_b000dd8934508d8ec6d6ef976a6ff49b(tTJSVariant * _this, tTJSVariantOctet * ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_d98ab5c968ebfde4e924901d09190774(tTJSVariant * _this, const tTJSString & ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_661e8c10d5d477e6823a840244937cd8(tTJSVariant * _this, const tjs_char * ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_6b39e70ea89c4f883689f51289029b69(tTJSVariant * _this, const tjs_nchar * ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_4a18b1c0afe37b84e2b35a7fc07c4e0f(tTJSVariant * _this, bool ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_48b85c8774d91ca40b2992f0e452f19e(tTJSVariant * _this, tjs_int32 ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_5ea8db9a9193fe6bab53baf2bee06b6b(tTJSVariant * _this, const tTVInteger ref) { return _this->operator =(ref); } static tTJSVariant & __stdcall TVP_Stub_46b92626ff6894e993c4f193a129540b(tTJSVariant * _this, tjs_real ref) { return _this->operator =(ref); } static void __stdcall TVP_Stub_6efc1d1f66f0e01a81faf767d7576816(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->logicalorequal(rhs); } static void __stdcall TVP_Stub_4ededf58eae77c320b4a6f5f701acafb(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->logicalandequal(rhs); } static void __stdcall TVP_Stub_028d5fda2f4568f6ab14b49d89650a4d(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator |=(rhs); } static void __stdcall TVP_Stub_11912984b8c094d2df26bf3c3677d096(tTJSVariant * _this) { return _this->increment(); } static void __stdcall TVP_Stub_6c0df790c33142e286aea9af6993d931(tTJSVariant * _this) { return _this->decrement(); } static void __stdcall TVP_Stub_c27d85b695cd6e144210785bdfd446ce(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator ^=(rhs); } static void __stdcall TVP_Stub_8422ef7f42009be0ad58a09d64149051(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator &=(rhs); } static void __stdcall TVP_Stub_ee07e6522577952453206ede39cdf54c(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator >>=(rhs); } static void __stdcall TVP_Stub_786a65424247e711f6ca31f0a10603d7(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->rbitshiftequal(rhs); } static void __stdcall TVP_Stub_995a222f2038dd2007f2c1f6429bd19e(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator <<=(rhs); } static void __stdcall TVP_Stub_da8c6e750d6a9c0557a56ef7f7fd8e88(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator %=(rhs); } static void __stdcall TVP_Stub_9cf7b0f119bcf3fa4564837ae25429b3(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator /=(rhs); } static void __stdcall TVP_Stub_17cbcacad2ed350215d7d700c676ea40(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->idivequal(rhs); } static void __stdcall TVP_Stub_2bd375c0598e9148d88579a51b2f07a8(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator *=(rhs); } static void __stdcall TVP_Stub_4d2c157f8b0b49e57c3e9b5abc9deb0f(tTJSVariant * _this) { return _this->logicalnot(); } static void __stdcall TVP_Stub_4b7eaccf64af0f3a4c4fe64f4e2dd3fd(tTJSVariant * _this) { return _this->bitnot(); } static void __stdcall TVP_Stub_3a4d2602c392a8d1f4c38d537a8c95e0(tTJSVariant * _this) { return _this->tonumber(); } static void __stdcall TVP_Stub_8d915d35ef8e857f245c5d46798618e4(tTJSVariant * _this) { return _this->changesign(); } static void __stdcall TVP_Stub_1e463482afa8ca30f5fa7bea4fa5741d(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator -=(rhs); } static void __stdcall TVP_Stub_fdf270e4080c986abd1649fa9fffdeab(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator +=(rhs); } static tTJSVariantType __stdcall TVP_Stub_972e0f9a6ec4648a9fb82bcf5d9095ff(tTJSVariant * _this) { return _this->Type(); } static bool __stdcall TVP_Stub_9d76731c37c4664d654db026644c64b4(tTJSVariant * _this, const tTJSVariant & val2) { return _this->NormalCompare(val2); } static bool __stdcall TVP_Stub_4f1620cb699874b9c8cedf6e321c606e(tTJSVariant * _this, const tTJSVariant & val2) { return _this->DiscernCompare(val2); } static bool __stdcall TVP_Stub_ef1c6b2b601d1b0ff70272a4d447aa3c(tTJSVariant * _this, const tTJSVariant & val2) { return _this->DiscernCompareStrictReal(val2); } static bool __stdcall TVP_Stub_9b7872860c95cfdafb056ab30318e99c(tTJSVariant * _this, const tTJSVariant & val2) { return _this->GreaterThan(val2); } static bool __stdcall TVP_Stub_53360f194a04fc142ddae2b9a3ab4c92(tTJSVariant * _this, const tTJSVariant & val2) { return _this->LittlerThan(val2); } static bool __stdcall TVP_Stub_ce1dcb05e5e7c4cafbc4ed37f63b256e(tTJSVariant * _this, const tjs_char * classname) { return _this->IsInstanceOf(classname); } static iTJSDispatch2 * __stdcall TVP_Stub_841ce4492b37321eea0c1b500de9b352(tTJSVariant * _this) { return _this->AsObject(); } static iTJSDispatch2 * __stdcall TVP_Stub_61785de870894968cd9d95e17e88eafc(tTJSVariant * _this) { return _this->AsObjectNoAddRef(); } static iTJSDispatch2 * __stdcall TVP_Stub_ad3236e727398311c3b8e1ddd5f4b293(tTJSVariant * _this) { return _this->AsObjectThis(); } static iTJSDispatch2 * __stdcall TVP_Stub_80e0b7be488545ff9b8bc52c9ab5fba5(tTJSVariant * _this) { return _this->AsObjectThisNoAddRef(); } static tTJSVariantClosure & __stdcall TVP_Stub_4eaa3e4efb319707db6ef81db1c6f147(tTJSVariant * _this) { return _this->AsObjectClosureNoAddRef(); } static tTJSVariantString * __stdcall TVP_Stub_693a0152f098caee7fc77f545dd3e954(tTJSVariant * _this) { return _this->AsString(); } static tTJSVariantString * __stdcall TVP_Stub_42840710f5fba9bb32b95290b1796a55(tTJSVariant * _this) { return _this->AsStringNoAddRef(); } static const tjs_char * __stdcall TVP_Stub_adec3f9ef429aa9a284081f0fc6a1b5b(tTJSVariant * _this) { return _this->GetString(); } static tTJSVariantOctet * __stdcall TVP_Stub_674a7948152a1d7a49050b9d98796403(tTJSVariant * _this) { return _this->AsOctet(); } static tTJSVariantOctet * __stdcall TVP_Stub_aa6f132b2031c83062f6149c90f2df5f(tTJSVariant * _this) { return _this->AsOctetNoAddRef(); } static tTVInteger __stdcall TVP_Stub_b52f446e22bb92d495f7e65ac71c9bf9(tTJSVariant * _this) { return _this->AsInteger(); } static void __stdcall TVP_Stub_d4899fd4a8beb06f192dcb1d300e3319(tTJSVariant * _this, tTJSVariant & targ) { return _this->AsNumber(targ); } static tTVInteger __stdcall TVP_Stub_d3f5ec78464d29ee6988a1f90c2e3e1b(tTJSVariant * _this) { return _this->operator tTVInteger(); } static bool __stdcall TVP_Stub_a463ad6a757c3f04e09a72e288737d06(tTJSVariant * _this) { return _this->operator bool(); } static tjs_int __stdcall TVP_Stub_27857bb89d35113183b682c3917d6c7a(tTJSVariant * _this) { return _this->operator tjs_int(); } static tTVReal __stdcall TVP_Stub_a5f80951cfb882ac6a3e06c0b9a95807(tTJSVariant * _this) { return _this->AsReal(); } static tTVReal __stdcall TVP_Stub_35aadb63079c8bd84ebc0389bae306e0(tTJSVariant * _this) { return _this->operator tTVReal(); } static tTJSVariant __stdcall TVP_Stub_fb6573df5887c2020ae58136f8342ed4(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator ||(rhs); } static tTJSVariant __stdcall TVP_Stub_86c67d2197c46824ab10f59e568ad13a(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator &&(rhs); } static tTJSVariant __stdcall TVP_Stub_263a0c5b335b2c4d5bc1f55b51b8315e(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator |(rhs); } static tTJSVariant __stdcall TVP_Stub_975c1099e57ab67122ddef0f44fd7dd5(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator ^(rhs); } static tTJSVariant __stdcall TVP_Stub_04493e5237a7ca97afd391cb7e831ba0(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator &(rhs); } static tTJSVariant __stdcall TVP_Stub_9996100acc7705cb2b0c904d6bad4401(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator !=(rhs); } static tTJSVariant __stdcall TVP_Stub_5d91cff3b2a26ff7c0543e0f6d737117(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator ==(rhs); } static tTJSVariant __stdcall TVP_Stub_ef1dedc2cb58dc4e1afc14238b6fc518(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator <(rhs); } static tTJSVariant __stdcall TVP_Stub_f18397fe81c043ba2346e31b359f6a73(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator >(rhs); } static tTJSVariant __stdcall TVP_Stub_2ee45ad60b0c06a8d0feebc3a6aad9e7(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator <=(rhs); } static tTJSVariant __stdcall TVP_Stub_44500491c57e17032951fe6ed268ff1d(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator >=(rhs); } static tTJSVariant __stdcall TVP_Stub_056f5d278c75750df792bf8b081fbf7d(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator >>(rhs); } static tTJSVariant __stdcall TVP_Stub_04233bc4f7d4df92c260d23110320afe(tTJSVariant * _this, tjs_int count) { return _this->rbitshift(count); } static tTJSVariant __stdcall TVP_Stub_cdc475c4419e77c22508e337428c4074(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator <<(rhs); } static tTJSVariant __stdcall TVP_Stub_06bacb2910308a47bbe27ff7efa1226d(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator %(rhs); } static tTJSVariant __stdcall TVP_Stub_521e053199a4aeb4e0f24d9f4a6cc682(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator /(rhs); } static tTJSVariant __stdcall TVP_Stub_02164e6fb4c925843ac774ec1e4c6e5d(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->idiv(rhs); } static tTJSVariant __stdcall TVP_Stub_5110cbbcddbd9688281ee5418e3f9023(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator *(rhs); } static tTJSVariant __stdcall TVP_Stub_1db54b61f00bf931452218c4a39e79ef(tTJSVariant * _this) { return _this->operator !(); } static tTJSVariant __stdcall TVP_Stub_9d0edd8f51f155767301017bd3d256da(tTJSVariant * _this) { return _this->operator ~(); } static tTJSVariant __stdcall TVP_Stub_8f744c5aa8df5471939b960bc759f12b(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator -(rhs); } static tTJSVariant __stdcall TVP_Stub_ba7ff7b0b4192bd2cc7f49c7b688ad57(tTJSVariant * _this) { return _this->operator +(); } static tTJSVariant __stdcall TVP_Stub_7773ac921bb82c85de3be69ef86265fd(tTJSVariant * _this) { return _this->operator -(); } static tTJSVariant __stdcall TVP_Stub_114a781ed71edace31abb352a2671f41(tTJSVariant * _this, const tTJSVariant & rhs) { return _this->operator +(rhs); } static void * __stdcall TVP_Stub_2bc5f4a97decfa82c625430479ec512b(size_t size) { return tTJSVariant::operator new(size); } static void __stdcall TVP_Stub_066fb79f94523d95d12480f23c58cc8e(void * p) { return tTJSVariant::operator delete(p); } static void * __stdcall TVP_Stub_803906b8de16ff825d4e69e1952d872f(size_t size) { return tTJSVariant::operator new [](size); } static void __stdcall TVP_Stub_34cc96a5118ee1e12b0750ea64d40b1f(void * p) { return tTJSVariant::operator delete [](p); } static void * __stdcall TVP_Stub_dbe821fb8b651d42a9c8e730517c408c(size_t size , void * buf) { return tTJSVariant::operator new(size, buf); } static void __stdcall TVP_Stub_8970ba46068ac74746c3e84299937d8f(tTJSVariantOctet * _this, const tjs_uint8 * data , tjs_uint length) { ::new (_this) tTJSVariantOctet(data, length); } static void __stdcall TVP_Stub_438e27dcbb077284213eb4d7dcd43f8f(tTJSVariantOctet * _this, const tjs_uint8 * data1 , tjs_uint len1 , const tjs_uint8 * data2 , tjs_uint len2) { ::new (_this) tTJSVariantOctet(data1, len1, data2, len2); } static void __stdcall TVP_Stub_a98d712ca19a49afe07d0a7c5d064cef(tTJSVariantOctet * _this, const tTJSVariantOctet * o1 , const tTJSVariantOctet * o2) { ::new (_this) tTJSVariantOctet(o1, o2); } static void __stdcall TVP_Stub_08aef69683bcfe2a5c63d4c7866de8e9(tTJSVariantOctet * _this) { _this->~tTJSVariantOctet(); } static void __stdcall TVP_Stub_dbc9bc2e27068c8426b1c6a7f89424e0(tTJSVariantOctet * _this) { return _this->AddRef(); } static void __stdcall TVP_Stub_5eeb98ca016123f57966457533bb639e(tTJSVariantOctet * _this) { return _this->Release(); } static tjs_uint __stdcall TVP_Stub_98fdc846d0b4a83412f3521f65bb98b4(tTJSVariantOctet * _this) { return _this->GetLength(); } static const tjs_uint8 * __stdcall TVP_Stub_3309591d3c7f6f688e81588f169dba21(tTJSVariantOctet * _this) { return _this->GetData(); } static void __stdcall TVP_Stub_d83a866389246d824efcc83303a04484(tTJSString * _this) { ::new (_this) tTJSString(); } static void __stdcall TVP_Stub_6cf6f332a6a14a15e8dce62301f5c840(tTJSString * _this, const tTJSString & rhs) { ::new (_this) tTJSString(rhs); } static void __stdcall TVP_Stub_566eeea3c5f009b0fc6fa123ba30f496(tTJSString * _this, tTJSVariantString * vstr) { ::new (_this) tTJSString(vstr); } static void __stdcall TVP_Stub_88806e38e35c73b36acadd4061a4fe0b(tTJSString * _this, const tjs_char * str) { ::new (_this) tTJSString(str); } static void __stdcall TVP_Stub_3bb69d3886159aaecc333b6ff17287bf(tTJSString * _this, const tjs_nchar * str) { ::new (_this) tTJSString(str); } static void __stdcall TVP_Stub_3e36278551a9c8b29cb2e8017db6af0d(tTJSString * _this, const tTJSStringBufferLength len) { ::new (_this) tTJSString(len); } static void __stdcall TVP_Stub_5de99d84f3dc902cb0812fb85a7d5c88(tTJSString * _this, tjs_char rch) { ::new (_this) tTJSString(rch); } static void __stdcall TVP_Stub_31e85cbc73f8fbd4cea895a751480059(tTJSString * _this, const tTJSVariant & val) { ::new (_this) tTJSString(val); } static void __stdcall TVP_Stub_6ae29e405ede762f1a89a9dd526cb36e(tTJSString * _this, const tTJSString & str , int n) { ::new (_this) tTJSString(str, n); } static void __stdcall TVP_Stub_c95bd66d95c153cdac41b5243e555f5f(tTJSString * _this, const tjs_char * str , int n) { ::new (_this) tTJSString(str, n); } static void __stdcall TVP_Stub_72a67e9c52fd27dbb66eded47efeea74(tTJSString * _this, tjs_int n) { ::new (_this) tTJSString(n); } static void __stdcall TVP_Stub_fb13e41bda53e4e59403e3e14effccd6(tTJSString * _this) { _this->~tTJSString(); } static tTJSString & __stdcall TVP_Stub_9a5c710e620e47f105752453ad5d6ab1(tTJSString * _this, const tTJSString & rhs) { return _this->operator =(rhs); } static tTJSString & __stdcall TVP_Stub_18f1ad16c11429707cbf8ea4d1d4a21e(tTJSString * _this, const tjs_char * rhs) { return _this->operator =(rhs); } static tTJSString & __stdcall TVP_Stub_550f317b573a1256af00586890ae82f1(tTJSString * _this, const tjs_nchar * rhs) { return _this->operator =(rhs); } static void __stdcall TVP_Stub_cd50da721dfb63f36c1ebb1226830428(tTJSString * _this, const tTJSString & ref) { return _this->operator +=(ref); } static void __stdcall TVP_Stub_fbba3dd6a087599d1277ae58f6cec18e(tTJSString * _this, const tTJSVariantString * ref) { return _this->operator +=(ref); } static void __stdcall TVP_Stub_43cc5b5a61a6090af83333d115b5b868(tTJSString * _this, const tjs_char * ref) { return _this->operator +=(ref); } static void __stdcall TVP_Stub_616fb5060d81eb5bab58647596582df4(tTJSString * _this, tjs_char rch) { return _this->operator +=(rch); } static void __stdcall TVP_Stub_168cf4c1b9ef70b98f2e0ab3695a4f3b(tTJSString * _this) { return _this->Clear(); } static tjs_char * __stdcall TVP_Stub_314573cca30a7c2aecc9166fbf5400c9(tTJSString * _this, tjs_uint len) { return _this->AllocBuffer(len); } static tjs_char * __stdcall TVP_Stub_03da356426c038fad663c836c3e330ef(tTJSString * _this, tjs_uint len) { return _this->AppendBuffer(len); } static void __stdcall TVP_Stub_31dbebdedc08d75e34a2cd564ce60586(tTJSString * _this) { return _this->FixLen(); } static void __stdcall TVP_Stub_d9224ad7a0de743a7eea15fdb2c5f934(tTJSString * _this, const tTJSString & from , const tTJSString & to , bool forall = true) { return _this->Replace(from, to, forall); } static void __stdcall TVP_Stub_c01b0720b49ce4f792446d8965d2c31f(tTJSString * _this) { return _this->ToLowerCase(); } static void __stdcall TVP_Stub_4af47e46a11e1357cb994f405289d13e(tTJSString * _this) { return _this->ToUppserCase(); } static tjs_uint32 * __stdcall TVP_Stub_25b6dafa19bfa5bde1a8b519da248f82(tTJSString * _this) { return _this->GetHint(); } static tjs_char * __stdcall TVP_Stub_72425405819c900aec719491cbd90c6d(tTJSString * _this) { return _this->Independ(); } static const tjs_char * __stdcall TVP_Stub_a79942af73f33bff6e432c9fd808e469(tTJSString * _this) { return _this->c_str(); } static tTJSVariantString * __stdcall TVP_Stub_df106470a4141ebc7eda22160859ffdc(tTJSString * _this) { return _this->AsVariantStringNoAddRef(); } static tjs_int64 __stdcall TVP_Stub_469bc225b0ecd9561aae5a46b85ded42(tTJSString * _this) { return _this->AsInteger(); } static bool __stdcall TVP_Stub_a6663c078b3aa79b39ee2d09f3875765(tTJSString * _this, const tTJSString & ref) { return _this->operator ==(ref); } static bool __stdcall TVP_Stub_efbe634ce4f13633e220cae167cf63fb(tTJSString * _this, const tTJSString & ref) { return _this->operator !=(ref); } static tjs_int __stdcall TVP_Stub_57f4147bcc09e4e4442ffc9b0895727e(tTJSString * _this, const tTJSString & ref) { return _this->CompareIC(ref); } static bool __stdcall TVP_Stub_1fb2d2e44cf83aebef7b26fd6b20bc2b(tTJSString * _this, const tjs_char * ref) { return _this->operator ==(ref); } static bool __stdcall TVP_Stub_bd6aa777bac947f5cffd891e9c724794(tTJSString * _this, const tjs_char * ref) { return _this->operator !=(ref); } static tjs_int __stdcall TVP_Stub_83c662330b75d616cdc8a4e11d7ababa(tTJSString * _this, const tjs_char * ref) { return _this->CompareIC(ref); } static bool __stdcall TVP_Stub_bbde02fe30c8a6cadb7073174ea3a874(tTJSString * _this, const tTJSString & ref) { return _this->operator <(ref); } static bool __stdcall TVP_Stub_cc1c14f63867f90bc883de03e9212cbc(tTJSString * _this, const tTJSString & ref) { return _this->operator >(ref); } static tTJSString __stdcall TVP_Stub_236e007b32bc2631b5f6dc1eda6be0a9(tTJSString * _this, const tTJSString & ref) { return _this->operator +(ref); } static tTJSString __stdcall TVP_Stub_cfbb9809e0e6d954b2652856e935ced9(tTJSString * _this, const tjs_char * ref) { return _this->operator +(ref); } static tTJSString __stdcall TVP_Stub_60ee96ae4a7704340bef20fb35ba6ade(tTJSString * _this, tjs_char rch) { return _this->operator +(rch); } static tjs_char __stdcall TVP_Stub_564b37278b50f4e5597dff6540868d49(tTJSString * _this, tjs_uint i) { return _this->operator [](i); } static void __stdcall TVP_Stub_890b3a4831b824653e919b4a5197358d(tTJSString * _this, tTJSString & dest) { return _this->AsLowerCase(dest); } static void __stdcall TVP_Stub_2dfa6c77c5051d160b8a06f540e0d68b(tTJSString * _this, tTJSString & dest) { return _this->AsUpperCase(dest); } static void __stdcall TVP_Stub_05f88567d510fd84659ccbf493f647ed(tTJSString * _this, tTJSString & dest) { return _this->EscapeC(dest); } static void __stdcall TVP_Stub_7166b8f7bb9688c980e4fa172f06f30c(tTJSString * _this, tTJSString & dest) { return _this->UnescapeC(dest); } static bool __stdcall TVP_Stub_b9456ecba8b7898d80d2e5caa64035c9(tTJSString * _this, const tjs_char * string) { return _this->StartsWith(string); } static bool __stdcall TVP_Stub_dd44464bd8430a5be5fef0cffcd97117(tTJSString * _this, const tTJSString & string) { return _this->StartsWith(string); } static tjs_int __stdcall TVP_Stub_a57696ca0c157cd7d3cd4e58c1df957c(tTJSString * _this) { return _this->GetNarrowStrLen(); } static void __stdcall TVP_Stub_1aea9f8a38bbb875b6d052f330da9178(tTJSString * _this, tjs_nchar * dest , tjs_int destmaxlen) { return _this->ToNarrowStr(dest, destmaxlen); } static bool __stdcall TVP_Stub_2d3b3d6e22ee139cda9eee47dc031945(tTJSString * _this) { return _this->IsEmpty(); } static tjs_int __stdcall TVP_Stub_8ff49e56c3c4c566561dcdd5c9ecc4db(tTJSString * _this) { return _this->GetLen(); } static tjs_int __stdcall TVP_Stub_490b547e93e40082d0b83312467104f9(tTJSString * _this) { return _this->length(); } static tjs_char __stdcall TVP_Stub_2c1ef06748df47df52b586ac0fbc6a34(tTJSString * _this) { return _this->GetLastChar(); } static void * __stdcall TVP_Stub_b6b2a03160b88239eccd18d89b1537d3(size_t size) { return tTJSString::operator new(size); } static void __stdcall TVP_Stub_8becefbd52c76c7ecb0ea7b7f50b7915(void * p) { return tTJSString::operator delete(p); } static void * __stdcall TVP_Stub_74b9687a3bfd3b2c7abe226efc4225c1(size_t size) { return tTJSString::operator new [](size); } static void __stdcall TVP_Stub_7cafc2bf5965b594e60830e3057bbd58(void * p) { return tTJSString::operator delete [](p); } static void * __stdcall TVP_Stub_80f111939c5694cbf43d07cf0ad1726c(size_t size , void * buf) { return tTJSString::operator new(size, buf); } static void __stdcall TVP_Stub_8dc9cef84191f79b38403a2070952fd4(tTJSVariantString * _this) { return _this->AddRef(); } static void __stdcall TVP_Stub_1d42bd1e659b36886c20567497b7ee96(tTJSVariantString * _this) { return _this->Release(); } static void __stdcall TVP_Stub_0848fbdc7eeddb12c80bcd9c31383a64(tTJSVariantString * _this, const tjs_char * ref , tjs_int maxlen = - 1) { return _this->SetString(ref, maxlen); } static void __stdcall TVP_Stub_1f1123c906c28ab6d16b6bef3f7ae978(tTJSVariantString * _this, const tjs_nchar * ref) { return _this->SetString(ref); } static void __stdcall TVP_Stub_b84394e20cc73a90349cf5be4e783111(tTJSVariantString * _this, tjs_uint len) { return _this->AllocBuffer(len); } static void __stdcall TVP_Stub_76e0db3797851fe8ff90cf84780c50ad(tTJSVariantString * _this, const tjs_char * ref) { return _this->ResetString(ref); } static void __stdcall TVP_Stub_6616241156c22bced42cd9f2f647677e(tTJSVariantString * _this, tjs_uint applen) { return _this->AppendBuffer(applen); } static void __stdcall TVP_Stub_1ace346a3dd546c66ad115a33d8cf693(tTJSVariantString * _this, const tjs_char * str) { return _this->Append(str); } static void __stdcall TVP_Stub_96fb9bbe33531d4268573355c658e165(tTJSVariantString * _this, const tjs_char * str , tjs_int applen) { return _this->Append(str, applen); } static tTJSVariantString * __stdcall TVP_Stub_c90b5737134c76f9ed0bb5da7cfaad8c(tTJSVariantString * _this) { return _this->FixLength(); } static tjs_uint32 * __stdcall TVP_Stub_070ed05259a265cabdd82bfedabdd638(tTJSVariantString * _this) { return _this->GetHint(); } static const tjs_char * __stdcall TVP_Stub_008b7e3a4c5bb23ee991f684a5064737(tTJSVariantString * _this) { return _this->operator const tjs_char *(); } static tjs_int __stdcall TVP_Stub_b64741dc4544ed43c44ddb6d0eb838ea(tTJSVariantString * _this) { return _this->GetLength(); } static tTVInteger __stdcall TVP_Stub_5b83e28b2d9ab0f75d7c7f6f61b5ded6(tTJSVariantString * _this) { return _this->ToInteger(); } static tTVReal __stdcall TVP_Stub_b948c9f43837efa489b0b91f3f675710(tTJSVariantString * _this) { return _this->ToReal(); } static void __stdcall TVP_Stub_eb83216f6f718245468ef48b97ab4c2d(tTJSVariantString * _this, tTJSVariant & dest) { return _this->ToNumber(dest); } static tjs_int __stdcall TVP_Stub_c66ab4868b743de9c0ba8b26c67b23da(tTJSVariantString * _this) { return _this->GetRefCount(); } #include "tjsTypes.h" #include "tjsConfig.h" static tjs_int __stdcall TVP_Stub_586e16d502a6ad98b08161bdb090f8b6(const tjs_char * s) { return TJS_atoi(s); } static tjs_char * __stdcall TVP_Stub_d8bc9c71c80b200c39b29167d795cad0(tjs_int value , tjs_char * string) { return TJS_int_to_str(value, string); } static tjs_char * __stdcall TVP_Stub_85df4beb87f6503891e116ce046353c3(tjs_int64 value , tjs_char * string) { return TJS_tTVInt_to_str(value, string); } static tjs_int __stdcall TVP_Stub_35b6a7e1c73f257aae91e05fa9826e84(const tjs_char * s1 , const tjs_char * s2 , size_t maxlen) { return TJS_strnicmp(s1, s2, maxlen); } static tjs_int __stdcall TVP_Stub_a25b46701e25030af1ed847e0df229eb(const tjs_char * s1 , const tjs_char * s2) { return TJS_stricmp(s1, s2); } static void __stdcall TVP_Stub_c8906bf1efa5e86f9fddfab55a01c8f6(tjs_char * d , const tjs_char * s , size_t len) { return TJS_strcpy_maxlen(d, s, len); } static void __stdcall TVP_Stub_8141059f613820f694608af28e20cbad(tjs_char * d , const tjs_char * s) { return TJS_strcpy(d, s); } static size_t __stdcall TVP_Stub_cf2690e47099ac6378ed50df4a8a8e90(const tjs_char * d) { return TJS_strlen(d); } #include "tjsVariantString.h" static tjs_char * __stdcall TVP_Stub_810c7054e44f535cf250f00707105417(tjs_uint len) { return TJSVS_malloc(len); } static tjs_char * __stdcall TVP_Stub_52a9af7905ddc71d8b4e0ef7366eebdd(tjs_char * buf , tjs_uint len) { return TJSVS_realloc(buf, len); } static void __stdcall TVP_Stub_1635dbae2d91b338ddfd0430f8aa7f10(tjs_char * buf) { return TJSVS_free(buf); } static tTJSVariantString * __stdcall TVP_Stub_30df0c29ad8f672f7fe0742b4b11cd7f(const tjs_char * ref1 , const tjs_char * ref2) { return TJSAllocVariantString(ref1, ref2); } static tTJSVariantString * __stdcall TVP_Stub_61c82dec644c58290a25f34a69478870(const tjs_char * ref , tjs_int n) { return TJSAllocVariantString(ref, n); } static tTJSVariantString * __stdcall TVP_Stub_f08e347d2d47dc5fc9a3cb59355b4fbb(const tjs_char * ref) { return TJSAllocVariantString(ref); } static tTJSVariantString * __stdcall TVP_Stub_5c62e59c2062f658d4c79d5257a9a586(const tjs_nchar * ref) { return TJSAllocVariantString(ref); } static tTJSVariantString * __stdcall TVP_Stub_259c72d8bfed1210ca71c54f24cacc7a(const tjs_uint8 * * src) { return TJSAllocVariantString(src); } static tTJSVariantString * __stdcall TVP_Stub_801a92ace08eb7ed001406869a39a75f(tjs_uint len) { return TJSAllocVariantStringBuffer(len); } static tTJSVariantString * __stdcall TVP_Stub_e22e647af4ded8e51b1e76c845b4c8e2(tTJSVariantString * str , const tjs_char * app) { return TJSAppendVariantString(str, app); } static tTJSVariantString * __stdcall TVP_Stub_12902221314df9bcf7f7cb74a5242fe0(tTJSVariantString * str , const tTJSVariantString * app) { return TJSAppendVariantString(str, app); } static tTJSVariantString * __stdcall TVP_Stub_b10feea1619ba8ac11237c12002cdb3e(const tjs_char * format , tjs_uint numparams , tTJSVariant * * params) { return TJSFormatString(format, numparams, params); } #include "tjsUtils.h" static const tjs_char * __stdcall TVP_Stub_19755b50d241edcb477bdcac22663778(tTJSVariantType type) { return TJSVariantTypeToTypeString(type); } static tTJSString __stdcall TVP_Stub_040a0ecf46963e094ee8ec32ab3f1962(const tTJSVariant & val , tjs_int maxlen = 512) { return TJSVariantToReadableString(val, maxlen); } static tTJSString __stdcall TVP_Stub_525c529dc687b5d86424d775d00bdfce(const tTJSVariant & val) { return TJSVariantToExpressionString(val); } static void * __stdcall TVP_Stub_c96107b91e2a215f560a2612c6e85931(tjs_uint bytes , tjs_uint align_bits) { return TJSAlignedAlloc(bytes, align_bits); } static void __stdcall TVP_Stub_b8788eaa2ca495263c6ea2df264af5f5(void * ptr) { return TJSAlignedDealloc(ptr); } static tjs_uint32 __stdcall TVP_Stub_4c6494008c520d896d699f82aca30b25(tjs_real r) { return TJSGetFPClass(r); } #include "tjsString.h" static tTJSString __stdcall TVP_Stub_7d8f8d5e0832ecf248b19a89801ead0e(const tjs_char * lhs , const tTJSString & rhs) { return operator +(lhs, rhs); } static tTJSString __stdcall TVP_Stub_70849965060a6402f41b0b11ec2bb3a7(tjs_uint32 num , int zeropad = 8) { return TJSInt32ToHex(num, zeropad); } #include "tjsInterface.h" #include "tjsErrorDefs.h" #include "tjsNative.h" static tjs_int32 __stdcall TVP_Stub_c72efa6b4efaa6664ae637a03e98e866(const tjs_char * name) { return TJSRegisterNativeClass(name); } static tjs_int32 __stdcall TVP_Stub_a250e46575d0df1166e1542613218a5c(const tjs_char * name) { return TJSFindNativeClassID(name); } static const tjs_char * __stdcall TVP_Stub_a7bcff67b8d380c225b9d0d83921b3ae(tjs_int32 id) { return TJSFindNativeClassName(id); } static tTJSNativeClassMethod * __stdcall TVP_Stub_fb68a3aa16bd2eb7d7550283170321bf(tTJSNativeClassMethodCallback callback) { return TJSCreateNativeClassMethod(callback); } static tTJSNativeClassMethod * __stdcall TVP_Stub_35b4299ede11f511b331b713ba9f38a8(tTJSNativeClassMethodCallback callback) { return TJSCreateNativeClassConstructor(callback); } static tTJSNativeClassProperty * __stdcall TVP_Stub_efe52691cff20b2dfaa16e8e16caac0a(tTJSNativeClassPropertyGetCallback get , tTJSNativeClassPropertySetCallback set) { return TJSCreateNativeClassProperty(get, set); } static void __stdcall TVP_Stub_38eed43ef69251c34dc45695b8cf35c0(tTJSNativeClass * cls , const tjs_char * name , iTJSDispatch2 * dsp , const tjs_char * classname , tTJSNativeInstanceType type , tjs_uint32 flags = 0) { return TJSNativeClassRegisterNCM(cls, name, dsp, classname, type, flags); } static void __stdcall TVP_Stub_2058b65abdfb7598910f0d584d40a19d(tTJSNativeClass * cls , tjs_int32 classid) { return TJSNativeClassSetClassID(cls, classid); } static tTJSNativeClassForPlugin * __stdcall TVP_Stub_1ebecaefe2ffdc811fccbac42e67e544(const ttstr & name , tTJSCreateNativeInstance createinstance) { return TJSCreateNativeClassForPlugin(name, createinstance); } #include "tjsVariant.h" static void __stdcall TVP_Stub_09e0f0912f8d758d3736ece9478c2686() { return TJSThrowNullAccess(); } static void __stdcall TVP_Stub_23d61eda3959b087b618e348471e2c36() { return TJSThrowDivideByZero(); } static tTJSVariantOctet * __stdcall TVP_Stub_e99b22c79b5bf04f3382f959c7bb69ca(const tjs_uint8 * data , tjs_uint length) { return TJSAllocVariantOctet(data, length); } static tTJSVariantOctet * __stdcall TVP_Stub_9c4bb9ebee4db0fcebeae11c34950f97(const tjs_uint8 * data1 , tjs_uint len1 , const tjs_uint8 * data2 , tjs_uint len2) { return TJSAllocVariantOctet(data1, len1, data2, len2); } static tTJSVariantOctet * __stdcall TVP_Stub_505a9563aeb1b0255cfcc8197bee7d9e(const tTJSVariantOctet * o1 , const tTJSVariantOctet * o2) { return TJSAllocVariantOctet(o1, o2); } static tTJSVariantOctet * __stdcall TVP_Stub_f5ab80fc67ee04570330b9035144e760(const tjs_uint8 * * src) { return TJSAllocVariantOctet(src); } static void __stdcall TVP_Stub_af50188bbaa019ee88b19ecd931f7cce(tTJSVariantOctet * o) { return TJSDeallocVariantOctet(o); } static tTJSVariantString * __stdcall TVP_Stub_268c452e85a6ac75301a6132f4f5e38b(const tTJSVariantOctet * oct) { return TJSOctetToListString(oct); } static tTJSVariantString * __stdcall TVP_Stub_646770a19b1768b372c9991ef0d3de85(const tTJSVariantClosure & dsp) { return TJSObjectToString(dsp); } static tTJSVariantString * __stdcall TVP_Stub_5ec88e04fcb8e1877752281e172173ed(tjs_int64 i) { return TJSIntegerToString(i); } static tTJSVariantString * __stdcall TVP_Stub_923f8161f2d2ba0e883bc4edc2901960(tjs_real r) { return TJSRealToString(r); } static tTJSVariantString * __stdcall TVP_Stub_6f70cdb7586cbe571204f286f43c9780(tjs_real r) { return TJSRealToHexString(r); } static tTVInteger __stdcall TVP_Stub_9a4eaa6a627038799015c093609bdde7(const tjs_char * str) { return TJSStringToInteger(str); } static tTVReal __stdcall TVP_Stub_c8bb6590f4a7adc906d7b3e42d907267(const tjs_char * str) { return TJSStringToReal(str); } #include "tjsArray.h" static iTJSDispatch2 * __stdcall TVP_Stub_8323d57f26876d87271dbfa257b7f7e2(iTJSDispatch2 * * classout = NULL) { return TJSCreateArrayObject(classout); } static tjs_int __stdcall TVP_Stub_4d6f148e8997e1ae0cc0006ec1bd9618(iTJSDispatch2 * dsp) { return TJSGetArrayElementCount(dsp); } static tjs_int __stdcall TVP_Stub_7f03a4ddb254d0518642d15513eaea85(iTJSDispatch2 * dsp , tTJSVariant * dest , tjs_uint start , tjs_int count) { return TJSCopyArrayElementTo(dsp, dest, start, count); } #include "tjsDictionary.h" static iTJSDispatch2 * __stdcall TVP_Stub_4add3926c72ba9df9259be58b680de0d(iTJSDispatch2 * * classout = NULL) { return TJSCreateDictionaryObject(classout); } #include "tjs.h" #include "tjsMessage.h" static ttstr __stdcall TVP_Stub_075d42cff8dc0c1fbd99c7459a63e526(const tjs_char * name) { return TJSGetMessageMapMessage(name); } #include "tjsGlobalStringMap.h" static ttstr __stdcall TVP_Stub_b6bc45b28e194c7ac98bfdea88edee36(const ttstr & string) { return TJSMapGlobalStringMap(string); } #include "tjsObject.h" static void __stdcall TVP_Stub_6dff6abb075da1a304520e60c011ef7b(tjs_int op , tTJSVariant & target , const tTJSVariant * param) { return TJSDoVariantOperation(op, target, param); } static void __stdcall TVP_Stub_892ffbdb8375851fc557e4abe9589b77() { return TJSDoRehash(); } static iTJSDispatch2 * __stdcall TVP_Stub_b2f3538284fc2adda2a43272ee654a96() { return TJSCreateCustomObject(); } #include "StorageIntf.h" static ttstr __stdcall TVP_Stub_e0ff899ea4a9cc49a0e3b38deaf93b45() { return TVPGetTemporaryName(); } static ttstr __stdcall TVP_Stub_4b9c9ac2aafad07af4b16f34e9d4bba2() { return TVPGetAppPath(); } static void __stdcall TVP_Stub_c2e423356d9ca3f26f9c1d294ee9b742(iTVPStorageMedia * media) { return TVPRegisterStorageMedia(media); } static void __stdcall TVP_Stub_c07314686fdf5815ce9b058020da942b(iTVPStorageMedia * media) { return TVPUnregisterStorageMedia(media); } static bool __stdcall TVP_Stub_4a197be1985d45ee86d5672d24134560(const ttstr & name) { return TVPIsExistentStorageNoSearch(name); } static bool __stdcall TVP_Stub_dec720a9c3cd2b378f195cf71a9ff8b0(const ttstr & name) { return TVPIsExistentStorageNoSearchNoNormalize(name); } static ttstr __stdcall TVP_Stub_5726a5c7af641ebaa504dc9ec8380938(const ttstr & name) { return TVPNormalizeStorageName(name); } static void __stdcall TVP_Stub_1c53bc96ac9dfd483c2227bc5fa44825(const ttstr & name) { return TVPSetCurrentDirectory(name); } static void __stdcall TVP_Stub_1940c8fa03145aa029d0b7718ce0c809(ttstr & name) { return TVPGetLocalName(name); } static ttstr __stdcall TVP_Stub_b37f047c0f9bd143b34a2fc87ce5f16e(const ttstr & name) { return TVPExtractStorageExt(name); } static ttstr __stdcall TVP_Stub_dec35fbd2a24fc32e5c220174d864cf4(const ttstr & name) { return TVPExtractStorageName(name); } static ttstr __stdcall TVP_Stub_86fd45a126296891aee413388597203e(const ttstr & name) { return TVPExtractStoragePath(name); } static ttstr __stdcall TVP_Stub_603243e54f3508c37d993e8359b735dc(const ttstr & name) { return TVPChopStorageExt(name); } static void __stdcall TVP_Stub_c3eadbd75b32dabe6faecebf492eb486(const ttstr & name) { return TVPAddAutoPath(name); } static void __stdcall TVP_Stub_725e49de1d970ef04b179776666f2c34(const ttstr & name) { return TVPRemoveAutoPath(name); } static ttstr __stdcall TVP_Stub_55a9b73f877bfd4c6d8157e7b1c458df(const ttstr & name) { return TVPGetPlacedPath(name); } static bool __stdcall TVP_Stub_d070209f152dd22087e6e996e02c85cf(const ttstr & name) { return TVPIsExistentStorage(name); } static void __stdcall TVP_Stub_308f905626bc51c7ef9b65b2c0ca34b2() { return TVPClearStorageCaches(); } #include "TextStream.h" static iTJSTextReadStream * __stdcall TVP_Stub_95aab2a1ac9491e8026f4977e0918760(const ttstr & name , const ttstr & modestr) { return TVPCreateTextStreamForRead(name, modestr); } static iTJSTextReadStream * __stdcall TVP_Stub_e0ac94325eb783ca2fe7856a54444c90(const ttstr & name , const ttstr & modestr , const ttstr & encoding) { return TVPCreateTextStreamForReadByEncoding(name, modestr, encoding); } static iTJSTextWriteStream * __stdcall TVP_Stub_0c99a79e866f08b4df3914e83fc203dc(const ttstr & name , const ttstr & modestr) { return TVPCreateTextStreamForWrite(name, modestr); } static void __stdcall TVP_Stub_f2de531a016173057ff3540e47fed4e6(const ttstr & encoding) { return TVPSetDefaultReadEncoding(encoding); } static const tjs_char * __stdcall TVP_Stub_4224a9066d8d13d6d7e12f1ace6a5beb() { return TVPGetDefaultReadEncoding(); } #include "CharacterSet.h" static tjs_int __stdcall TVP_Stub_900476efbc2031e643c042ca8e63a3d7(const tjs_char * in , char * out) { return TVPWideCharToUtf8String(in, out); } static tjs_int __stdcall TVP_Stub_07dfce61d490cf671a2d5359d713d64a(const char * in , tjs_char * out) { return TVPUtf8ToWideCharString(in, out); } #include "XP3Archive.h" static void __stdcall TVP_Stub_52d30ac8479ef7e870b5aff076482799(tTVPXP3ArchiveExtractionFilter filter) { return TVPSetXP3ArchiveExtractionFilter(filter); } #include "EventIntf.h" static void __stdcall TVP_Stub_8e4d0392ed46e87f94e5fcf675a124a1() { return TVPBreathe(); } static bool __stdcall TVP_Stub_73f46e08d17e707725f433b454f05a89() { return TVPGetBreathing(); } static void __stdcall TVP_Stub_80d60e682fa72973071e335db272a2a2(bool en) { return TVPSetSystemEventDisabledState(en); } static bool __stdcall TVP_Stub_6bd6262185fa0b9cf1750f6a525d893a() { return TVPGetSystemEventDisabledState(); } static void __stdcall TVP_Stub_cf29f737d4eb450b26789d421d0ec69a(iTJSDispatch2 * source , iTJSDispatch2 * target , ttstr & eventname , tjs_uint32 tag , tjs_uint32 flag , tjs_uint numargs , tTJSVariant * args) { return TVPPostEvent(source, target, eventname, tag, flag, numargs, args); } static tjs_int __stdcall TVP_Stub_13c0e371c08fd1b9da2f0c103d01c59a(iTJSDispatch2 * source , iTJSDispatch2 * target , const ttstr & eventname , tjs_uint32 tag = 0) { return TVPCancelEvents(source, target, eventname, tag); } static bool __stdcall TVP_Stub_82693e38df8f033ea98f9b7969d66d7b(iTJSDispatch2 * source , iTJSDispatch2 * target , const ttstr & eventname , tjs_uint32 tag) { return TVPAreEventsInQueue(source, target, eventname, tag); } static tjs_int __stdcall TVP_Stub_6e3f8a3b18f55dae6153a889f00a3e87(iTJSDispatch2 * source , iTJSDispatch2 * target , const ttstr & eventname , tjs_uint32 tag) { return TVPCountEventsInQueue(source, target, eventname, tag); } static void __stdcall TVP_Stub_efe14a197131b4813656d6669cc3475b(iTJSDispatch2 * source , iTJSDispatch2 * target , tjs_uint32 tag = 0) { return TVPCancelEventsByTag(source, target, tag); } static void __stdcall TVP_Stub_ba4ecf60f872f757b69c84f457b3e941(iTJSDispatch2 * source) { return TVPCancelSourceEvents(source); } static iTJSDispatch2 * __stdcall TVP_Stub_dffedabe32ce886e3b7e695b44ad3547(const tjs_char * type , iTJSDispatch2 * targthis , iTJSDispatch2 * targ) { return TVPCreateEventObject(type, targthis, targ); } static void __stdcall TVP_Stub_f518c60b165658d19a0fadd8f69586aa(tTVPContinuousEventCallbackIntf * cb) { return TVPAddContinuousEventHook(cb); } static void __stdcall TVP_Stub_6fefcb1c2ca01a876c301ab41dbdab9f(tTVPContinuousEventCallbackIntf * cb) { return TVPRemoveContinuousEventHook(cb); } static void __stdcall TVP_Stub_df55083347df0483b4ca6ba1e4f0b9a0(tTVPCompactEventCallbackIntf * cb) { return TVPAddCompactEventHook(cb); } static void __stdcall TVP_Stub_d8d28310f702714733c4c5dc850058df(tTVPCompactEventCallbackIntf * cb) { return TVPRemoveCompactEventHook(cb); } #include "SystemIntf.h" static ttstr __stdcall TVP_Stub_52d24c38b05be174bc5c4fdcf02e9b9f() { return TVPGetPlatformName(); } static ttstr __stdcall TVP_Stub_f27f455c8f30cbaf1706faac3c7b8e02() { return TVPGetOSName(); } #include "SystemImpl.h" static bool __stdcall TVP_Stub_78ec453a50b2800bb01347e8ebbac000(tjs_uint keycode , bool getcurrent = true) { return TVPGetAsyncKeyState(keycode, getcurrent); } #include "ScriptMgnIntf.h" static iTJSDispatch2 * __stdcall TVP_Stub_0936d0f6fc53339d255893e58bcc6699() { return TVPGetScriptDispatch(); } static void __stdcall TVP_Stub_f4f7181b7fd679784c50b0cc7ba4c60e(const ttstr & content , tTJSVariant * result = NULL) { return TVPExecuteScript(content, result); } static void __stdcall TVP_Stub_79816d7e5741c2416fefe2c2a8baef00(const ttstr & content , iTJSDispatch2 * context , tTJSVariant * result = NULL) { return TVPExecuteScript(content, context, result); } static void __stdcall TVP_Stub_42a3d248fab928f16555abcceca62834(const ttstr & content , tTJSVariant * result = NULL) { return TVPExecuteExpression(content, result); } static void __stdcall TVP_Stub_926d6212b8b1b238e7bef9b17a3ee643(const ttstr & content , iTJSDispatch2 * context , tTJSVariant * result = NULL) { return TVPExecuteExpression(content, context, result); } static void __stdcall TVP_Stub_236e3d626784d80ca2cc5b2fe14cd9c6(const ttstr & content , const ttstr & name , tjs_int lineofs , tTJSVariant * result = NULL) { return TVPExecuteScript(content, name, lineofs, result); } static void __stdcall TVP_Stub_1bfac11a5f95c842f97a8bb57d4019de(const ttstr & content , const ttstr & name , tjs_int lineofs , iTJSDispatch2 * context , tTJSVariant * result = NULL) { return TVPExecuteScript(content, name, lineofs, context, result); } static void __stdcall TVP_Stub_198ce21c54b0cea4c1bf5eeba35349ab(const ttstr & content , const ttstr & name , tjs_int lineofs , tTJSVariant * result = NULL) { return TVPExecuteExpression(content, name, lineofs, result); } static void __stdcall TVP_Stub_590a1ec7f64904eaa32b5c771bb5f8cd(const ttstr & content , const ttstr & name , tjs_int lineofs , iTJSDispatch2 * context , tTJSVariant * result = NULL) { return TVPExecuteExpression(content, name, lineofs, context, result); } static void __stdcall TVP_Stub_dd13d4bc2b48540a92f047bf015b829b(const ttstr & name , tTJSVariant * result = NULL , bool isexpression = false , const tjs_char * modestr = NULL) { return TVPExecuteStorage(name, result, isexpression, modestr); } static void __stdcall TVP_Stub_0ff502d492598d2211405180bfb4d1e1(const ttstr & name , iTJSDispatch2 * context , tTJSVariant * result = NULL , bool isexpression = false , const tjs_char * modestr = NULL) { return TVPExecuteStorage(name, context, result, isexpression, modestr); } static void __stdcall TVP_Stub_cf5401746759bfe38918087aaab6c57b() { return TVPDumpScriptEngine(); } static void __stdcall TVP_Stub_04e84aa7d8cf0477d55c700164544b38(const tjs_uint8 * content , size_t len , iTJSDispatch2 * context , tTJSVariant * result = NULL , const tjs_char * name = NULL) { return TVPExecuteBytecode(content, len, context, result, name); } static void __stdcall TVP_Stub_449039d3afbfbd52a63130a3b227a490(const ttstr & filename) { return TVPCreateMessageMapFile(filename); } #include "StorageImpl.h" static bool __stdcall TVP_Stub_347a4fa85af84e223c4b61d33ead694a(const ttstr & name) { return TVPCheckExistentLocalFolder(name); } static bool __stdcall TVP_Stub_4ad1dd24b3b4769ee10149eea006af7a(const ttstr & name) { return TVPCheckExistentLocalFile(name); } static bool __stdcall TVP_Stub_b246b17b62d273bdc04e9d9e827f5c74(const ttstr & folder) { return TVPCreateFolders(folder); } static IStream * __stdcall TVP_Stub_9974ebc6296f925cff55d8bcb2d52ce9(const ttstr & name , tjs_uint32 flags) { return TVPCreateIStream(name, flags); } static tTJSBinaryStream * __stdcall TVP_Stub_0e0c9d9107d8c56b8bc4d4198ae9208a(IStream * refstream) { return TVPCreateBinaryStreamAdapter(refstream); } #include "PluginImpl.h" static void __stdcall TVP_Stub_c23ece207f6ec2dd7c76ef873047aee3(const char * funcname) { return TVPThrowPluginUnboundFunctionError(funcname); } static void __stdcall TVP_Stub_81507020bc646be2f53ab95b9430ba27(const tjs_char * funcname) { return TVPThrowPluginUnboundFunctionError(funcname); } static void * __stdcall TVP_Stub_acc0d3861d1b971abcbdda1c075dd681(size_t size) { return TVP_malloc(size); } static void * __stdcall TVP_Stub_ff2dccead1b31e3f34e8be3e2ba5bbf1(void * pp , size_t size) { return TVP_realloc(pp, size); } static void __stdcall TVP_Stub_e17db0d4f69625c61aba7fffe540dded(void * pp) { return TVP_free(pp); } static tjs_int __stdcall TVP_Stub_5bbc872e7bba5b761c509d31116e4460() { return TVPGetAutoLoadPluginCount(); } static int __stdcall TVP_Stub_4adf361303eae78829250c7b732a5722(unsigned char * dest , unsigned long * destlen , const unsigned char * source , unsigned long sourcelen) { return ZLIB_uncompress(dest, destlen, source, sourcelen); } static int __stdcall TVP_Stub_bf172364c57c1aa561b145fd5cacda0c(unsigned char * dest , unsigned long * destlen , const unsigned char * source , unsigned long sourcelen) { return ZLIB_compress(dest, destlen, source, sourcelen); } static int __stdcall TVP_Stub_d7687aa80dac10f88deac7aa7e70538a(unsigned char * dest , unsigned long * destlen , const unsigned char * source , unsigned long sourcelen , int level) { return ZLIB_compress2(dest, destlen, source, sourcelen, level); } static void __stdcall TVP_Stub_b18b7259f98029f745c75291d6855ab1(TVP_md5_state_t * pms) { return TVP_md5_init(pms); } static void __stdcall TVP_Stub_b79e5d877116025576ca1f76af124009(TVP_md5_state_t * pms , const tjs_uint8 * data , int nbytes) { return TVP_md5_append(pms, data, nbytes); } static void __stdcall TVP_Stub_8aea098dfe8a36c705cc2a9e1a189b84(TVP_md5_state_t * pms , tjs_uint8 * digest) { return TVP_md5_finish(pms, digest); } static HWND __stdcall TVP_Stub_4ccd3f6ab60d61be6dbfc59e8e3d1726() { return TVPGetApplicationWindowHandle(); } static void __stdcall TVP_Stub_3d70bb72a7d7765c7e8ea580079ab7e9() { return TVPProcessApplicationMessages(); } static void __stdcall TVP_Stub_eba9b272d78a4b0cd7f9212e29a58607() { return TVPHandleApplicationMessage(); } static bool __stdcall TVP_Stub_cfbe8ee9d43aa64ae4190eac91f7c55f(const tjs_char * name , iTJSDispatch2 * dsp) { return TVPRegisterGlobalObject(name, dsp); } static bool __stdcall TVP_Stub_a4308a386968ef5d23025ab8a9e8c6db(const tjs_char * name) { return TVPRemoveGlobalObject(name); } static void __stdcall TVP_Stub_5a4fcbe1e398e3d9690d571acbbbae9f(tTVPTryBlockFunction tryblock , tTVPCatchBlockFunction catchblock , tTVPFinallyBlockFunction finallyblock , void * data) { return TVPDoTryBlock(tryblock, catchblock, finallyblock, data); } static bool __stdcall TVP_Stub_5b62f504fe6d22428d7518d6c52d775d(const wchar_t * module_filename , tjs_int & major , tjs_int & minor , tjs_int & release , tjs_int & build) { return TVPGetFileVersionOf(module_filename, major, minor, release, build); } #include "SysInitIntf.h" static bool __stdcall TVP_Stub_fb3b405f8747b54f26c332b9e6af81cd(const tjs_char * name , tTJSVariant * value = NULL) { return TVPGetCommandLine(name, value); } static tjs_int __stdcall TVP_Stub_b7ccd11d130f186883c109d2ba17b598() { return TVPGetCommandLineArgumentGeneration(); } static void __stdcall TVP_Stub_cf8ab6c24f25993ccc7663e572ac2991(const tjs_char * name , const ttstr & value) { return TVPSetCommandLine(name, value); } #include "SysInitImpl.h" #include "DetectCPU.h" static tjs_uint32 __stdcall TVP_Stub_ba40ffbca76695b54a02aa8c1f1e047b() { return TVPGetCPUType(); } #include "ThreadIntf.h" static tjs_int __stdcall TVP_Stub_c97720e639e95ba5130ce9dd78d30403() { return TVPGetProcessorNum(); } static tjs_int __stdcall TVP_Stub_c5557ac5391b1b831a22e64b65d1746c() { return TVPGetThreadNum(); } static void __stdcall TVP_Stub_3243a4c32d4f674f1bbc8d3895257568(tjs_int num) { return TVPBeginThreadTask(num); } static void __stdcall TVP_Stub_78390a3d08879903ee9558e9df68db4d(TVP_THREAD_TASK_FUNC func , TVP_THREAD_PARAM param) { return TVPExecThreadTask(func, param); } static void __stdcall TVP_Stub_58e9454d7096a52808f9a83b9ce25ff0() { return TVPEndThreadTask(); } #include "DebugIntf.h" static void __stdcall TVP_Stub_cdefadd0c3bf15b4639b2f0338a40585(const ttstr & line) { return TVPAddLog(line); } static void __stdcall TVP_Stub_4bf80e9bac16b9e3f9bf385b2fbce657(const ttstr & line) { return TVPAddImportantLog(line); } #include "Random.h" static void __stdcall TVP_Stub_51aeacf2b6ef9deb01c3b3db201d6bf9(const void * buf , tjs_int bufsize) { return TVPPushEnvironNoise(buf, bufsize); } static void __stdcall TVP_Stub_9ed5432d73448da47991df9577ee97bc(void * dest) { return TVPGetRandomBits128(dest); } #include "ClipboardIntf.h" static bool __stdcall TVP_Stub_cf1d02d1cc1aff0aae6c038c95dac80f(tTVPClipboardFormat format) { return TVPClipboardHasFormat(format); } static void __stdcall TVP_Stub_ddb0e05c72c0692e78af885ac7ec82dc(const ttstr & text) { return TVPClipboardSetText(text); } static bool __stdcall TVP_Stub_a3029db6292616cd16c228b91dc4af13(ttstr & text) { return TVPClipboardGetText(text); } #include "TickCount.h" static tjs_uint64 __stdcall TVP_Stub_2d90871c6bc15a9e8d97d24c29e78e3b() { return TVPGetTickCount(); } #include "MsgIntf.h" static ttstr __stdcall TVP_Stub_0af6744e35e38276d6a98c1f382b1519(const tjs_char * msg , const ttstr & p1) { return TVPFormatMessage(msg, p1); } static ttstr __stdcall TVP_Stub_ad40567a051208757642e5e087f3e741(const tjs_char * msg , const ttstr & p1 , const ttstr & p2) { return TVPFormatMessage(msg, p1, p2); } static void __stdcall TVP_Stub_6a15185daab9b274963fe5ef46305775(const tjs_char * msg) { return TVPThrowExceptionMessage(msg); } static void __stdcall TVP_Stub_073a2332a8ab3ed31ab81daea3d3f2c4(const tjs_char * msg , const ttstr & p1 , tjs_int num) { return TVPThrowExceptionMessage(msg, p1, num); } static void __stdcall TVP_Stub_01216e91225e06c7422bef0c2febc0cc(const tjs_char * msg , const ttstr & p1) { return TVPThrowExceptionMessage(msg, p1); } static void __stdcall TVP_Stub_16ce22ad500a5bdfd5d5743c847a28b6(const tjs_char * msg , const ttstr & p1 , const ttstr & p2) { return TVPThrowExceptionMessage(msg, p1, p2); } static ttstr __stdcall TVP_Stub_59251c4104f736fa2690c5f77fb0a908() { return TVPGetAboutString(); } static ttstr __stdcall TVP_Stub_f923750e0fdb51a6fc6c304832cb3dd3() { return TVPGetVersionInformation(); } static ttstr __stdcall TVP_Stub_bc77a1e312ff7827d90387fb92f0f5b0() { return TVPGetVersionString(); } static void __stdcall TVP_Stub_2090afd7ae8bcb021ec4d04947d0d845(tjs_int & major , tjs_int & minor , tjs_int & release , tjs_int & build) { return TVPGetSystemVersion(major, minor, release, build); } static void __stdcall TVP_Stub_3a0f858bdf86199dc2d00b583a3b915f(tjs_int & major , tjs_int & minor , tjs_int & release) { return TVPGetTJSVersion(major, minor, release); } #include "WaveIntf.h" static void __stdcall TVP_Stub_0d316a141f7a502ff8d9ffe2d38d25a8(tjs_int16 * output , const void * input , const tTVPWaveFormat & format , tjs_int count , bool downmix) { return TVPConvertPCMTo16bits(output, input, format, count, downmix); } static void __stdcall TVP_Stub_b31ff64ae2d8f93dbf28161d5080b295(tjs_int16 * output , const void * input , tjs_int channels , tjs_int bytespersample , tjs_int bitspersample , bool isfloat , tjs_int count , bool downmix) { return TVPConvertPCMTo16bits(output, input, channels, bytespersample, bitspersample, isfloat, count, downmix); } static void __stdcall TVP_Stub_d9b1c73516daea6a9c6564e2b731615a(float * output , const void * input , tjs_int channels , tjs_int bytespersample , tjs_int bitspersample , bool isfloat , tjs_int count) { return TVPConvertPCMToFloat(output, input, channels, bytespersample, bitspersample, isfloat, count); } static void __stdcall TVP_Stub_003f9d3de568fcd71dd532f33d38839c(float * output , const void * input , const tTVPWaveFormat & format , tjs_int count) { return TVPConvertPCMToFloat(output, input, format, count); } #include "WaveImpl.h" static void __stdcall TVP_Stub_5da29a19bbe279a89be00e16c59d7641() { return TVPReleaseDirectSound(); } static IDirectSound * __stdcall TVP_Stub_c1b52e8f3578d11f369552a887e13c5b() { return TVPGetDirectSound(); } #include "GraphicsLoaderIntf.h" static void __stdcall TVP_Stub_b94ead6de9316bc65758c5aefb564078(const ttstr & name , tTVPGraphicLoadingHandlerForPlugin loading , tTVPGraphicHeaderLoadingHandlerForPlugin header , tTVPGraphicSaveHandlerForPlugin save , tTVPGraphicAcceptSaveHandler accept , void * formatdata) { return TVPRegisterGraphicLoadingHandler(name, loading, header, save, accept, formatdata); } static void __stdcall TVP_Stub_8a35be936d2aca049e398a081e511c97(const ttstr & name , tTVPGraphicLoadingHandlerForPlugin loading , tTVPGraphicHeaderLoadingHandlerForPlugin header , tTVPGraphicSaveHandlerForPlugin save , tTVPGraphicAcceptSaveHandler accept , void * formatdata) { return TVPUnregisterGraphicLoadingHandler(name, loading, header, save, accept, formatdata); } static void __stdcall TVP_Stub_5b1fa785e397e643dd09cb43c2f2f4db() { return TVPClearGraphicCache(); } #include "tvpfontstruc.h" #include "tvpinputdefs.h" #include "LayerBitmapIntf.h" #include "drawable.h" #include "ComplexRect.h" #include "LayerIntf.h" static tjs_uint32 __stdcall TVP_Stub_29af78765c764c566e6adc77e0ea7041(tjs_uint32 col) { return TVPToActualColor(col); } static tjs_uint32 __stdcall TVP_Stub_9e0df54e4c24ee28d5517c1743faa3a3(tjs_uint32 col) { return TVPFromActualColor(col); } static iTJSDispatch2 * __stdcall TVP_Stub_d3aaa55d66777d7308ffa7a348c84841(tTJSNI_BaseLayer * layer) { return TVPGetObjectFrom_NI_BaseLayer(layer); } #include "LayerManager.h" #include "WindowIntf.h" #include "WindowImpl.h" static tjs_uint32 __stdcall TVP_Stub_b426fbfb6ccb4e89c252b6af566995b8() { return TVPGetCurrentShiftKeyState(); } static void __stdcall TVP_Stub_c145419db7b63f7488ea05a2a8826c1d(HWND hWnd , char virt , short key , short cmd) { return TVPRegisterAcceleratorKey(hWnd, virt, key, cmd); } static void __stdcall TVP_Stub_d795cd5ebfb6ca6f1b91bafbe66d7a65(HWND hWnd , short cmd) { return TVPUnregisterAcceleratorKey(hWnd, cmd); } static void __stdcall TVP_Stub_4564a3ce5cf48cb47e63a3948cef03be(HWND hWnd) { return TVPDeleteAcceleratorKeyTable(hWnd); } static void __stdcall TVP_Stub_bee2775f2e4042043b7cb08056d2ae5c() { return TVPEnsureDirect3DObject(); } static IDirect3D9 * __stdcall TVP_Stub_5fd8dfd2816a2cfd4a51cab41053d575() { return TVPGetDirect3DObjectNoAddRef(); } #include "DrawDevice.h" #include "voMode.h" #include "VideoOvlIntf.h" #include "TransIntf.h" static iTVPScanLineProvider * __stdcall TVP_Stub_9982ebedc12d343cb098e2a7b25bdef1(const ttstr & name , tjs_int bpp , tjs_uint32 key , tjs_uint w , tjs_uint h) { return TVPSLPLoadImage(name, bpp, key, w, h); } static void __stdcall TVP_Stub_81eeacbed5ee6129bef4b370e28b5d10(iTVPTransHandlerProvider * pro) { return TVPAddTransHandlerProvider(pro); } static void __stdcall TVP_Stub_6ed1088905d99012d2fb5827ea19527e(iTVPTransHandlerProvider * pro) { return TVPRemoveTransHandlerProvider(pro); } #include "transhandler.h" #include "tvpgl.h" static void __stdcall TVP_Stub_b4d6c64cc0004ffaba804f0e8f02ab9b(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPAlphaBlend(dest, src, len); } static void __stdcall TVP_Stub_2c3e08b8df93ec50451edd916c707030(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPAlphaBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_eba070d1583ca5f5d02630ba33a5504b(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPAlphaBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_ee474537852ce5eb165cb1761950faba(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPAlphaBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_eed221c603243522667e2f1c6ace3ba4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPAlphaBlend_d(dest, src, len); } static void __stdcall TVP_Stub_1f973c5e3cfaf00fa752b7e22d7ba481(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPAlphaBlend_a(dest, src, len); } static void __stdcall TVP_Stub_b9d5260bba9edd7503f1adf882218979(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPAlphaBlend_do(dest, src, len, opa); } static void __stdcall TVP_Stub_aedbd2eda61145de808e295331884245(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPAlphaBlend_ao(dest, src, len, opa); } static void __stdcall TVP_Stub_ce0f184e84752eb279e4f900d8b53c18(tjs_uint32 * dest , const tjs_uint32 color , tjs_int len) { return TVPAlphaColorMat(dest, color, len); } static void __stdcall TVP_Stub_0217d49393163b80897d044c1d93092f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPAdditiveAlphaBlend(dest, src, len); } static void __stdcall TVP_Stub_5bbd9d5b364840e9615af35a62f69d7d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPAdditiveAlphaBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_2b2837e81fcaeec35f61a2a3ecf2fb2d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPAdditiveAlphaBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_bb0706a78e9066944bfbffd1406be2d4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPAdditiveAlphaBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_770e67c91215292980b88cc6efb9f2a5(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPAdditiveAlphaBlend_a(dest, src, len); } static void __stdcall TVP_Stub_068ab11f05731f2c2e9ea8c5fdb16a9f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPAdditiveAlphaBlend_ao(dest, src, len, opa); } static void __stdcall TVP_Stub_b9873a0ad2653952cb2948b817e786e4(tjs_uint32 * buf , tjs_int len) { return TVPConvertAdditiveAlphaToAlpha(buf, len); } static void __stdcall TVP_Stub_11d9804ae4db32d731af69c397769cbf(tjs_uint32 * buf , tjs_int len) { return TVPConvertAlphaToAdditiveAlpha(buf, len); } static void __stdcall TVP_Stub_421f5aa6dbaaaf946f74942c77aac9bc(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchAlphaBlend(dest, len, src, srcstart, srcstep); } static void __stdcall TVP_Stub_563ee9dcb14a2914fc246e64679f42b5(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchAlphaBlend_HDA(dest, len, src, srcstart, srcstep); } static void __stdcall TVP_Stub_e23a54b6b80bd03111a40f669524724f(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchAlphaBlend_o(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_c90c8bbd18a7190636ae4269c36ad005(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchAlphaBlend_HDA_o(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_03c54a8e8c86e171f868a624e490691f(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchAlphaBlend_d(dest, len, src, srcstart, srcstep); } static void __stdcall TVP_Stub_30b63f3cc59b39f1a71829bbbdf6e45d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchAlphaBlend_a(dest, len, src, srcstart, srcstep); } static void __stdcall TVP_Stub_705bcc30a0561ec679c2267e1a573b23(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchAlphaBlend_do(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_5c627d080007e455b0393a9b4457cd4d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchAlphaBlend_ao(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_72a64cecd44d80f95fc93faf0d239e32(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchAdditiveAlphaBlend(dest, len, src, srcstart, srcstep); } static void __stdcall TVP_Stub_ef838904712bfdc614dbc689fbe7fb18(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int blend_y , tjs_int srcstart , tjs_int srcstep) { return TVPInterpStretchAdditiveAlphaBlend(dest, destlen, src1, src2, blend_y, srcstart, srcstep); } static void __stdcall TVP_Stub_acc97936adc40656e824cfdf7a34e20c(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchAdditiveAlphaBlend_HDA(dest, len, src, srcstart, srcstep); } static void __stdcall TVP_Stub_5ea1ba3602f9d9fee344de6c3406d7a3(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchAdditiveAlphaBlend_o(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_d25f0771b8fc7715d69f01d950463a49(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int blend_y , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPInterpStretchAdditiveAlphaBlend_o(dest, destlen, src1, src2, blend_y, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_f8ab11c930782ce058e517d0440ec87f(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchAdditiveAlphaBlend_HDA_o(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_b8157e369d53c2d944b76494980ced7b(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchAdditiveAlphaBlend_a(dest, len, src, srcstart, srcstep); } static void __stdcall TVP_Stub_aba94f656b4c1de827d11c72b36a5e9c(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchAdditiveAlphaBlend_ao(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_0656942f5a95783a4de73ca6e654d3b5(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransAlphaBlend(dest, len, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_5c2b7d12713dd5a94ef8e6eff1f79752(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransAlphaBlend_HDA(dest, len, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_6f1d30ac7e812cc5a059459c47638cd0(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransAlphaBlend_o(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_1d51684322635e7848ef53f7f6be8a1e(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransAlphaBlend_HDA_o(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_a1f2d56d138a4038fe1678328910a81d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransAlphaBlend_d(dest, len, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_c135ef491b533febfd49696d22a1dd3d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransAlphaBlend_a(dest, len, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_579117a873b466d78bf93e49c4a078da(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransAlphaBlend_do(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_ec8fa08705639eb7ae5d44ab63dea5e8(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransAlphaBlend_ao(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_b49dc1cda6109256815dae7b4293725d(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransAdditiveAlphaBlend(dest, len, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_912a670f56707ac70f2fee13660c2af8(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPInterpLinTransAdditiveAlphaBlend(dest, destlen, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_d0159986645df76b8c66fdb662efffde(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransAdditiveAlphaBlend_HDA(dest, len, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_cd7a2e6f91bf8d2daa3e28139d7d9f5c(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransAdditiveAlphaBlend_o(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_676004ca892b2bfee6859d0bb132fdd7(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPInterpLinTransAdditiveAlphaBlend_o(dest, destlen, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_d4b161d8a745baa5e2113669773a758f(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransAdditiveAlphaBlend_HDA_o(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_ef7537293f6e3b6127480f6c5fd018a1(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransAdditiveAlphaBlend_a(dest, len, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_6f6f73b75cffe40a28566d1832ae1224(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransAdditiveAlphaBlend_ao(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_7adc5aad39e459e01543d07c239efe57(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPCopyOpaqueImage(dest, src, len); } static void __stdcall TVP_Stub_3ff6b480097eec3f5fdb7bfad685fd2a(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPConstAlphaBlend(dest, src, len, opa); } static void __stdcall TVP_Stub_b2c50c3a1dfea7e9d05fed69818bafc3(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPConstAlphaBlend_HDA(dest, src, len, opa); } static void __stdcall TVP_Stub_8024df9077e2c85b5b718ad2c87e57e7(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPConstAlphaBlend_d(dest, src, len, opa); } static void __stdcall TVP_Stub_989769d4eb8e42e9c9bbe721b296406c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPConstAlphaBlend_a(dest, src, len, opa); } static void __stdcall TVP_Stub_cc1ac928b5c31570dfba7ed8f565be4b(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchCopyOpaqueImage(dest, destlen, src, srcstart, srcstep); } static void __stdcall TVP_Stub_62931efed5729a332e60bd1f7c7cecdf(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchConstAlphaBlend(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_53c18160b157088f72a9afd79737b48b(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int blend_y , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPInterpStretchConstAlphaBlend(dest, destlen, src1, src2, blend_y, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_48135697fd7f4df87402a7dd4d761555(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchConstAlphaBlend_HDA(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_e2c71cf04e876069eb7315c800a96898(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchConstAlphaBlend_d(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_1f63c018cf805ca1168af192cf8a4b41(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep , tjs_int opa) { return TVPStretchConstAlphaBlend_a(dest, len, src, srcstart, srcstep, opa); } static void __stdcall TVP_Stub_704a9574dafd3669e10d546549948e03(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransCopyOpaqueImage(dest, destlen, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_97905c510b9502c20c9322c9f5fb4188(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransConstAlphaBlend(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_b23e84230c4736667279c7a71f4ca53e(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPInterpLinTransConstAlphaBlend(dest, destlen, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_eb41fc900b0a6e3aba9d531f266137f1(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransConstAlphaBlend_HDA(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_5bd02c627b74bbb22d5a525b8bcbbd27(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransConstAlphaBlend_d(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_cc82e6a6b31ea743b9ebbdeed1ddedc3(tjs_uint32 * dest , tjs_int len , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch , tjs_int opa) { return TVPLinTransConstAlphaBlend_a(dest, len, src, sx, sy, stepx, stepy, srcpitch, opa); } static void __stdcall TVP_Stub_247b25d497e48bc0191fdb2ac530f4ca(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int len , tjs_int opa) { return TVPConstAlphaBlend_SD(dest, src1, src2, len, opa); } static void __stdcall TVP_Stub_6bbea3af36c35631641cc8356ff65475(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int len , tjs_int opa) { return TVPConstAlphaBlend_SD_a(dest, src1, src2, len, opa); } static void __stdcall TVP_Stub_cac02dfd62ba94abf6a346bef0bf3ab9(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int len , tjs_int opa) { return TVPConstAlphaBlend_SD_d(dest, src1, src2, len, opa); } static void __stdcall TVP_Stub_68eeb36d76d88ff00014f04b23454254(tjs_uint32 * table , tjs_int phase , tjs_int vague) { return TVPInitUnivTransBlendTable(table, phase, vague); } static void __stdcall TVP_Stub_65e03b1c849b6e9cb5c478024aa9a5b7(tjs_uint32 * table , tjs_int phase , tjs_int vague) { return TVPInitUnivTransBlendTable_d(table, phase, vague); } static void __stdcall TVP_Stub_7670c0c5630625ee6a73b7b9ee093650(tjs_uint32 * table , tjs_int phase , tjs_int vague) { return TVPInitUnivTransBlendTable_a(table, phase, vague); } static void __stdcall TVP_Stub_68a0abce6eefa08e74353ec48c4c87a8(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len) { return TVPUnivTransBlend(dest, src1, src2, rule, table, len); } static void __stdcall TVP_Stub_ccb6e098b9a0791a0f20e9f1af55e341(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len , tjs_int src1lv , tjs_int src2lv) { return TVPUnivTransBlend_switch(dest, src1, src2, rule, table, len, src1lv, src2lv); } static void __stdcall TVP_Stub_0f817efe47b451fd719c05a104c2b803(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len) { return TVPUnivTransBlend_d(dest, src1, src2, rule, table, len); } static void __stdcall TVP_Stub_efad1a3d774747bd2b5adb221ede2678(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len , tjs_int src1lv , tjs_int src2lv) { return TVPUnivTransBlend_switch_d(dest, src1, src2, rule, table, len, src1lv, src2lv); } static void __stdcall TVP_Stub_563285ed004ddd2945f91db7b5347d3c(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len) { return TVPUnivTransBlend_a(dest, src1, src2, rule, table, len); } static void __stdcall TVP_Stub_4c032260ef83d44bfe05fdc16843a8f9(tjs_uint32 * dest , const tjs_uint32 * src1 , const tjs_uint32 * src2 , const tjs_uint8 * rule , const tjs_uint32 * table , tjs_int len , tjs_int src1lv , tjs_int src2lv) { return TVPUnivTransBlend_switch_a(dest, src1, src2, rule, table, len, src1lv, src2lv); } static void __stdcall TVP_Stub_96fd614457f06499a430b0c6e0e8a941(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color) { return TVPApplyColorMap(dest, src, len, color); } static void __stdcall TVP_Stub_d6e36d304ff7253088ab4bc1aaf13a98(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPApplyColorMap_o(dest, src, len, color, opa); } static void __stdcall TVP_Stub_eddacf49735189e23d9d49831851ffdb(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color) { return TVPApplyColorMap65(dest, src, len, color); } static void __stdcall TVP_Stub_20275a5de4aef464b85d3f6db2800063(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPApplyColorMap65_o(dest, src, len, color, opa); } static void __stdcall TVP_Stub_872d1c626e6d4e3d5e86a257f0b14536(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color) { return TVPApplyColorMap_HDA(dest, src, len, color); } static void __stdcall TVP_Stub_a7ebb70cdec339f26c2ea7fd9a471b88(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPApplyColorMap_HDA_o(dest, src, len, color, opa); } static void __stdcall TVP_Stub_d748ffef5cde2a6a3333e75b7fa3fb49(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color) { return TVPApplyColorMap65_HDA(dest, src, len, color); } static void __stdcall TVP_Stub_15e1fe0e6230e7b60e216e266f927f7b(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPApplyColorMap65_HDA_o(dest, src, len, color, opa); } static void __stdcall TVP_Stub_f8179eafd0cbe8116874310519207dc0(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color) { return TVPApplyColorMap_d(dest, src, len, color); } static void __stdcall TVP_Stub_accbc3bed3223d552de2723366cfc2b6(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color) { return TVPApplyColorMap65_d(dest, src, len, color); } static void __stdcall TVP_Stub_e2c3e74d2a20a601c1f393348f58aeb2(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color) { return TVPApplyColorMap_a(dest, src, len, color); } static void __stdcall TVP_Stub_e0163a6ca3397c2e71715132cccefa1d(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color) { return TVPApplyColorMap65_a(dest, src, len, color); } static void __stdcall TVP_Stub_2c3ea1ea88799dfde81025bf1959333a(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPApplyColorMap_do(dest, src, len, color, opa); } static void __stdcall TVP_Stub_a6bb56b3f4b7a89fe78d63956a0f444c(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPApplyColorMap65_do(dest, src, len, color, opa); } static void __stdcall TVP_Stub_09a81ac18a121d8fbb67285a081bf9c6(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPApplyColorMap_ao(dest, src, len, color, opa); } static void __stdcall TVP_Stub_46fdfe0f5369bf234c3ed60a43947d9d(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPApplyColorMap65_ao(dest, src, len, color, opa); } static void __stdcall TVP_Stub_d866cb6c8a47444bbac60eeffbfc6d96(tjs_uint32 * dest , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPConstColorAlphaBlend(dest, len, color, opa); } static void __stdcall TVP_Stub_7b5718fc67458089c685dbb900126890(tjs_uint32 * dest , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPConstColorAlphaBlend_d(dest, len, color, opa); } static void __stdcall TVP_Stub_5713dfe9525662357d3819229e0204c2(tjs_uint32 * dest , tjs_int len , tjs_uint32 color , tjs_int opa) { return TVPConstColorAlphaBlend_a(dest, len, color, opa); } static void __stdcall TVP_Stub_8954a6b4a7f8b378c2af16a00d5059b0(tjs_uint32 * dest , tjs_int len , tjs_int strength) { return TVPRemoveConstOpacity(dest, len, strength); } static void __stdcall TVP_Stub_2ed4faa38db6f3dee0dea18ebe973d35(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len) { return TVPRemoveOpacity(dest, src, len); } static void __stdcall TVP_Stub_d0338dedb0af532d22f2075a85373548(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_int strength) { return TVPRemoveOpacity_o(dest, src, len, strength); } static void __stdcall TVP_Stub_583d57c3bb9491f8f9904c266d3f52e8(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len) { return TVPRemoveOpacity65(dest, src, len); } static void __stdcall TVP_Stub_8ac206da43e322eb8e34fce2b0959656(tjs_uint32 * dest , const tjs_uint8 * src , tjs_int len , tjs_int strength) { return TVPRemoveOpacity65_o(dest, src, len, strength); } static void __stdcall TVP_Stub_14f5f97d90bd8da89b68d035367f4ba4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPAddBlend(dest, src, len); } static void __stdcall TVP_Stub_ac3b21181ef4c1be73cf5e0edb4e1a8f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPAddBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_1d7d97509292a4ca9269f2539dcc70fd(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPAddBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_c4033f54a99517783b8d6ad23c90aeed(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPAddBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_f19e38d48755c971fc35408ac65562fa(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPSubBlend(dest, src, len); } static void __stdcall TVP_Stub_e01204e226d8aa9520b3620b68da6196(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPSubBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_b50000da98f1257cf789fc63fb1fda02(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPSubBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_c55f38b1a7623646aa5cc45d4f4f479b(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPSubBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_983d270549ec0e83e2a863b43e1e6f70(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPMulBlend(dest, src, len); } static void __stdcall TVP_Stub_b48d779dc6a881c67c5f8fa12655aa28(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPMulBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_d3967c6e24d0c4ad107a03c1cadd57b1(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPMulBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_6b6f416b5725a7cafb4774ffc3a00f10(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPMulBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_bc7fc5dfa228152a09d2230823c2fe71(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPColorDodgeBlend(dest, src, len); } static void __stdcall TVP_Stub_a1cb941317b947beb88e29fa8d46a2be(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPColorDodgeBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_8e185e82bb27a7fb40f0b08f560a57e9(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPColorDodgeBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_4b7b264b61ee0eea68213934217f5865(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPColorDodgeBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_e872f12593d6853ebdffebbb5d003c10(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPDarkenBlend(dest, src, len); } static void __stdcall TVP_Stub_e86fcf60fa658129d937de3728d3c432(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPDarkenBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_350741a7398a187628866f5b397c7a99(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPDarkenBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_3b5a3e187077b0b5eac9a040c99dd9e7(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPDarkenBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_2d9b2bb2cd57220048fe170f1e960cb7(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPLightenBlend(dest, src, len); } static void __stdcall TVP_Stub_260624e275a20115e8861eb7b0383971(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPLightenBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_15b31724287dbbecb775b2e46dc35fb9(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPLightenBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_ff652293eef07b5a7ec4f372e5504e2c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPLightenBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_99b773033e9a2c631b483d4d0e3881f8(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPScreenBlend(dest, src, len); } static void __stdcall TVP_Stub_3787960fc29b8545629d894ff46d4641(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPScreenBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_3fc76257bb1639de4bfa0c0fcedf9c4a(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPScreenBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_292ee2eeb8131e34368ba9ee144b737a(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPScreenBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_ec144655bc61bfa2c6e9505cc1a0a298(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchCopy(dest, destlen, src, srcstart, srcstep); } static void __stdcall TVP_Stub_230218bdabfc34178a8306a54276a3c8(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src1 , const tjs_uint32 * src2 , tjs_int blend_y , tjs_int srcstart , tjs_int srcstep) { return TVPInterpStretchCopy(dest, destlen, src1, src2, blend_y, srcstart, srcstep); } static void __stdcall TVP_Stub_617dfb046aaf40078ee76715fa4756af(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src) { return TVPFastLinearInterpH2F(dest, destlen, src); } static void __stdcall TVP_Stub_8116bb2b26dcafd9fefca76e9f1d9b24(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src) { return TVPFastLinearInterpH2B(dest, destlen, src); } static void __stdcall TVP_Stub_12962f857563cd39b3cb1f9894775cc7(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src0 , const tjs_uint32 * src1) { return TVPFastLinearInterpV2(dest, destlen, src0, src1); } static void __stdcall TVP_Stub_50c0d25cd9af311a5fb0aca78f691c3b(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int srcstart , tjs_int srcstep) { return TVPStretchColorCopy(dest, destlen, src, srcstart, srcstep); } static void __stdcall TVP_Stub_6c37a1ccda816c4fbab4f0117ca75e8a(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransCopy(dest, destlen, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_e21c21762dd0e36d6f7d2cedaac97383(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPInterpLinTransCopy(dest, destlen, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_487ee86557f94113db9a981e08d29caa(tjs_uint32 * dest , tjs_int destlen , const tjs_uint32 * src , tjs_int sx , tjs_int sy , tjs_int stepx , tjs_int stepy , tjs_int srcpitch) { return TVPLinTransColorCopy(dest, destlen, src, sx, sy, stepx, stepy, srcpitch); } static void __stdcall TVP_Stub_dfdfe0e494845bf484612cc97145f85c(tjs_uint32 * dest , tjs_int len , tjs_uint32 key) { return TVPMakeAlphaFromKey(dest, len, key); } static void __stdcall TVP_Stub_e74dc11dbd56fb450eed1388a65d3102(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPCopyMask(dest, src, len); } static void __stdcall TVP_Stub_6981c02247de5799ea7dfbd79fdc208d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPCopyColor(dest, src, len); } static void __stdcall TVP_Stub_7c559043315f6ecd7a86ec7d8d820f6d(tjs_uint32 * main , const tjs_uint8 * mask , tjs_int len) { return TVPBindMaskToMain(main, mask, len); } static void __stdcall TVP_Stub_3a8b6aca73c83d6fc9ce813661ec734d(tjs_uint32 * dest , tjs_int len , tjs_uint32 value) { return TVPFillARGB(dest, len, value); } static void __stdcall TVP_Stub_20d7ce65e240b745b10616bb5da1f897(tjs_uint32 * dest , tjs_int len , tjs_uint32 value) { return TVPFillARGB_NC(dest, len, value); } static void __stdcall TVP_Stub_f4d1217249674ac9274d358c381afc0b(tjs_uint32 * dest , tjs_int len , tjs_uint32 color) { return TVPFillColor(dest, len, color); } static void __stdcall TVP_Stub_ca77323bbe361f88f68536018fa94c50(tjs_uint32 * dest , tjs_int len , tjs_uint32 mask) { return TVPFillMask(dest, len, mask); } static void __stdcall TVP_Stub_17983ecc7e7fe370bce664281a84c948(tjs_uint16 * dest , const tjs_uint32 * addline , const tjs_uint32 * subline , tjs_int len) { return TVPAddSubVertSum16(dest, addline, subline, len); } static void __stdcall TVP_Stub_61a2f61030362903d00ba21a3cebecdd(tjs_uint16 * dest , const tjs_uint32 * addline , const tjs_uint32 * subline , tjs_int len) { return TVPAddSubVertSum16_d(dest, addline, subline, len); } static void __stdcall TVP_Stub_e9f985403dbd18540d8230a2af6ed76b(tjs_uint32 * dest , const tjs_uint32 * addline , const tjs_uint32 * subline , tjs_int len) { return TVPAddSubVertSum32(dest, addline, subline, len); } static void __stdcall TVP_Stub_be0523c9a72ba26cb4bfa3cb188cacf6(tjs_uint32 * dest , const tjs_uint32 * addline , const tjs_uint32 * subline , tjs_int len) { return TVPAddSubVertSum32_d(dest, addline, subline, len); } static void __stdcall TVP_Stub_8ac7cf651223c8ba53df90cf4f3d3bbc(tjs_uint32 * dest , tjs_uint16 * sum , const tjs_uint16 * add , const tjs_uint16 * sub , tjs_int n , tjs_int len) { return TVPDoBoxBlurAvg16(dest, sum, add, sub, n, len); } static void __stdcall TVP_Stub_873e73aa35096ad4c684d394a10135a6(tjs_uint32 * dest , tjs_uint16 * sum , const tjs_uint16 * add , const tjs_uint16 * sub , tjs_int n , tjs_int len) { return TVPDoBoxBlurAvg16_d(dest, sum, add, sub, n, len); } static void __stdcall TVP_Stub_3342548f105147c86019ae31ece01d4e(tjs_uint32 * dest , tjs_uint32 * sum , const tjs_uint32 * add , const tjs_uint32 * sub , tjs_int n , tjs_int len) { return TVPDoBoxBlurAvg32(dest, sum, add, sub, n, len); } static void __stdcall TVP_Stub_607ee0956cbb16b2afb7cb2227aa6267(tjs_uint32 * dest , tjs_uint32 * sum , const tjs_uint32 * add , const tjs_uint32 * sub , tjs_int n , tjs_int len) { return TVPDoBoxBlurAvg32_d(dest, sum, add, sub, n, len); } static void __stdcall TVP_Stub_816d84c86e86d5e7c0018d551e741e4f(tjs_uint8 * line1 , tjs_uint8 * line2 , tjs_int len) { return TVPSwapLine8(line1, line2, len); } static void __stdcall TVP_Stub_985fcda0141eb3b4c6bd8342e947f130(tjs_uint32 * line1 , tjs_uint32 * line2 , tjs_int len) { return TVPSwapLine32(line1, line2, len); } static void __stdcall TVP_Stub_d00e4f9e493334d2f65ea379ff03d717(tjs_uint8 * pixels , tjs_int len) { return TVPReverse8(pixels, len); } static void __stdcall TVP_Stub_0c246e6c7c8798e4c10d2bbfc66326c9(tjs_uint32 * pixels , tjs_int len) { return TVPReverse32(pixels, len); } static void __stdcall TVP_Stub_501015843a83368b3ff1c7c9ef5f3bcb(tjs_uint32 * dest , tjs_int len) { return TVPDoGrayScale(dest, len); } static void __stdcall TVP_Stub_61d5fc5a060f346752a3a8b6886d17bc(tTVPGLGammaAdjustTempData * temp , const tTVPGLGammaAdjustData * data) { return TVPInitGammaAdjustTempData(temp, data); } static void __stdcall TVP_Stub_0debe3e1caf0f57572a59917851676d3(tTVPGLGammaAdjustTempData * temp) { return TVPUninitGammaAdjustTempData(temp); } static void __stdcall TVP_Stub_ee3a36682f48639166ba04a19fe1b332(tjs_uint32 * dest , tjs_int len , tTVPGLGammaAdjustTempData * temp) { return TVPAdjustGamma(dest, len, temp); } static void __stdcall TVP_Stub_4d99b9e38121251b40a90cd2bd5fea63(tjs_uint32 * dest , tjs_int len , tTVPGLGammaAdjustTempData * temp) { return TVPAdjustGamma_a(dest, len, temp); } static void __stdcall TVP_Stub_f1509827696ebf5627bee1a45d675fb8(tjs_uint8 * dest , const tjs_uint8 * src , tjs_int len , tjs_int level) { return TVPChBlurMulCopy65(dest, src, len, level); } static void __stdcall TVP_Stub_bbb625e23229350453161810c41419dd(tjs_uint8 * dest , const tjs_uint8 * src , tjs_int len , tjs_int level) { return TVPChBlurAddMulCopy65(dest, src, len, level); } static void __stdcall TVP_Stub_489a6aae30de0feff5d3c5fbd42ae325(tjs_uint8 * dest , tjs_int destpitch , tjs_int destwidth , tjs_int destheight , const tjs_uint8 * src , tjs_int srcpitch , tjs_int srcwidth , tjs_int srcheight , tjs_int blurwidth , tjs_int blurlevel) { return TVPChBlurCopy65(dest, destpitch, destwidth, destheight, src, srcpitch, srcwidth, srcheight, blurwidth, blurlevel); } static void __stdcall TVP_Stub_6b9a349305f8c689dcfdbcea2566769c(tjs_uint8 * dest , const tjs_uint8 * src , tjs_int len , tjs_int level) { return TVPChBlurMulCopy(dest, src, len, level); } static void __stdcall TVP_Stub_6320d208ce1a570aca52c3cdf7421f7c(tjs_uint8 * dest , const tjs_uint8 * src , tjs_int len , tjs_int level) { return TVPChBlurAddMulCopy(dest, src, len, level); } static void __stdcall TVP_Stub_0f83f0459badd1cd352041b9243d712f(tjs_uint8 * dest , tjs_int destpitch , tjs_int destwidth , tjs_int destheight , const tjs_uint8 * src , tjs_int srcpitch , tjs_int srcwidth , tjs_int srcheight , tjs_int blurwidth , tjs_int blurlevel) { return TVPChBlurCopy(dest, destpitch, destwidth, destheight, src, srcpitch, srcwidth, srcheight, blurwidth, blurlevel); } static void __stdcall TVP_Stub_186a94b2fed609ed2d2a7ac1a2bed87f(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal) { return TVPBLExpand1BitTo8BitPal(dest, buf, len, pal); } static void __stdcall TVP_Stub_bde8efb9971664f2b52fe912745e2791(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len) { return TVPBLExpand1BitTo8Bit(dest, buf, len); } static void __stdcall TVP_Stub_386d6fa5cb73e3519b62d20470e5414b(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal) { return TVPBLExpand1BitTo32BitPal(dest, buf, len, pal); } static void __stdcall TVP_Stub_c61f97ec3d99bdbb23afe93870001bbf(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal) { return TVPBLExpand4BitTo8BitPal(dest, buf, len, pal); } static void __stdcall TVP_Stub_f92821f2b23662c6f1256511a626cd3f(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len) { return TVPBLExpand4BitTo8Bit(dest, buf, len); } static void __stdcall TVP_Stub_76b0732e3e2886897d5f26b4b0545dee(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal) { return TVPBLExpand4BitTo32BitPal(dest, buf, len, pal); } static void __stdcall TVP_Stub_903ed11ef3863850e837bd4b3b1d61a1(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal) { return TVPBLExpand8BitTo8BitPal(dest, buf, len, pal); } static void __stdcall TVP_Stub_2661124b39595ffafe2fb0bfb7bd2efc(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len , const tjs_uint32 * pal) { return TVPBLExpand8BitTo32BitPal(dest, buf, len, pal); } static void __stdcall TVP_Stub_d0b7170e54398c2f9d27dcc513c4cf46(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len) { return TVPExpand8BitTo32BitGray(dest, buf, len); } static void __stdcall TVP_Stub_31bdd2a1eed3785c1422fab5ea6b3ce7(tjs_uint8 * dest , const tjs_uint16 * buf , tjs_int len) { return TVPBLConvert15BitTo8Bit(dest, buf, len); } static void __stdcall TVP_Stub_dbc300d1dadc1a60cb0dcadfb92f1aee(tjs_uint32 * dest , const tjs_uint16 * buf , tjs_int len) { return TVPBLConvert15BitTo32Bit(dest, buf, len); } static void __stdcall TVP_Stub_1d4d9f8bdf55bd4c78abd90656af0364(tjs_uint8 * dest , const tjs_uint8 * buf , tjs_int len) { return TVPBLConvert24BitTo8Bit(dest, buf, len); } static void __stdcall TVP_Stub_5c7049e712e84b40ac05942421202de5(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len) { return TVPBLConvert24BitTo32Bit(dest, buf, len); } static void __stdcall TVP_Stub_5dca8992bb340d70ba65ddab65c28371(tjs_uint32 * dest , const tjs_uint8 * buf , tjs_int len) { return TVPConvert24BitTo32Bit(dest, buf, len); } static void __stdcall TVP_Stub_85f1f38f783ebfcf638f3c443bc9b204(tjs_uint8 * dest , const tjs_uint32 * buf , tjs_int len) { return TVPBLConvert32BitTo8Bit(dest, buf, len); } static void __stdcall TVP_Stub_7d61d143884bfa4b6c50dae11c2b659f(tjs_uint32 * dest , const tjs_uint32 * buf , tjs_int len) { return TVPBLConvert32BitTo32Bit_NoneAlpha(dest, buf, len); } static void __stdcall TVP_Stub_793a2ad7ad3411be3670576a8e6ddcf8(tjs_uint32 * dest , const tjs_uint32 * buf , tjs_int len) { return TVPBLConvert32BitTo32Bit_MulAddAlpha(dest, buf, len); } static void __stdcall TVP_Stub_68d8eec33254f1684e53bbc0aa8b2466(tjs_uint32 * dest , const tjs_uint32 * buf , tjs_int len) { return TVPBLConvert32BitTo32Bit_AddAlpha(dest, buf, len); } static void __stdcall TVP_Stub_b09652d2197b29f7d38aff0298c69f17(tjs_uint16 * dest , const tjs_uint32 * src , tjs_int len , tjs_int xofs , tjs_int yofs) { return TVPDither32BitTo16Bit565(dest, src, len, xofs, yofs); } static void __stdcall TVP_Stub_be7db03ddcf1886cb7233e58f19c8c77(tjs_uint16 * dest , const tjs_uint32 * src , tjs_int len , tjs_int xofs , tjs_int yofs) { return TVPDither32BitTo16Bit555(dest, src, len, xofs, yofs); } static void __stdcall TVP_Stub_b4c8fedc1ffbe30d9703cb2b8d3c0e7b(tjs_uint8 * dest , const tjs_uint32 * src , tjs_int len , tjs_int xofs , tjs_int yofs) { return TVPDither32BitTo8Bit(dest, src, len, xofs, yofs); } static void __stdcall TVP_Stub_77efef3b4ffc0cb577b76304e06e39f3(tjs_uint8 * outp , const tjs_uint8 * upper , tjs_uint8 * const * buf , tjs_int width) { return TVPTLG5ComposeColors3To4(outp, upper, buf, width); } static void __stdcall TVP_Stub_0e55187bde599d6585eaabd2c4ac3f02(tjs_uint8 * outp , const tjs_uint8 * upper , tjs_uint8 * const * buf , tjs_int width) { return TVPTLG5ComposeColors4To4(outp, upper, buf, width); } static tjs_int __stdcall TVP_Stub_f72e3fc3b97a9141b6f516f5e53bf9b8(tjs_uint8 * out , const tjs_uint8 * in , tjs_int insize , tjs_uint8 * text , tjs_int initialr) { return TVPTLG5DecompressSlide(out, in, insize, text, initialr); } static void __stdcall TVP_Stub_e7a1ac237f00bb6320d0e0ac7e6d51c6(tjs_int8 * pixelbuf , tjs_int pixel_count , tjs_uint8 * bit_pool) { return TVPTLG6DecodeGolombValuesForFirst(pixelbuf, pixel_count, bit_pool); } static void __stdcall TVP_Stub_d87682f6d691350878077bd101b7f0fc(tjs_int8 * pixelbuf , tjs_int pixel_count , tjs_uint8 * bit_pool) { return TVPTLG6DecodeGolombValues(pixelbuf, pixel_count, bit_pool); } static void __stdcall TVP_Stub_d7ae155eaabd8e65d6b4d356fe4af496(tjs_uint32 * prevline , tjs_uint32 * curline , tjs_int width , tjs_int start_block , tjs_int block_limit , tjs_uint8 * filtertypes , tjs_int skipblockbytes , tjs_uint32 * in , tjs_uint32 initialp , tjs_int oddskip , tjs_int dir) { return TVPTLG6DecodeLineGeneric(prevline, curline, width, start_block, block_limit, filtertypes, skipblockbytes, in, initialp, oddskip, dir); } static void __stdcall TVP_Stub_be3a1844ea6af533bd4e7b0a76c826a1(tjs_uint32 * prevline , tjs_uint32 * curline , tjs_int width , tjs_int block_count , tjs_uint8 * filtertypes , tjs_int skipblockbytes , tjs_uint32 * in , tjs_uint32 initialp , tjs_int oddskip , tjs_int dir) { return TVPTLG6DecodeLine(prevline, curline, width, block_count, filtertypes, skipblockbytes, in, initialp, oddskip, dir); } static void __stdcall TVP_Stub_aa531d2c3c87f456e48a14722faa1c1f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsAlphaBlend(dest, src, len); } static void __stdcall TVP_Stub_6889cd886e1c2e7faf541528636c16c3(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsAlphaBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_5d9266e6a8a154fe4ba80b0995e109ab(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsAlphaBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_a7dc19b023737979ad1ae1ae01d560d2(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsAlphaBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_d20444b7a6243d668a0d3956d95af510(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsAddBlend(dest, src, len); } static void __stdcall TVP_Stub_1458dec9eee36816c8002d4049840355(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsAddBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_21137ff5351245b1611852301b7f5796(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsAddBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_c07fc4e45fc2dc44d839c5e012d0be60(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsAddBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_6815b962a3122ae967284239932cc656(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsSubBlend(dest, src, len); } static void __stdcall TVP_Stub_e96cccbe1f16b0fb74673f2ec3343ff8(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsSubBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_e8cd7494f919b18a992cb8c2722b2bf0(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsSubBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_990fdefcafc0de5e8e1f502c1b341e44(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsSubBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_de5d83ba307e822825062377fb76c2ba(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsMulBlend(dest, src, len); } static void __stdcall TVP_Stub_5e28bcc0f5ad6a038eb5a6535b56386c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsMulBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_e33419e8ede4bb501ab1787cf17c7ca5(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsMulBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_1cd7cb9580c0cf723dea402b85a720b1(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsMulBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_d18ca17fad389ff60ce3caa769083798(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsScreenBlend(dest, src, len); } static void __stdcall TVP_Stub_0a959a5ff02530a8eb122e7e1f8ceed3(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsScreenBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_a4774ea559e64b4667b3845f8540d207(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsScreenBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_52eae3e8106494bfa604c15492ecb9f4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsScreenBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_882f458df5e05bb9ab2222e79f6c81cf(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsOverlayBlend(dest, src, len); } static void __stdcall TVP_Stub_6069a18bf7d3f394c230cdcf2f574ef4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsOverlayBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_75b60565caf44027cc52b2b5cf6b0ea3(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsOverlayBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_9d735149c3ad586363895f76645abf2e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsOverlayBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_ea5168fae254acdd8c8db6f1f3d2da03(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsHardLightBlend(dest, src, len); } static void __stdcall TVP_Stub_f5a42bd5239e1a0be29f92eb838d2c8c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsHardLightBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_7cc8cd9f415b183b42c546635aeade7f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsHardLightBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_ad2fefa53e05528f9c1fe29d27db0f37(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsHardLightBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_f3e06fed4c82a9bd1b53252abaf50847(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsSoftLightBlend(dest, src, len); } static void __stdcall TVP_Stub_960db7ea36202bf7ec3bf6b767cc045e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsSoftLightBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_7bf5d357eb52dd206a269b54c8136e0e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsSoftLightBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_ba1c9b771c5cdb725128de684af3c9ca(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsSoftLightBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_69cc6311196adc134fd153c4c5346bc5(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsColorDodgeBlend(dest, src, len); } static void __stdcall TVP_Stub_8ed68f8e79efe1c767f92e7d92eb8b54(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsColorDodgeBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_60da1e9ec15b251ff18ddcdf8a3e93e0(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsColorDodgeBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_ef47304bad87a036e38f0319b48c1f6e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsColorDodgeBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_182d19020e4e2d5cd1462d7c8ef24d1f(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsColorDodge5Blend(dest, src, len); } static void __stdcall TVP_Stub_9e1fa429a92a5c99d397a06c20fd6705(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsColorDodge5Blend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_74ac7c291299eb928aa4c2899df5567e(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsColorDodge5Blend_HDA(dest, src, len); } static void __stdcall TVP_Stub_fb645d9ec0ef3fd2aba2b762ef6b9a15(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsColorDodge5Blend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_f988626275257574050ac789f9060a3b(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsColorBurnBlend(dest, src, len); } static void __stdcall TVP_Stub_1831064ed23493cef407648763ba4d69(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsColorBurnBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_305390c94750daa7124db3ff6e77931c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsColorBurnBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_4fb384a391bfcf6a3a2932661d3051aa(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsColorBurnBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_305537c4820e23cf217a15efb56dba1c(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsLightenBlend(dest, src, len); } static void __stdcall TVP_Stub_aacf83677ca7df75117f7bafa7a53791(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsLightenBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_d14b922fefc6c07aa536b94762579fe5(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsLightenBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_00fd650a79c603bdeb2f8e36f667a782(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsLightenBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_a36ee133c07c30185b0bbc6375954e88(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsDarkenBlend(dest, src, len); } static void __stdcall TVP_Stub_dc657ecacf8e578870314427216864d9(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsDarkenBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_e79d02b58a8bfdee439bc0694d7edd6d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsDarkenBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_6b7537b66b71d27384bea45bc2bf24b4(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsDarkenBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_b3456dbad652b52f5bce1889b6f4d0ef(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsDiffBlend(dest, src, len); } static void __stdcall TVP_Stub_9a50803a03e1ccb60120dff8b92ecdcd(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsDiffBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_0f6b3940dc72e3e56cd15216b53b9126(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsDiffBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_23b647f1c825e214a7465de3ebe9968d(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsDiffBlend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_8ec96bc7b777180f23e1a2e43bf9a413(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsDiff5Blend(dest, src, len); } static void __stdcall TVP_Stub_cffd45014652659638d59abe11daf3be(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsDiff5Blend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_a784285a35b1bc76bb367305b5099e35(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsDiff5Blend_HDA(dest, src, len); } static void __stdcall TVP_Stub_03773751329896facf2003ab79bbc475(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsDiff5Blend_HDA_o(dest, src, len, opa); } static void __stdcall TVP_Stub_923884216edf134d07d8e70f8f57e827(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsExclusionBlend(dest, src, len); } static void __stdcall TVP_Stub_e48798dc69498f80b6633bb405eda6eb(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsExclusionBlend_o(dest, src, len, opa); } static void __stdcall TVP_Stub_998a5e1aa5cd85689795348fc540a655(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len) { return TVPPsExclusionBlend_HDA(dest, src, len); } static void __stdcall TVP_Stub_5f6d263c0d48d03f6eb0dc44c9dd0be2(tjs_uint32 * dest , const tjs_uint32 * src , tjs_int len , tjs_int opa) { return TVPPsExclusionBlend_HDA_o(dest, src, len, opa); } #include "tvpgl_ia32_intf.h" #include "TVPVideoOverlay.h" static void __stdcall TVP_Stub_bf363ba3d5b54df9d6df35a518deb6b0(const ttstr & name , void * guid , tTVPCreateDSFilter splitter , tTVPCreateDSFilter video , tTVPCreateDSFilter audio , void * formatdata) { return TVPRegisterDSVideoCodec(name, guid, splitter, video, audio, formatdata); } static void __stdcall TVP_Stub_6cc8a24cc7ce23179d1d4ccab7a8c97b(const ttstr & name , void * guid , tTVPCreateDSFilter splitter , tTVPCreateDSFilter video , tTVPCreateDSFilter audio , void * formatdata) { return TVPUnregisterDSVideoCodec(name, guid, splitter, video, audio, formatdata); } #include /* function table is pretty large; is compressed via zlib */ static tjs_uint8 compressed_functable[] = { 0x78, 0x9c, 0xd5, 0x5d, 0x6b, 0x73, 0xdb, 0xba, 0xd1, 0xce, 0x4f, 0x49, 0x3f, 0x34, 0xa3, 0x93, 0xe3, 0x4e, 0x27, 0x4e, 0xec, 0x49, 0x3b, 0xe7, 0x9c, 0x19, 0x5d, 0x7c, 0x51, 0x6b, 0x3b, 0x6a, 0xa4, 0x38, 0x9d, 0x76, 0xde, 0x7a, 0x60, 0x12, 0xb6, 0x78, 0x42, 0x11, 0x2a, 0x49, 0x39, 0x56, 0xa7, 0x73, 0x7e, 0x7b, 0x71, 0xe1, 0x05, 0x77, 0x82, 0x04, 0x94, 0xcc, 0xfb, 0xc5, 0xb6, 0x88, 0xdd, 0x67, 0x17, 0x8b, 0xc5, 0x62, 0xb1, 0x00, 0xe5, 0x27, 0x94, 0xc4, 0x2f, 0xcb, 0xd5, 0x5f, 0x96, 0xb7, 0x20, 0x4f, 0x40, 0x56, 0xfe, 0xf9, 0xcf, 0xd3, 0x35, 0xc8, 0x1e, 0xe1, 0x34, 0x45, 0xc5, 0x2e, 0x87, 0x1f, 0xee, 0x7f, 0x5d, 0xad, 0x93, 0x62, 0x94, 0x60, 0x8a, 0x59, 0x52, 0x6c, 0x41, 0x19, 0xad, 0x8f, 0x5f, 0xbe, 0xfe, 0xe1, 0x85, 0xc0, 0xc2, 0x7d, 0x18, 0x59, 0x9a, 0x22, 0x94, 0x15, 0x25, 0x2f, 0xec, 0xe5, 0x2b, 0x0b, 0xb5, 0xbb, 0x48, 0x89, 0xf2, 0xc8, 0x9d, 0xb3, 0xd2, 0xe8, 0xd7, 0xe2, 0x2e, 0x5a, 0x83, 0xdc, 0x85, 0x14, 0x3f, 0x59, 0x96, 0x79, 0x92, 0x3d, 0x5a, 0x75, 0x6f, 0x71, 0x33, 0x57, 0x60, 0x4c, 0xbb, 0x4b, 0xb2, 0xf2, 0x3d, 0xd6, 0xbf, 0xfe, 0xdb, 0xc2, 0x74, 0x8f, 0x50, 0x6a, 0x69, 0x26, 0x08, 0x18, 0xe0, 0xed, 0x71, 0x37, 0xcd, 0xe9, 0xbb, 0x0e, 0x9a, 0x1c, 0x02, 0x9b, 0x28, 0x45, 0x7d, 0xa5, 0xb3, 0xbf, 0xbd, 0x34, 0xfa, 0xc7, 0x6a, 0xbf, 0x85, 0xa2, 0xf7, 0x91, 0x27, 0x98, 0xe6, 0x49, 0x75, 0xcb, 0x14, 0x82, 0x5c, 0xe4, 0xae, 0x7c, 0xf4, 0xe5, 0x2b, 0x91, 0x72, 0x5c, 0x60, 0xaf, 0x85, 0x51, 0xdd, 0xac, 0x45, 0x5b, 0x21, 0x46, 0x23, 0xbb, 0x2b, 0xda, 0xc2, 0x1c, 0x94, 0x28, 0x7f, 0x29, 0xf9, 0x90, 0x01, 0x84, 0xb9, 0x02, 0x01, 0xa9, 0xfa, 0xff, 0x16, 0xd3, 0x8a, 0x44, 0x17, 0xb0, 0xbc, 0x4c, 0x68, 0xbf, 0xb5, 0x5a, 0x44, 0x25, 0x34, 0xb5, 0xcd, 0xb3, 0x12, 0x3e, 0xc2, 0xdc, 0xd0, 0xfa, 0x11, 0x0f, 0x8b, 0xa8, 0xbd, 0x6c, 0x87, 0xa6, 0x2f, 0x3f, 0xeb, 0x67, 0x9e, 0xc6, 0xc6, 0x68, 0xbb, 0xff, 0x08, 0x1f, 0x3a, 0x27, 0xaa, 0x45, 0x92, 0x6d, 0xee, 0xc9, 0x6c, 0x4b, 0x58, 0x56, 0xa3, 0x10, 0x84, 0xcb, 0x3a, 0xef, 0x2d, 0x2a, 0xab, 0x1e, 0x35, 0x80, 0xb3, 0x0a, 0x0a, 0x43, 0x84, 0x52, 0x1f, 0x70, 0xe7, 0xec, 0x08, 0x44, 0xdd, 0x9c, 0xfa, 0x68, 0xe7, 0xc4, 0xa7, 0x8b, 0x66, 0x16, 0x46, 0x25, 0x4a, 0xd9, 0x0c, 0xa2, 0x0d, 0x59, 0x0e, 0x76, 0xb8, 0xad, 0xe6, 0x49, 0x1f, 0x41, 0x2c, 0xa6, 0xa9, 0x13, 0x20, 0x45, 0x8f, 0x49, 0x04, 0x52, 0x94, 0xc3, 0x7f, 0xef, 0xf0, 0xf4, 0x72, 0x9c, 0x36, 0x15, 0x17, 0xc8, 0xe2, 0x5e, 0x6c, 0x8d, 0x4e, 0xff, 0x75, 0x9e, 0xa0, 0x49, 0x16, 0xe5, 0x70, 0x03, 0x0d, 0xe1, 0x24, 0x86, 0xb6, 0xd6, 0x46, 0xdc, 0xbf, 0x9c, 0xc5, 0x35, 0x2c, 0xaf, 0xfa, 0xb3, 0xfc, 0xf2, 0x8b, 0x33, 0x4f, 0x7e, 0x9f, 0x94, 0xc5, 0x3a, 0x79, 0x28, 0x87, 0x99, 0xef, 0xa7, 0x9f, 0xfa, 0x6b, 0xf7, 0xfb, 0xfe, 0x2c, 0x7f, 0x74, 0x1f, 0xa5, 0x38, 0x79, 0x1a, 0xd6, 0x95, 0xd7, 0xce, 0x32, 0x2a, 0x9f, 0xcb, 0x90, 0x7e, 0xb0, 0xb1, 0x45, 0x4d, 0x4d, 0x25, 0xca, 0x76, 0x9b, 0x7b, 0xc3, 0xba, 0x12, 0xd1, 0xe4, 0xaf, 0x48, 0x1e, 0x33, 0xbb, 0x0f, 0xfd, 0xa1, 0xbf, 0xfd, 0x7e, 0x34, 0xb0, 0x38, 0xa4, 0x03, 0x2f, 0x29, 0xe3, 0x0b, 0x12, 0x4e, 0xc4, 0xe6, 0x1b, 0x94, 0x6f, 0x40, 0x3a, 0x45, 0x9b, 0x2d, 0xc0, 0x0b, 0xbd, 0x0e, 0xde, 0xc8, 0x8a, 0x17, 0x8a, 0x08, 0xe6, 0x59, 0x00, 0x5e, 0x12, 0x86, 0xa3, 0x92, 0xae, 0xc7, 0xbd, 0x50, 0x2e, 0x70, 0x14, 0x2a, 0x61, 0xbe, 0xc2, 0x26, 0xef, 0xc7, 0x78, 0x95, 0x94, 0x65, 0x3a, 0x84, 0x71, 0x5e, 0xcc, 0x71, 0x03, 0xc8, 0x22, 0xf8, 0xe1, 0x41, 0x5d, 0x0d, 0x2a, 0x36, 0x69, 0x15, 0xd5, 0xe7, 0x56, 0xa3, 0x5e, 0xd4, 0x37, 0x68, 0x1c, 0xc7, 0x24, 0xb1, 0xe8, 0xc5, 0x45, 0x37, 0x1e, 0xbd, 0x39, 0x14, 0x59, 0xbd, 0x13, 0x46, 0x1b, 0x42, 0xbd, 0xcc, 0xcb, 0x00, 0x75, 0x22, 0xd8, 0x97, 0x43, 0x91, 0x25, 0x8f, 0x8a, 0x92, 0x4c, 0x9a, 0x25, 0x55, 0x79, 0x84, 0xd2, 0x37, 0x96, 0x62, 0xf6, 0xa3, 0xd7, 0xd8, 0xa0, 0x5e, 0x67, 0x65, 0xfa, 0x26, 0x4d, 0xad, 0x28, 0xd5, 0x10, 0x30, 0x2e, 0x6e, 0x58, 0xc4, 0xd1, 0xba, 0xa9, 0x3e, 0x5a, 0xb4, 0xf2, 0x74, 0xaa, 0x73, 0x84, 0xc4, 0xcb, 0x3b, 0x48, 0xaa, 0xd4, 0x82, 0xef, 0x0b, 0x99, 0xad, 0xb2, 0x92, 0x2c, 0xa3, 0xee, 0xd2, 0xca, 0x44, 0x65, 0x5a, 0xdb, 0xff, 0x6b, 0x9b, 0xa2, 0xdd, 0xfc, 0xaf, 0x5e, 0xf9, 0xf1, 0x7b, 0x8a, 0xff, 0x97, 0xa7, 0xf6, 0x7e, 0xec, 0xbf, 0xd3, 0x2f, 0x19, 0xce, 0xfc, 0x3f, 0x7b, 0xf2, 0xff, 0xe4, 0xc7, 0xfe, 0x8b, 0xa7, 0x74, 0x4f, 0xed, 0x0d, 0x09, 0x98, 0x3b, 0xff, 0x30, 0xfd, 0x9b, 0x6c, 0xae, 0x4e, 0xe9, 0x7b, 0xf4, 0xd8, 0xd3, 0xe0, 0xbf, 0xf7, 0x63, 0xff, 0xe3, 0x20, 0x76, 0x92, 0xed, 0xf9, 0xc9, 0x7d, 0xed, 0x39, 0x4b, 0x7a, 0x84, 0xa3, 0xdf, 0x7a, 0xd0, 0xfe, 0xc1, 0x4f, 0xad, 0x1f, 0x7b, 0x89, 0xea, 0x83, 0x6b, 0x51, 0x8b, 0x2e, 0x3e, 0xaf, 0x0d, 0x9c, 0x19, 0xfc, 0x3a, 0x2a, 0x92, 0xff, 0xc0, 0xbb, 0xd2, 0x9a, 0xa8, 0xc6, 0x30, 0x85, 0x25, 0x1c, 0x31, 0xa8, 0x1f, 0x3a, 0x21, 0x5f, 0xfe, 0xf3, 0xff, 0xdc, 0x51, 0x09, 0xb1, 0x2b, 0x70, 0x85, 0x7a, 0x54, 0xd3, 0xcb, 0x4b, 0xb7, 0x50, 0x87, 0x63, 0xab, 0xbc, 0x63, 0x2d, 0xb1, 0x3f, 0xfb, 0x51, 0x18, 0x64, 0x25, 0xf9, 0x38, 0x32, 0x35, 0xe8, 0x50, 0x7f, 0x53, 0xe8, 0x34, 0x9b, 0x94, 0x8a, 0xb6, 0x4e, 0x5f, 0x4c, 0xed, 0x1f, 0xf1, 0x70, 0x80, 0x02, 0x72, 0xa5, 0x3b, 0x0d, 0x11, 0x4e, 0xb7, 0xae, 0x60, 0xf6, 0x58, 0xae, 0x35, 0xe9, 0x59, 0x5d, 0xed, 0xd4, 0x72, 0xcd, 0x40, 0x09, 0x04, 0x97, 0x66, 0x59, 0x1b, 0x33, 0x4c, 0x5b, 0x34, 0xd4, 0x37, 0x98, 0x0a, 0x3c, 0x1a, 0x52, 0x4d, 0x9e, 0xd9, 0x05, 0x2b, 0x55, 0x7f, 0xac, 0x84, 0x99, 0x1b, 0x65, 0xf3, 0x60, 0xb2, 0x7b, 0x78, 0x80, 0x39, 0x33, 0x99, 0x59, 0xe7, 0x4a, 0x03, 0x07, 0x54, 0x69, 0x97, 0xe8, 0x64, 0xab, 0xa3, 0xc6, 0x25, 0x1d, 0x6c, 0x60, 0x25, 0xae, 0x97, 0x2f, 0xa1, 0xfd, 0xb7, 0x97, 0x86, 0x21, 0xac, 0x36, 0x15, 0x35, 0x9d, 0x43, 0xc1, 0xce, 0x91, 0x4f, 0x3b, 0x60, 0x2e, 0x5c, 0xcd, 0xe8, 0x35, 0x53, 0x40, 0x21, 0xff, 0x51, 0xaf, 0x9d, 0x23, 0x83, 0xe2, 0x79, 0x2e, 0x7c, 0x5c, 0x77, 0xac, 0xe4, 0xad, 0x9b, 0x28, 0x64, 0xcd, 0x51, 0x80, 0xb8, 0x4b, 0xaa, 0x9b, 0xc7, 0x69, 0x8a, 0x22, 0xe6, 0x8a, 0x23, 0x2e, 0x48, 0x19, 0x88, 0xb7, 0x5b, 0x98, 0xc5, 0x0a, 0xb5, 0x22, 0xf3, 0x3c, 0x79, 0xc6, 0x7e, 0x3d, 0xd2, 0xb4, 0x7c, 0x84, 0xdb, 0x14, 0x44, 0x50, 0xe7, 0x8a, 0x9a, 0x47, 0xac, 0x24, 0xaa, 0x80, 0xac, 0xd0, 0x15, 0xfa, 0x0a, 0xf3, 0x29, 0x0b, 0x49, 0x9a, 0xe6, 0x4f, 0xdb, 0x6d, 0xd1, 0xb4, 0x2b, 0xa7, 0x0d, 0x35, 0x5d, 0x7b, 0xd8, 0x60, 0xe8, 0xee, 0x3c, 0x8b, 0x21, 0xe9, 0x30, 0xa6, 0xd0, 0xee, 0x34, 0x6b, 0xba, 0xe8, 0xae, 0x28, 0xb5, 0x3b, 0x2f, 0x61, 0x3b, 0xdb, 0x18, 0xb1, 0x10, 0x5a, 0xd5, 0xcd, 0x63, 0x7d, 0xd4, 0x24, 0x71, 0xc9, 0x3b, 0xbc, 0xa6, 0x62, 0xa1, 0xfa, 0xb5, 0xd6, 0x51, 0x3b, 0xd9, 0x7e, 0x67, 0x63, 0xab, 0xb4, 0x12, 0x5d, 0x8b, 0x95, 0x74, 0xe6, 0xd3, 0x41, 0xe2, 0x7e, 0xd6, 0x78, 0x79, 0x0f, 0x1d, 0x15, 0x26, 0x27, 0x0d, 0x7b, 0x88, 0xfa, 0x69, 0x50, 0xaf, 0x7e, 0xb1, 0xd9, 0xb0, 0x7d, 0xa6, 0x9f, 0xc8, 0x21, 0x78, 0x55, 0xbb, 0x74, 0x72, 0x36, 0xd1, 0x83, 0xb3, 0x24, 0xc5, 0xd0, 0xd2, 0xe3, 0xa4, 0xac, 0x99, 0xfa, 0x72, 0x15, 0xa3, 0xf5, 0xd6, 0x76, 0x86, 0xea, 0x7a, 0xa3, 0x61, 0xc0, 0x73, 0xb6, 0x0f, 0xc3, 0x59, 0x11, 0x81, 0x2d, 0x9c, 0xba, 0x11, 0x7f, 0xca, 0xa0, 0x85, 0x5c, 0x19, 0xcc, 0x65, 0x09, 0xf2, 0xb2, 0xf8, 0x9c, 0xe0, 0x54, 0xc6, 0xd9, 0x6d, 0x54, 0x1e, 0xc7, 0x49, 0x84, 0xa3, 0xd0, 0x0d, 0xc8, 0x73, 0xf4, 0x15, 0x3f, 0xa0, 0x41, 0xd3, 0xd4, 0x89, 0x15, 0x6a, 0xe8, 0x46, 0xdc, 0x8a, 0x75, 0x24, 0x6d, 0x1c, 0x15, 0xcd, 0xe6, 0xc5, 0xd9, 0x66, 0x5b, 0xee, 0xe5, 0xf8, 0x22, 0x2b, 0xc1, 0xcb, 0xd6, 0x91, 0xa4, 0x62, 0x6e, 0xa7, 0xf5, 0x11, 0x02, 0x03, 0x8a, 0x72, 0xba, 0x06, 0x52, 0x85, 0xeb, 0xb5, 0xde, 0x95, 0xb4, 0x7b, 0x0c, 0x85, 0xca, 0xbc, 0xc5, 0xd0, 0x01, 0x6a, 0x77, 0x18, 0x06, 0x4c, 0xc3, 0x06, 0xc3, 0xa2, 0xe7, 0x91, 0x40, 0xae, 0x84, 0x7a, 0x4b, 0x2a, 0xdd, 0xae, 0x80, 0x75, 0x2e, 0x6d, 0xa2, 0x58, 0x36, 0x75, 0x4b, 0x25, 0x03, 0x6b, 0xb2, 0xac, 0x3e, 0xbc, 0x6a, 0x6a, 0x23, 0xeb, 0xac, 0xcd, 0x01, 0xcc, 0x1d, 0x28, 0x8c, 0x0a, 0x5a, 0x64, 0x74, 0xa4, 0x0e, 0x5a, 0xf2, 0xde, 0xf8, 0x16, 0x8b, 0x99, 0x96, 0x65, 0x09, 0x87, 0xa5, 0x2e, 0xd4, 0xd3, 0x8d, 0xf7, 0x14, 0x34, 0x09, 0x84, 0xda, 0xd8, 0x38, 0x8f, 0xac, 0x92, 0x76, 0x96, 0xa9, 0xc8, 0xd2, 0x5e, 0x4a, 0x5f, 0x52, 0x6e, 0x63, 0x83, 0x5a, 0xff, 0x55, 0xca, 0xb6, 0x2d, 0xb1, 0x50, 0x96, 0x35, 0x59, 0x14, 0xc7, 0x1b, 0x5b, 0x21, 0xda, 0xaa, 0x3c, 0x9e, 0x02, 0x53, 0xb4, 0xe3, 0xab, 0xc8, 0x15, 0x39, 0x86, 0xfd, 0xcb, 0xf2, 0x0e, 0xdb, 0x25, 0xd1, 0x65, 0xec, 0x6d, 0x7a, 0xc5, 0xe8, 0x30, 0xc7, 0x5d, 0x89, 0x68, 0x76, 0x55, 0x01, 0x1c, 0x59, 0xe9, 0x99, 0x91, 0x24, 0x96, 0xd3, 0x77, 0x0a, 0x53, 0xab, 0x09, 0xa6, 0xcb, 0x92, 0x68, 0xb3, 0x55, 0x1d, 0x47, 0x79, 0x50, 0x07, 0x15, 0x05, 0xc0, 0x8d, 0xbf, 0x72, 0xdd, 0x86, 0x2b, 0xda, 0xee, 0xef, 0x36, 0xe0, 0x19, 0x87, 0xd5, 0x91, 0x8b, 0x54, 0x85, 0xd9, 0xc6, 0xf5, 0xc3, 0x0b, 0xc6, 0xd6, 0x32, 0x10, 0x31, 0xdd, 0x06, 0xbf, 0x5d, 0x62, 0x95, 0x48, 0x30, 0xd0, 0x6f, 0x05, 0x6a, 0x1a, 0x72, 0x21, 0xa0, 0x26, 0xe2, 0xa6, 0x19, 0x37, 0xa3, 0x6b, 0xca, 0x87, 0x1c, 0xc2, 0x91, 0x20, 0x51, 0x33, 0x0b, 0x29, 0x31, 0x8d, 0x41, 0x42, 0x8b, 0x8b, 0x49, 0xbd, 0xe0, 0xac, 0xa1, 0xc1, 0x15, 0x65, 0x28, 0xb7, 0xee, 0x72, 0x48, 0x0f, 0x76, 0xfd, 0xf5, 0xb1, 0x2e, 0x00, 0x75, 0x9f, 0x67, 0xe4, 0xa5, 0xe1, 0x54, 0x94, 0xae, 0x21, 0xee, 0x35, 0x24, 0xfd, 0x20, 0x75, 0x5b, 0x66, 0x23, 0xf6, 0x39, 0x39, 0xda, 0xb6, 0x0e, 0x34, 0xad, 0xcb, 0xf1, 0x91, 0x8c, 0xda, 0x4e, 0xd9, 0xd6, 0x31, 0xc7, 0x65, 0x24, 0xe4, 0x38, 0x7d, 0x85, 0xc8, 0x4f, 0x55, 0x5b, 0xf2, 0x54, 0x28, 0x31, 0x08, 0x8c, 0x24, 0xc0, 0xc6, 0xe0, 0x3e, 0x85, 0xa2, 0x46, 0x7c, 0x1c, 0x15, 0xbd, 0x4f, 0x0b, 0x72, 0xf6, 0xbc, 0xcd, 0x61, 0x51, 0x24, 0x28, 0x33, 0xc3, 0x34, 0x79, 0x4b, 0x35, 0xe2, 0xc9, 0x63, 0x06, 0xe3, 0xb1, 0x30, 0x85, 0xb5, 0x73, 0xb3, 0xa2, 0x9c, 0x55, 0x33, 0xb9, 0xa9, 0x9a, 0xb6, 0x2b, 0x1e, 0x25, 0xc3, 0xa1, 0xfc, 0x7c, 0x31, 0x4d, 0x41, 0x51, 0x48, 0xb7, 0x1b, 0x1b, 0x85, 0x2d, 0x1b, 0x10, 0xcd, 0x8e, 0x5e, 0xed, 0xed, 0x9c, 0x08, 0x5b, 0xa1, 0x4b, 0xf8, 0x3c, 0x6a, 0x85, 0x1f, 0x35, 0x91, 0x87, 0xd3, 0xe5, 0x23, 0x7c, 0x4c, 0x8a, 0x12, 0xe6, 0x37, 0xa0, 0x4c, 0x9e, 0x20, 0x53, 0x4a, 0x1f, 0xd2, 0x38, 0xa6, 0xf3, 0x24, 0x8b, 0x39, 0x86, 0xf9, 0x4c, 0xc3, 0xa2, 0x77, 0x02, 0x89, 0xf3, 0x06, 0x6c, 0xa0, 0x7c, 0xed, 0x8a, 0x6b, 0xbe, 0x86, 0xe5, 0x1a, 0x35, 0xe3, 0x30, 0xa5, 0x97, 0x15, 0x94, 0xe6, 0x91, 0x96, 0x69, 0x8a, 0x87, 0xe0, 0x1e, 0x44, 0x5f, 0xfa, 0x62, 0x4e, 0x89, 0xda, 0xf9, 0x2e, 0xc2, 0xc6, 0xef, 0x09, 0xbc, 0xc8, 0xc9, 0xa8, 0x95, 0x7b, 0x23, 0x74, 0x4d, 0x20, 0xe3, 0xd6, 0xcf, 0xb1, 0x5b, 0xd4, 0xe0, 0x47, 0x06, 0x92, 0x65, 0x4b, 0xc2, 0xfb, 0x1d, 0x47, 0xd9, 0x8c, 0xe7, 0xf4, 0x5a, 0x96, 0xa3, 0x5b, 0x08, 0xe5, 0xfb, 0x8b, 0xea, 0x2c, 0x6f, 0x30, 0xea, 0x7b, 0x1b, 0x64, 0x92, 0x1e, 0xb5, 0x5e, 0x65, 0xd0, 0x83, 0x68, 0x5a, 0xf9, 0x86, 0xaa, 0x86, 0x79, 0xc4, 0x71, 0xc8, 0x59, 0xa4, 0xbb, 0xc7, 0x24, 0x33, 0x5a, 0xb1, 0xa1, 0xa8, 0x7d, 0xae, 0xc4, 0xe3, 0x45, 0x66, 0xbe, 0x44, 0x5c, 0xab, 0xcb, 0xeb, 0xb7, 0x5a, 0xe3, 0x9d, 0xde, 0xcd, 0x2e, 0x4d, 0xc7, 0x51, 0x84, 0x63, 0xc0, 0x48, 0x69, 0x9b, 0x25, 0x4f, 0x49, 0x0c, 0x27, 0xfb, 0x7f, 0xc0, 0x1c, 0x89, 0x09, 0x68, 0x7d, 0x53, 0x41, 0x59, 0x03, 0xfa, 0x9f, 0x7a, 0x0c, 0x41, 0xe9, 0x75, 0xf8, 0xd1, 0x29, 0x40, 0xa1, 0xef, 0x71, 0x06, 0xd2, 0x43, 0x7b, 0x31, 0x3d, 0xab, 0xa2, 0xa2, 0xc0, 0xd2, 0x21, 0x50, 0x5c, 0x8e, 0x28, 0xc5, 0x0a, 0x5d, 0x61, 0xff, 0x36, 0x85, 0x6e, 0x07, 0x10, 0x76, 0x4b, 0x07, 0x99, 0x10, 0x9a, 0xfb, 0x39, 0x16, 0x8c, 0x6a, 0x57, 0xd0, 0x80, 0xe8, 0xaf, 0xb1, 0x8b, 0x3c, 0x64, 0x73, 0x20, 0x30, 0x28, 0x77, 0xda, 0x75, 0xf4, 0x38, 0x80, 0x6b, 0x58, 0x9a, 0x3d, 0x0b, 0xa5, 0x64, 0x04, 0xed, 0x5e, 0x45, 0x97, 0x3c, 0xb0, 0x5d, 0x8b, 0x40, 0xce, 0x5f, 0x16, 0xe3, 0x68, 0xe5, 0x4b, 0x4e, 0xdc, 0x24, 0x1c, 0xe7, 0x39, 0xd8, 0xeb, 0xef, 0x3d, 0x2b, 0x5b, 0x00, 0x1c, 0xcb, 0x28, 0xf9, 0x59, 0x4a, 0x6f, 0x83, 0xb2, 0x6d, 0x8b, 0x7a, 0x39, 0x9a, 0x67, 0x21, 0x37, 0xbf, 0x79, 0x9e, 0x15, 0x52, 0x6e, 0x57, 0x0b, 0x99, 0xc6, 0x91, 0xb0, 0x14, 0xd3, 0x89, 0x60, 0x51, 0x7e, 0x96, 0x44, 0x25, 0x5e, 0xf3, 0x41, 0x6e, 0xeb, 0x01, 0x0d, 0x25, 0xb5, 0xfe, 0xd7, 0x38, 0x42, 0x80, 0x47, 0x78, 0x0d, 0xb6, 0xd5, 0x5f, 0x3a, 0xcb, 0xb6, 0x1c, 0x98, 0xee, 0x22, 0x45, 0xf7, 0x20, 0x65, 0x06, 0xc6, 0x1f, 0xc5, 0x00, 0x25, 0x4c, 0x05, 0x54, 0xfb, 0x2b, 0x5d, 0xe7, 0xb1, 0x5e, 0xed, 0x4e, 0x4c, 0x48, 0x67, 0xd4, 0xdc, 0x44, 0x9c, 0x52, 0x78, 0x14, 0xd7, 0xa0, 0x20, 0xbb, 0x6a, 0x4b, 0xd7, 0xa7, 0xbb, 0xa2, 0x44, 0x9b, 0xf6, 0x65, 0x83, 0x5a, 0xe7, 0xdb, 0x05, 0xee, 0xe5, 0x0a, 0x6e, 0xb6, 0x28, 0xc7, 0x66, 0xa1, 0x4b, 0xb1, 0xdc, 0x8a, 0xb3, 0xcb, 0x05, 0xa0, 0xbb, 0xf6, 0x5a, 0xe8, 0xed, 0xa2, 0x5e, 0x61, 0x96, 0x78, 0x89, 0x24, 0xf6, 0x81, 0x71, 0x02, 0xb0, 0x35, 0x6f, 0x17, 0xfc, 0x03, 0x5e, 0xcf, 0xdb, 0xc5, 0xa7, 0x2c, 0x77, 0x65, 0xa2, 0x85, 0x36, 0xca, 0x34, 0x2f, 0xce, 0x9e, 0x09, 0x0f, 0x99, 0x19, 0x94, 0xe6, 0x06, 0x2d, 0x21, 0xc8, 0xa3, 0xb5, 0x6c, 0x57, 0x07, 0x96, 0x1b, 0xc4, 0xae, 0x69, 0xe2, 0xfd, 0x9b, 0xcc, 0xcd, 0x75, 0xb8, 0xa1, 0xa9, 0xb9, 0x89, 0x49, 0x0c, 0x83, 0x88, 0x35, 0xc7, 0x2b, 0xdc, 0x2e, 0xcf, 0xb1, 0xb0, 0x59, 0x92, 0x43, 0x92, 0x30, 0xec, 0xcd, 0xc4, 0xa4, 0xf4, 0x80, 0x22, 0x90, 0xb2, 0x84, 0x47, 0x23, 0xfb, 0xec, 0xb9, 0xcc, 0x41, 0x54, 0xeb, 0x8d, 0x3f, 0x59, 0xf4, 0x14, 0x69, 0x75, 0x5a, 0x1a, 0x89, 0xe9, 0x68, 0x9a, 0x89, 0xa7, 0x6b, 0xb4, 0x35, 0xab, 0xd0, 0x76, 0x67, 0x1c, 0xc7, 0xe3, 0x5d, 0x89, 0x74, 0x68, 0xbc, 0xa3, 0x6c, 0xd0, 0x13, 0x34, 0xd1, 0x89, 0x8e, 0xb6, 0x20, 0xe7, 0x57, 0xb1, 0x8e, 0xce, 0x32, 0xba, 0x66, 0xd1, 0xf4, 0x78, 0xae, 0xa2, 0x9a, 0x82, 0x68, 0x0d, 0x8b, 0x6a, 0x8a, 0xac, 0xe0, 0x33, 0xb9, 0x26, 0x1b, 0xe3, 0x49, 0x0a, 0xc1, 0x86, 0xcd, 0x13, 0x4c, 0x4e, 0xe7, 0x09, 0x69, 0x63, 0xcf, 0x71, 0x8e, 0x41, 0x88, 0xa4, 0x0c, 0x43, 0x92, 0xd6, 0x1b, 0x6e, 0xb2, 0x3f, 0xcb, 0x22, 0x14, 0x73, 0xcb, 0x8e, 0x0e, 0xd8, 0x24, 0xe6, 0x73, 0x9e, 0x94, 0xb0, 0x53, 0x0e, 0xa5, 0xb2, 0xeb, 0x2d, 0x78, 0xf0, 0x0c, 0x3e, 0x80, 0x5d, 0x4a, 0xfb, 0xa0, 0x57, 0x4e, 0x9f, 0xc8, 0xd3, 0x31, 0xd3, 0xf1, 0x0a, 0x31, 0xfd, 0x76, 0xf1, 0x19, 0x67, 0x53, 0xa4, 0x6e, 0xbd, 0x42, 0x9f, 0xca, 0x87, 0xf7, 0xc6, 0x0a, 0x84, 0x5a, 0x44, 0xc2, 0x31, 0x03, 0x33, 0xac, 0x50, 0x0d, 0x20, 0xb0, 0x72, 0x1b, 0x50, 0xb9, 0x0a, 0x44, 0x3b, 0xf5, 0xf7, 0xc5, 0xdb, 0x31, 0x9e, 0xf4, 0x38, 0x09, 0xac, 0x9c, 0x1f, 0x07, 0xd8, 0xf3, 0x24, 0x2d, 0x69, 0xd5, 0xed, 0x76, 0x61, 0x6e, 0xe6, 0x71, 0x26, 0xc4, 0xb8, 0x6b, 0x12, 0x12, 0x5b, 0x0f, 0xc4, 0x9d, 0x66, 0x8f, 0x59, 0x57, 0x05, 0xa1, 0xcb, 0x3d, 0x76, 0xcd, 0xcd, 0xd9, 0x13, 0x8d, 0x07, 0x05, 0xd9, 0xa6, 0x62, 0xaf, 0xc0, 0xc3, 0x53, 0xbd, 0x81, 0x22, 0x80, 0x18, 0x69, 0x79, 0xcc, 0x05, 0x2a, 0x4a, 0x4a, 0xd2, 0xf5, 0x92, 0xd1, 0x51, 0x93, 0x02, 0xb7, 0x5b, 0x3d, 0xcd, 0x9f, 0x47, 0xd2, 0x32, 0x22, 0x58, 0x7b, 0x4a, 0x52, 0xe5, 0x94, 0x8a, 0x53, 0xde, 0xb4, 0x34, 0x6d, 0x12, 0x14, 0xa9, 0x7c, 0x2f, 0xc7, 0x39, 0x64, 0x68, 0xf3, 0xec, 0x6f, 0x3b, 0xb8, 0x83, 0x1e, 0xa0, 0xa2, 0xa2, 0x24, 0x93, 0x08, 0x85, 0xcc, 0x05, 0x0c, 0xae, 0xff, 0x93, 0xfd, 0x0a, 0x3c, 0x76, 0x1b, 0xdd, 0x82, 0xb3, 0x44, 0xbb, 0x3c, 0x82, 0x7a, 0x6b, 0x6a, 0x97, 0xea, 0x7a, 0x2e, 0x53, 0x96, 0x6a, 0xa5, 0xee, 0xdc, 0xab, 0x29, 0xc0, 0x42, 0x7c, 0xc6, 0x1b, 0xd9, 0x32, 0xc9, 0x76, 0x68, 0x57, 0x50, 0xd0, 0x4b, 0x84, 0xbe, 0x50, 0xef, 0x97, 0x9e, 0xd7, 0xdb, 0x49, 0x9c, 0x3d, 0x3e, 0x88, 0x18, 0x2c, 0x7c, 0x7b, 0xc3, 0x50, 0x55, 0x36, 0x5b, 0x3c, 0xcd, 0x64, 0x80, 0xf6, 0x61, 0xb7, 0x12, 0x3d, 0x01, 0x94, 0xc5, 0xa5, 0x7c, 0xc0, 0x6b, 0xbb, 0x36, 0xc5, 0xf9, 0xb0, 0xac, 0x1e, 0x0b, 0x33, 0x74, 0x5c, 0xec, 0xb3, 0xe8, 0xaf, 0x70, 0xcf, 0xa6, 0x65, 0x33, 0x85, 0xd8, 0x5c, 0xd6, 0x0e, 0x20, 0x99, 0xd6, 0x51, 0x9e, 0x6c, 0xcb, 0xba, 0x45, 0x98, 0xcc, 0x67, 0xcf, 0x30, 0xda, 0xe1, 0xf8, 0x4d, 0x29, 0x34, 0x3b, 0x57, 0x4d, 0x7a, 0x67, 0x67, 0xb2, 0xa6, 0xc6, 0x1a, 0x90, 0xb6, 0xec, 0xd5, 0x53, 0xba, 0x91, 0xb1, 0xaf, 0x06, 0xda, 0x6e, 0xa8, 0x73, 0x53, 0x13, 0xa9, 0x7c, 0xa0, 0x82, 0xd9, 0x69, 0x98, 0xa6, 0x3d, 0xe1, 0x7a, 0xdb, 0x54, 0x97, 0x08, 0x49, 0xdb, 0x24, 0xe2, 0xb3, 0x96, 0x73, 0x93, 0x0e, 0x2c, 0xfb, 0x16, 0xac, 0x13, 0x7b, 0xb6, 0xdb, 0x6c, 0xd9, 0x68, 0x9d, 0x65, 0x8f, 0x49, 0x06, 0x75, 0x93, 0x62, 0xb2, 0x2f, 0x21, 0x4e, 0x1f, 0xf8, 0xfd, 0x55, 0x5d, 0xe3, 0xa8, 0x8e, 0x87, 0xed, 0x4a, 0xd8, 0xe4, 0xb3, 0xb0, 0xda, 0x6e, 0xe5, 0xf0, 0x3a, 0xaf, 0xa4, 0x8d, 0xed, 0xc4, 0x9f, 0xae, 0x61, 0xf4, 0xa5, 0x4e, 0x32, 0x69, 0xbe, 0x7e, 0x8e, 0xd2, 0xb8, 0xdd, 0x53, 0x3b, 0x71, 0xd8, 0x25, 0x50, 0x7d, 0x18, 0x6a, 0x21, 0x93, 0xcd, 0x75, 0xe9, 0x5d, 0xf5, 0x50, 0x1e, 0x62, 0x7e, 0x7d, 0xc4, 0xd6, 0x98, 0x24, 0x64, 0x6b, 0xab, 0xe3, 0xe7, 0x5b, 0xc6, 0x31, 0xd8, 0x92, 0x2c, 0xa8, 0x11, 0xc4, 0x9b, 0x8a, 0x16, 0xc0, 0x58, 0x69, 0xed, 0x53, 0x76, 0x8f, 0x97, 0xd9, 0xf8, 0x7c, 0x97, 0xd1, 0xe4, 0xe8, 0x2c, 0xcf, 0x51, 0x2e, 0xe4, 0x5e, 0xfd, 0xf9, 0x94, 0xe1, 0xa9, 0x94, 0xac, 0x8f, 0xc6, 0x84, 0x13, 0xb9, 0xba, 0x2d, 0x17, 0x0a, 0xe9, 0xca, 0xa9, 0x1d, 0xa6, 0xa0, 0x47, 0x61, 0x7c, 0x9d, 0xbd, 0x49, 0x14, 0x48, 0x10, 0xc7, 0x5b, 0x8f, 0x2b, 0x04, 0x62, 0xa6, 0x5c, 0x75, 0x74, 0xfa, 0x82, 0x51, 0xfc, 0xe3, 0x6a, 0x3e, 0xb9, 0xc3, 0x7a, 0xe2, 0x45, 0x84, 0x4c, 0xd0, 0xd1, 0x2e, 0x2b, 0x68, 0xed, 0xbe, 0x4e, 0x2e, 0x9b, 0xcf, 0x29, 0xe2, 0xce, 0x4f, 0xac, 0x54, 0x02, 0xf4, 0xc1, 0x81, 0x8f, 0x43, 0x20, 0x1f, 0x09, 0x07, 0x18, 0x64, 0x34, 0xe2, 0x13, 0x6c, 0xc2, 0xa4, 0x1c, 0xd5, 0x1f, 0x0a, 0xb2, 0x00, 0xde, 0x49, 0xd1, 0x87, 0xb6, 0x00, 0x76, 0x37, 0x40, 0x21, 0xd4, 0x94, 0x2a, 0x75, 0x52, 0x1e, 0xb0, 0x98, 0x62, 0xad, 0x61, 0xe7, 0x18, 0x7f, 0x78, 0x71, 0xf9, 0xf9, 0x66, 0xc6, 0x57, 0x23, 0xd2, 0x24, 0xa2, 0xf5, 0x92, 0xcf, 0x49, 0x16, 0xa3, 0xaf, 0x97, 0x20, 0x8b, 0x53, 0x29, 0x6b, 0xce, 0x11, 0x29, 0xed, 0x72, 0xa4, 0xd5, 0xe4, 0x2f, 0x04, 0x32, 0xc6, 0xa9, 0x52, 0x09, 0x79, 0x40, 0x5d, 0xe9, 0x60, 0x75, 0x1d, 0xc7, 0xb4, 0x4c, 0x04, 0x20, 0xd9, 0x8b, 0x95, 0x5d, 0x08, 0x96, 0x68, 0x95, 0xef, 0x27, 0xd8, 0xe1, 0x59, 0x82, 0x53, 0x7f, 0xa8, 0xa7, 0xd3, 0x11, 0xcd, 0x7a, 0x88, 0x18, 0xf5, 0xf1, 0x39, 0x9e, 0xe5, 0x69, 0x2a, 0xd1, 0xd7, 0xf3, 0x42, 0xc8, 0x6c, 0x48, 0x7c, 0xba, 0xc5, 0xc1, 0x07, 0x13, 0x34, 0x6f, 0x60, 0x7e, 0x25, 0xba, 0x34, 0xc6, 0x4f, 0xf8, 0x93, 0x34, 0xfd, 0x5f, 0x12, 0x26, 0x4e, 0xc5, 0x36, 0xd8, 0xa0, 0x57, 0x24, 0xc0, 0x6b, 0x4f, 0x10, 0x4c, 0xdb, 0x0e, 0x91, 0x77, 0x9c, 0x3f, 0xee, 0x48, 0xe5, 0xef, 0x02, 0x66, 0x75, 0x59, 0x4c, 0x2e, 0xb8, 0xd8, 0x04, 0xc9, 0x05, 0x06, 0xe1, 0xd4, 0x8d, 0xc9, 0x5a, 0x7c, 0xaa, 0xbe, 0xdc, 0x43, 0xd6, 0xa2, 0x72, 0x1b, 0x94, 0xdf, 0xec, 0x36, 0x9a, 0x66, 0x1c, 0xe3, 0xf0, 0x2e, 0x97, 0xb5, 0x71, 0x5b, 0x44, 0xec, 0x1f, 0x19, 0x6b, 0x5a, 0x81, 0xe2, 0x4b, 0x7b, 0x5b, 0x5b, 0x5c, 0xe2, 0x38, 0x0a, 0xe2, 0xed, 0xab, 0xcb, 0x8f, 0x67, 0xe3, 0xd9, 0xdd, 0x6a, 0xbc, 0xfc, 0xeb, 0xdd, 0xf9, 0xa7, 0x9b, 0xe9, 0x11, 0xf7, 0x70, 0x31, 0xfe, 0x38, 0xbe, 0x16, 0xf8, 0xb3, 0x98, 0x63, 0x97, 0xf2, 0xea, 0x2b, 0xa4, 0x6c, 0xd6, 0x85, 0xf6, 0x39, 0x29, 0xed, 0x95, 0x80, 0x2c, 0x4c, 0x16, 0xc2, 0xc5, 0xae, 0x58, 0x9f, 0x65, 0x4f, 0x49, 0x8e, 0xb2, 0x1b, 0x94, 0x14, 0xb5, 0x61, 0xab, 0x98, 0xab, 0xe9, 0x13, 0xb9, 0x89, 0x82, 0x07, 0x01, 0x6d, 0x26, 0x49, 0x59, 0xbc, 0x39, 0x7e, 0x3f, 0x52, 0xfd, 0x6c, 0x9a, 0x26, 0xdb, 0x7b, 0x04, 0xf2, 0xf8, 0x12, 0x14, 0xec, 0x14, 0x99, 0xa5, 0xec, 0xf5, 0x63, 0xf6, 0x4c, 0xac, 0xd8, 0x54, 0x4d, 0x4b, 0x52, 0x93, 0x54, 0x6b, 0x4f, 0x1a, 0xec, 0x8b, 0x8a, 0x52, 0x19, 0xf1, 0xd3, 0x77, 0xed, 0xc0, 0x25, 0xd1, 0x97, 0x3a, 0xf0, 0x73, 0x79, 0x3f, 0x93, 0x6f, 0xaa, 0xeb, 0x2a, 0x9e, 0x34, 0x8c, 0xd1, 0x5c, 0x78, 0xa1, 0x4b, 0xe6, 0xd9, 0x73, 0x04, 0xb7, 0x7c, 0xe8, 0xb1, 0x85, 0x06, 0x37, 0x0e, 0x7d, 0x56, 0xe9, 0x8b, 0xe3, 0xad, 0x87, 0xb5, 0xf2, 0x37, 0xc6, 0x29, 0x43, 0xf3, 0x46, 0xb1, 0xd4, 0x56, 0xc5, 0xa9, 0x79, 0xf6, 0x40, 0xcd, 0xce, 0x02, 0x82, 0x96, 0xa4, 0x01, 0x10, 0xdc, 0x94, 0xd5, 0x59, 0x2a, 0x92, 0x91, 0x73, 0x6c, 0x13, 0x30, 0x48, 0xf4, 0x72, 0x01, 0x10, 0x9c, 0x19, 0x65, 0x4f, 0x30, 0x2f, 0x17, 0xd3, 0xeb, 0x15, 0x7a, 0x73, 0x4a, 0x5e, 0x46, 0xac, 0x79, 0xdf, 0x9c, 0x36, 0xd6, 0xa9, 0x26, 0x58, 0x5d, 0xe2, 0xbf, 0x5d, 0x7c, 0x06, 0x4f, 0x90, 0xf9, 0x17, 0xb7, 0x23, 0xe0, 0x2e, 0xeb, 0xf7, 0x86, 0x6e, 0x36, 0x29, 0xd2, 0x6f, 0x9a, 0xb5, 0xbb, 0x08, 0x38, 0x4f, 0x11, 0x9e, 0xb9, 0x0f, 0xe4, 0xe7, 0x10, 0xec, 0x01, 0xb0, 0x76, 0x6b, 0x88, 0x95, 0x01, 0x7a, 0xe3, 0x93, 0xd5, 0xde, 0x97, 0x24, 0xed, 0xc4, 0xa3, 0x3f, 0xe7, 0x3e, 0xf2, 0x95, 0x4a, 0x81, 0x48, 0x3d, 0xca, 0xb8, 0xc8, 0xc1, 0x76, 0x9d, 0x44, 0x24, 0x57, 0xc4, 0x5e, 0xc4, 0x72, 0x83, 0x5c, 0xd9, 0x54, 0x61, 0x28, 0x1d, 0x5d, 0x73, 0x20, 0xcd, 0x93, 0x5c, 0xe2, 0x90, 0x0d, 0x73, 0x07, 0xc2, 0x25, 0xee, 0xa6, 0xad, 0x9d, 0x9c, 0x54, 0x6f, 0x4b, 0x8e, 0x4a, 0xbc, 0x2b, 0x2b, 0x1d, 0xaf, 0xfc, 0x3f, 0xef, 0x08, 0x2d, 0xdb, 0x57, 0xf4, 0xb4, 0x6c, 0x3f, 0x52, 0x97, 0xf1, 0x15, 0x1a, 0x47, 0xe5, 0x8e, 0x7c, 0xe3, 0x46, 0x8a, 0x72, 0xee, 0x76, 0x8b, 0x4a, 0x79, 0x9e, 0xa3, 0x8d, 0x89, 0xd6, 0x54, 0xc2, 0x61, 0x59, 0x1a, 0xe1, 0xbc, 0xbb, 0x99, 0xdf, 0x4d, 0xb0, 0x83, 0x5d, 0x81, 0x7d, 0x75, 0x5b, 0x93, 0x7f, 0xa0, 0x5e, 0xeb, 0x61, 0x09, 0x06, 0x3b, 0x10, 0x5a, 0x92, 0x77, 0x8f, 0x9b, 0xea, 0x91, 0xce, 0xe3, 0x88, 0x35, 0x52, 0x76, 0xc7, 0x07, 0xd3, 0x8d, 0x48, 0x9a, 0x4b, 0xcb, 0xe0, 0x47, 0xc5, 0x1a, 0x2f, 0xd9, 0xec, 0xa7, 0x7e, 0x88, 0x75, 0x9c, 0x0a, 0xf9, 0x8c, 0x5e, 0xc4, 0x16, 0x49, 0x57, 0xa4, 0xce, 0x4c, 0xe9, 0xc5, 0x04, 0x83, 0x1c, 0x77, 0xb3, 0x09, 0xf2, 0x76, 0xd6, 0x1c, 0x12, 0xce, 0xeb, 0x27, 0x7f, 0x52, 0xa6, 0x51, 0x4d, 0xd5, 0xbe, 0x62, 0xf3, 0x82, 0x1e, 0xe4, 0x45, 0x20, 0x23, 0x79, 0x19, 0xce, 0xa4, 0xc8, 0x1d, 0x8a, 0xe6, 0xa0, 0x60, 0x79, 0xb5, 0x20, 0xde, 0x33, 0xdf, 0x68, 0xea, 0x14, 0x5c, 0xec, 0x50, 0x8a, 0xd5, 0xca, 0xf5, 0x2a, 0x9a, 0xd2, 0xac, 0x72, 0x90, 0x15, 0x95, 0x03, 0xd5, 0x92, 0xe8, 0x39, 0xa2, 0xae, 0x41, 0x57, 0x4a, 0xf4, 0x00, 0x18, 0xa7, 0xdb, 0x35, 0x98, 0xa4, 0x64, 0xd3, 0xc3, 0x0d, 0xbd, 0xbc, 0xdf, 0x79, 0x7b, 0xac, 0xcf, 0x9a, 0x5a, 0xee, 0xbb, 0xcb, 0xd9, 0xd8, 0x13, 0x01, 0xb9, 0xf2, 0x77, 0x6b, 0x12, 0x0c, 0xcb, 0xd7, 0x2a, 0xc0, 0x93, 0x3f, 0x0e, 0xd5, 0x11, 0xe0, 0x0f, 0x44, 0x03, 0xce, 0x35, 0x28, 0xed, 0x40, 0x5a, 0xf6, 0x38, 0x4e, 0xc8, 0xf5, 0x25, 0x4f, 0x67, 0x53, 0x50, 0x06, 0x3b, 0x9d, 0x8a, 0xe4, 0x67, 0x1e, 0xad, 0x66, 0xc1, 0x31, 0x87, 0x39, 0x93, 0x06, 0xc7, 0x4b, 0xb1, 0x2a, 0xe9, 0x11, 0x70, 0xf1, 0xfa, 0x45, 0x7e, 0x8d, 0xba, 0x94, 0xa9, 0x79, 0x2b, 0x1e, 0x1e, 0xa2, 0x93, 0x97, 0x94, 0xf7, 0xf0, 0xc2, 0x66, 0xf2, 0xa1, 0x5a, 0xe3, 0x7e, 0x9d, 0x51, 0x40, 0x55, 0x97, 0x0a, 0x05, 0x8c, 0x86, 0xc2, 0x3a, 0xeb, 0x7d, 0x68, 0x11, 0x07, 0xb2, 0xb8, 0x7e, 0xe8, 0xbd, 0x61, 0xe5, 0xd0, 0x19, 0xda, 0x1a, 0xf2, 0x2c, 0x0a, 0x83, 0xdf, 0x11, 0x29, 0x87, 0x19, 0x67, 0x9e, 0xe1, 0x1c, 0x6b, 0xeb, 0x2f, 0x22, 0x70, 0xd7, 0x42, 0xcf, 0xb5, 0xce, 0xa8, 0xee, 0x37, 0x44, 0x1d, 0x56, 0xec, 0x21, 0xcc, 0x5d, 0x7e, 0x6f, 0x7b, 0x1e, 0x26, 0x06, 0x74, 0xae, 0x45, 0xa1, 0x07, 0x2e, 0xec, 0xe4, 0xc2, 0x29, 0x3c, 0xcd, 0x84, 0xfd, 0x67, 0xd5, 0x30, 0x69, 0x3e, 0x8e, 0x3e, 0x50, 0xa2, 0xb7, 0xfd, 0x86, 0xf7, 0xf4, 0xbb, 0xc9, 0xfe, 0xd6, 0xa3, 0x3a, 0x78, 0x0e, 0x0c, 0xed, 0xdf, 0xf7, 0x32, 0xac, 0xff, 0x6c, 0xec, 0x25, 0x38, 0xd8, 0x1a, 0xe8, 0x1e, 0xd5, 0xbf, 0x8f, 0x6c, 0xb3, 0xd4, 0x6f, 0x16, 0x31, 0x0e, 0xb0, 0x66, 0x86, 0xb0, 0xfa, 0x37, 0x8e, 0x21, 0x07, 0x5a, 0x4a, 0x3d, 0x75, 0xf8, 0x36, 0xf1, 0xe5, 0x10, 0x8b, 0xaf, 0x8b, 0x02, 0xe4, 0xd5, 0x88, 0x0f, 0x5b, 0xf0, 0xef, 0x1d, 0x64, 0x65, 0x34, 0x01, 0xd7, 0x6d, 0x6f, 0x3b, 0x25, 0x54, 0xfd, 0x8b, 0x0a, 0x0e, 0x50, 0x7d, 0x2a, 0x0b, 0x2e, 0x70, 0x41, 0x75, 0x73, 0xae, 0x03, 0x58, 0x72, 0x2e, 0xab, 0xf5, 0xdd, 0x07, 0x5c, 0x8b, 0x6c, 0x19, 0x94, 0xfe, 0xae, 0x64, 0xcc, 0xc0, 0x87, 0xca, 0x09, 0x92, 0x7c, 0x77, 0xba, 0x8b, 0x5f, 0x47, 0x0d, 0x52, 0x82, 0x1a, 0xd3, 0x20, 0xc3, 0x3b, 0xe8, 0xe8, 0x82, 0x4c, 0x20, 0x6f, 0xeb, 0x27, 0x32, 0xa8, 0x1b, 0xf6, 0x5f, 0xd4, 0xbe, 0x83, 0x02, 0x06, 0xd1, 0x87, 0x48, 0x26, 0xfa, 0x88, 0xff, 0xae, 0x7d, 0x0f, 0xbe, 0x88, 0xba, 0x44, 0xe8, 0xe5, 0xac, 0x33, 0x44, 0xfb, 0x2d, 0x01, 0xcb, 0x99, 0xc3, 0x2a, 0xe0, 0x2d, 0xa2, 0x7b, 0xd5, 0xea, 0x5b, 0x87, 0x4a, 0xca, 0x4f, 0x59, 0xf2, 0x44, 0x07, 0x8a, 0x4a, 0x61, 0xe7, 0x77, 0x9e, 0xfc, 0x26, 0x07, 0xeb, 0x81, 0x60, 0xf0, 0x12, 0x0d, 0x82, 0xc8, 0x3d, 0xc4, 0x40, 0xe2, 0xa3, 0xf7, 0xce, 0xd9, 0x8e, 0x28, 0xf9, 0xae, 0xf8, 0x9a, 0x90, 0x0b, 0xf9, 0x07, 0x56, 0xc0, 0xdd, 0x14, 0xc3, 0xbc, 0x25, 0xa8, 0x31, 0x0e, 0xaf, 0x42, 0x0f, 0x73, 0x0c, 0x9a, 0x9f, 0x61, 0xcd, 0x71, 0x70, 0x15, 0x6c, 0xe6, 0x20, 0xf7, 0x50, 0xf7, 0xd5, 0x99, 0xe1, 0xd6, 0xa6, 0xc8, 0x7b, 0x09, 0x8f, 0x91, 0x19, 0xa1, 0xec, 0xc7, 0x6a, 0x7a, 0xb0, 0x4e, 0xfd, 0x4e, 0x4f, 0x02, 0x6a, 0x78, 0x7a, 0x72, 0x10, 0x1d, 0xbb, 0xf6, 0x24, 0x7d, 0xed, 0xd8, 0x79, 0x44, 0x39, 0xd8, 0x96, 0x81, 0x35, 0x65, 0x80, 0x87, 0xb1, 0xa9, 0x35, 0x62, 0xf4, 0xd7, 0x33, 0x24, 0x9c, 0x7d, 0xfa, 0xf6, 0xd7, 0x2d, 0x24, 0x5c, 0xc7, 0xc5, 0x84, 0xe1, 0x9e, 0x73, 0x10, 0xdc, 0x8e, 0x13, 0xef, 0xe1, 0xda, 0x86, 0xc2, 0xa5, 0xb9, 0x17, 0xc5, 0xed, 0xda, 0x30, 0xf4, 0xc7, 0xb1, 0x65, 0x47, 0x3d, 0x91, 0x2c, 0x59, 0x92, 0x19, 0xa9, 0x79, 0xe5, 0xb2, 0x28, 0xf1, 0x16, 0x30, 0x4a, 0xca, 0xbd, 0x73, 0xae, 0xc5, 0x58, 0xb5, 0x5c, 0x46, 0x4b, 0x1b, 0xf9, 0xfb, 0xc5, 0x0f, 0x1b, 0x92, 0xf3, 0x62, 0x61, 0x41, 0xf0, 0xd2, 0x66, 0x1c, 0xc7, 0x3e, 0xb7, 0x68, 0x7c, 0xef, 0xce, 0x84, 0xb9, 0x31, 0x13, 0xe8, 0x9e, 0xcc, 0x72, 0x77, 0x3f, 0xd8, 0x16, 0x35, 0xef, 0x50, 0x5b, 0x34, 0xfc, 0x41, 0x7a, 0xe0, 0x6f, 0x8b, 0xeb, 0x5d, 0x3a, 0xd8, 0x16, 0x35, 0xef, 0x50, 0x5b, 0x34, 0xfc, 0x41, 0x7a, 0xe0, 0x6f, 0x0b, 0x1a, 0xbb, 0x66, 0x28, 0x7e, 0x84, 0x83, 0x4d, 0x22, 0x41, 0x0c, 0xb5, 0x8c, 0x0c, 0x13, 0xb2, 0x5b, 0xfe, 0x76, 0x9a, 0x81, 0xfc, 0x0b, 0xcc, 0x06, 0xdb, 0x88, 0x63, 0x1f, 0x6a, 0x1f, 0x1e, 0x22, 0x54, 0x57, 0xfc, 0xed, 0x72, 0x95, 0x3c, 0xae, 0x4b, 0x0f, 0xc3, 0xf0, 0xfc, 0x43, 0x2d, 0x23, 0x60, 0x04, 0xeb, 0x4d, 0x80, 0x98, 0x1b, 0xe5, 0xd0, 0xc3, 0x34, 0x1c, 0xfb, 0xe0, 0xc8, 0xcb, 0x41, 0x84, 0xea, 0x4a, 0x00, 0xbb, 0xb4, 0x67, 0x2b, 0xc1, 0xaf, 0x6d, 0xf5, 0x02, 0x1d, 0xb6, 0x63, 0x3f, 0x07, 0x45, 0x49, 0x6e, 0xbb, 0x83, 0x9c, 0x49, 0xbe, 0x3c, 0x3e, 0x77, 0x95, 0x68, 0x87, 0x99, 0x84, 0x80, 0xb9, 0x3d, 0xf6, 0xe8, 0xbe, 0x76, 0x94, 0x70, 0x24, 0x0d, 0x35, 0x54, 0xfc, 0x41, 0xc7, 0xb7, 0xbb, 0xad, 0x70, 0x68, 0x69, 0xad, 0x1c, 0x4f, 0x53, 0xb9, 0x08, 0xbb, 0x06, 0x5f, 0xd8, 0x21, 0x34, 0x79, 0x51, 0x85, 0xbc, 0x05, 0x62, 0x04, 0x54, 0xf7, 0xa6, 0x44, 0xb7, 0xeb, 0xfa, 0x6d, 0xd5, 0xde, 0xcb, 0xf3, 0x76, 0x2f, 0xbf, 0x4b, 0xe3, 0xcc, 0x3c, 0x49, 0xb2, 0x98, 0x08, 0x5e, 0xa1, 0x6b, 0x90, 0x64, 0x03, 0xb6, 0x05, 0xe7, 0x49, 0x9a, 0x8e, 0x3f, 0x5e, 0x18, 0x66, 0x88, 0xbe, 0xb7, 0x35, 0xcf, 0xdd, 0xcd, 0xb4, 0x2f, 0x9b, 0xa6, 0xa3, 0xdd, 0x4c, 0xaa, 0x65, 0xed, 0x3c, 0x38, 0xb9, 0xc7, 0x39, 0xed, 0x2d, 0xcc, 0xcb, 0xe5, 0x6e, 0xf3, 0xe6, 0xb4, 0x61, 0xe5, 0x5e, 0xe6, 0x1b, 0x60, 0x6a, 0x09, 0x95, 0xdb, 0xd6, 0x06, 0xc4, 0x7d, 0x7b, 0xdc, 0xe9, 0x05, 0x83, 0x50, 0xbd, 0x8e, 0x52, 0x84, 0x1c, 0x07, 0x4d, 0xd0, 0xf3, 0x24, 0xdd, 0xe5, 0xe3, 0xa7, 0x47, 0xce, 0xb4, 0x0d, 0xb9, 0xc1, 0x1e, 0xa6, 0x47, 0x96, 0xf9, 0x28, 0x4a, 0xd2, 0x55, 0x11, 0x0e, 0x23, 0x4b, 0x1e, 0x82, 0xe1, 0x76, 0xeb, 0x96, 0x64, 0xea, 0x55, 0x18, 0x59, 0xcb, 0xaf, 0x80, 0x84, 0x6a, 0xf8, 0xbe, 0x11, 0xc2, 0x7f, 0xc5, 0xad, 0x21, 0x20, 0xd4, 0x4c, 0x56, 0x33, 0x68, 0xf8, 0x3e, 0xc2, 0x27, 0x98, 0x17, 0x1a, 0x59, 0x7a, 0x3a, 0x1d, 0xbc, 0x62, 0xaa, 0x8b, 0x1c, 0xec, 0x97, 0x11, 0x30, 0x9c, 0xd0, 0xc9, 0xe7, 0x6a, 0x17, 0x60, 0xb3, 0x01, 0xe3, 0xf8, 0xd7, 0x5d, 0x41, 0xbf, 0x80, 0x93, 0xfe, 0xaf, 0x3e, 0xfa, 0xae, 0xe4, 0x95, 0xa6, 0xa5, 0x35, 0xa6, 0x4c, 0xc1, 0x5a, 0xa5, 0xc3, 0x8d, 0xfe, 0xf0, 0xe2, 0x64, 0x24, 0x6d, 0x94, 0xcc, 0x10, 0xc7, 0x7a, 0xe3, 0x18, 0x6b, 0x61, 0x6e, 0x48, 0xd3, 0x35, 0xf1, 0x41, 0xbc, 0xdb, 0x25, 0xab, 0x0f, 0x57, 0x4f, 0x52, 0x8f, 0x5b, 0x3a, 0x4a, 0x41, 0x0c, 0x08, 0x47, 0x9b, 0x60, 0x58, 0x1a, 0x14, 0xd3, 0x2a, 0xde, 0x89, 0xee, 0xb2, 0xee, 0x0b, 0xa6, 0x08, 0x67, 0x88, 0x10, 0x66, 0xf8, 0x76, 0x46, 0x98, 0x5c, 0x9d, 0x3d, 0x6f, 0x41, 0x16, 0xbf, 0x99, 0x24, 0xe5, 0x0a, 0xbd, 0xc7, 0x3f, 0x17, 0x20, 0x75, 0xec, 0x82, 0x3d, 0xdb, 0x55, 0x91, 0xdd, 0x60, 0xcd, 0x18, 0x6f, 0x8f, 0x25, 0xf5, 0x3a, 0x0a, 0x98, 0x6e, 0xfa, 0xbd, 0x3b, 0x58, 0xcf, 0xdf, 0x05, 0xe8, 0xf9, 0xbb, 0x03, 0xf6, 0xfc, 0xfd, 0xc1, 0x7a, 0xfe, 0xfe, 0x00, 0x5a, 0x2b, 0xc8, 0x64, 0x91, 0x18, 0x90, 0xf8, 0x4e, 0xae, 0xa6, 0xec, 0x65, 0xc0, 0x37, 0x27, 0x2e, 0xe3, 0xc3, 0x67, 0x10, 0x36, 0x18, 0xaa, 0x92, 0x4d, 0x9d, 0x4e, 0xa0, 0x63, 0x3f, 0x7f, 0x11, 0x51, 0x3a, 0xd5, 0x31, 0xe0, 0x84, 0x41, 0x69, 0xb4, 0xa1, 0x00, 0x9d, 0x7d, 0x32, 0x6e, 0x72, 0x24, 0x18, 0xfa, 0xeb, 0xee, 0x06, 0x65, 0xba, 0x37, 0x37, 0x7d, 0x20, 0x71, 0xe8, 0x26, 0x5f, 0xc2, 0x1c, 0x16, 0xd4, 0x07, 0x71, 0x96, 0x94, 0x6b, 0x98, 0x57, 0x70, 0x6f, 0x4e, 0xf1, 0xaf, 0x13, 0x6e, 0x69, 0x34, 0xed, 0x3b, 0x1c, 0xe2, 0xbd, 0x06, 0xf8, 0x24, 0x3c, 0x70, 0x8f, 0xf1, 0xb6, 0x61, 0xae, 0xae, 0x2e, 0x4e, 0xc8, 0x17, 0x93, 0xa2, 0x02, 0xd2, 0xfd, 0x63, 0xf1, 0x76, 0x85, 0xde, 0x39, 0xcc, 0x8d, 0xea, 0xef, 0xea, 0xdf, 0x9a, 0x69, 0x0d, 0xac, 0x40, 0xbf, 0xf3, 0x84, 0xae, 0xfe, 0x68, 0xd1, 0x67, 0xb0, 0xfe, 0x72, 0xb9, 0x65, 0x9a, 0xc4, 0xb0, 0x47, 0x5a, 0x60, 0x99, 0x58, 0x18, 0xf8, 0x74, 0x46, 0xbf, 0xdf, 0xf1, 0x02, 0x6b, 0xbd, 0xb9, 0xbf, 0x05, 0xe9, 0x0e, 0x92, 0x2f, 0x85, 0x3a, 0x4f, 0xf2, 0x82, 0x99, 0xdc, 0x0c, 0xd8, 0x0d, 0x34, 0x08, 0x80, 0x6c, 0x1a, 0xe8, 0x97, 0x8c, 0x25, 0xd1, 0x48, 0x19, 0x61, 0xa7, 0xc2, 0x8c, 0xc9, 0x08, 0x12, 0x4a, 0x87, 0xab, 0x70, 0xea, 0xf4, 0xd4, 0x23, 0x80, 0xfc, 0x85, 0xf1, 0x1d, 0x3f, 0xb7, 0x09, 0xbf, 0xb0, 0xbc, 0x43, 0xd7, 0x6f, 0xf3, 0xb7, 0xb0, 0xbe, 0xff, 0x37, 0x40, 0x1b, 0xef, 0xea, 0xf4, 0xa2, 0xf0, 0x39, 0x37, 0x6e, 0xb9, 0x43, 0x69, 0xe1, 0x61, 0x95, 0x60, 0xa7, 0xc7, 0x8b, 0xc2, 0xe7, 0xfc, 0xb8, 0xe5, 0x0e, 0xa5, 0xc5, 0x70, 0x9b, 0x84, 0x3b, 0x45, 0x5e, 0x14, 0x3e, 0xe7, 0xc8, 0x2d, 0x77, 0x28, 0x2d, 0x86, 0xdb, 0x24, 0xdc, 0x69, 0x32, 0xb6, 0xaf, 0xdf, 0x99, 0x97, 0x00, 0x10, 0x50, 0x17, 0x0f, 0x87, 0x09, 0x79, 0xf2, 0xb5, 0x28, 0x3e, 0xe0, 0xc4, 0x2b, 0x05, 0x7b, 0x0f, 0x03, 0xf1, 0x08, 0x21, 0xb5, 0x19, 0x6e, 0x22, 0x19, 0xc5, 0x57, 0xab, 0x4b, 0x90, 0xc7, 0xf4, 0x24, 0xd6, 0xc3, 0x4a, 0x22, 0x46, 0x58, 0x8d, 0x86, 0x5b, 0x4a, 0xc5, 0xf1, 0xf6, 0x71, 0xf4, 0x50, 0xfa, 0xda, 0x4a, 0xc4, 0x08, 0xab, 0x91, 0xc7, 0xc4, 0x53, 0x70, 0x7c, 0x35, 0x0b, 0x70, 0xd7, 0x45, 0x01, 0x09, 0xac, 0xd3, 0x70, 0x73, 0x05, 0xbf, 0xf1, 0xc2, 0x43, 0x9e, 0x04, 0x31, 0xd8, 0x49, 0x60, 0x8b, 0x9d, 0x04, 0x33, 0xd9, 0x49, 0x58, 0x9b, 0x4d, 0x76, 0xb9, 0xcf, 0x12, 0x28, 0x62, 0x84, 0xd5, 0xc8, 0xd3, 0x5a, 0x02, 0x8e, 0xaf, 0x66, 0xbe, 0x77, 0x87, 0x44, 0x84, 0x90, 0xda, 0x0c, 0xb7, 0x52, 0xd8, 0x1b, 0x44, 0x8b, 0xc2, 0xf3, 0xde, 0x99, 0x00, 0x10, 0x50, 0x97, 0xe1, 0x06, 0x0a, 0x7a, 0xfb, 0x0c, 0xc3, 0x25, 0x0f, 0x0f, 0x3e, 0xd6, 0xa9, 0xd9, 0x83, 0xe9, 0xe1, 0x61, 0x19, 0x1e, 0x22, 0x84, 0x3e, 0x3e, 0x51, 0xbb, 0xe5, 0x0f, 0xa7, 0x89, 0x9f, 0x69, 0xc2, 0xc5, 0xe8, 0xb3, 0xe7, 0x28, 0xdd, 0x91, 0x6f, 0x75, 0xf6, 0xb0, 0x8f, 0x88, 0x11, 0x56, 0xa3, 0xe1, 0x76, 0x52, 0x71, 0xfc, 0x34, 0xab, 0xbf, 0xb2, 0x76, 0xb6, 0xbc, 0x4d, 0x62, 0x88, 0xa6, 0x28, 0x86, 0x91, 0xf4, 0x45, 0xae, 0x94, 0xf8, 0x35, 0xfb, 0xff, 0x04, 0xec, 0xbf, 0x6d, 0x2e, 0xd9, 0x3f, 0x54, 0x73, 0x7c, 0xc4, 0xf8, 0xc5, 0x73, 0xec, 0xfc, 0xdb, 0x89, 0xfd, 0x1f, 0x79, 0x51, 0x95, 0x71, }; static void * func_ptrs[] = { TVP_Stub_3d4b725f0b4234d79524822e7c34486b, TVP_Stub_3fc0c32ee41ea0c515f8fbb681e37982, TVP_Stub_e8dbd4fe012262d9da831e0735aa33b3, TVP_Stub_ace6cce1353865d7376caca1f2124216, TVP_Stub_5055344aa8055bc238b79e5f88fc3300, TVP_Stub_8238c542b814acf1a83c00cced57ba26, TVP_Stub_bd2a14ca8c345fd7f151b08d1792fb60, TVP_Stub_16d432f9f86738a7688cbfc9b12441ec, TVP_Stub_6dac00582b8ba529e548ef058c4e869e, TVP_Stub_9193ae470b5efdfe617b5e94cd8f5da6, TVP_Stub_ec455b6ef0f5da178063db3875973260, TVP_Stub_a56aaf685bd171b63b0ef3c894d80ecf, TVP_Stub_9a5fe199cebb9841f94ac0bb7a4a3b6a, TVP_Stub_2acb76a1f86e34afc5fe934d406c6c4c, TVP_Stub_3a4d914ca7d24989c236ad223c002d49, TVP_Stub_8fca7d3a123df1eacf228ba89f6a02ff, TVP_Stub_58be195f96a36c158d638e3b0c79308b, TVP_Stub_eaa4d5b1d186a807a63311ab6d5e16e4, TVP_Stub_246f30d208c1d3a4e2b558090f403734, TVP_Stub_3206ef9b7a8013d6572decdea49e7e2e, TVP_Stub_c5a30d297c3a121879b1392bc6c604ef, TVP_Stub_e398f5aef0ab92bc1323f3b094722fb1, TVP_Stub_0733b0ac80880897d327dc6f3b04ea9e, TVP_Stub_4cb055ed9d8ef71d1af10898965c940c, TVP_Stub_ef8d198596b7d3143d02ed4450ccefa1, TVP_Stub_d48ea419e040ffe8c20c1e86d80c9a5f, TVP_Stub_679b215ff76a269871d5f325b981e561, TVP_Stub_1039eff4a4443f9238438485a35a93a7, TVP_Stub_2f873b0ee1c6591ba28bc4b9c0e4c954, TVP_Stub_a583ffb56cdb2ede691e15053a8a165a, TVP_Stub_e09ed277802c1b117e1908421448886d, TVP_Stub_e76dfb9e00f4a9d491117d815f30db7f, TVP_Stub_b000dd8934508d8ec6d6ef976a6ff49b, TVP_Stub_d98ab5c968ebfde4e924901d09190774, TVP_Stub_661e8c10d5d477e6823a840244937cd8, TVP_Stub_6b39e70ea89c4f883689f51289029b69, TVP_Stub_4a18b1c0afe37b84e2b35a7fc07c4e0f, TVP_Stub_48b85c8774d91ca40b2992f0e452f19e, TVP_Stub_5ea8db9a9193fe6bab53baf2bee06b6b, TVP_Stub_46b92626ff6894e993c4f193a129540b, TVP_Stub_6efc1d1f66f0e01a81faf767d7576816, TVP_Stub_4ededf58eae77c320b4a6f5f701acafb, TVP_Stub_028d5fda2f4568f6ab14b49d89650a4d, TVP_Stub_11912984b8c094d2df26bf3c3677d096, TVP_Stub_6c0df790c33142e286aea9af6993d931, TVP_Stub_c27d85b695cd6e144210785bdfd446ce, TVP_Stub_8422ef7f42009be0ad58a09d64149051, TVP_Stub_ee07e6522577952453206ede39cdf54c, TVP_Stub_786a65424247e711f6ca31f0a10603d7, TVP_Stub_995a222f2038dd2007f2c1f6429bd19e, TVP_Stub_da8c6e750d6a9c0557a56ef7f7fd8e88, TVP_Stub_9cf7b0f119bcf3fa4564837ae25429b3, TVP_Stub_17cbcacad2ed350215d7d700c676ea40, TVP_Stub_2bd375c0598e9148d88579a51b2f07a8, TVP_Stub_4d2c157f8b0b49e57c3e9b5abc9deb0f, TVP_Stub_4b7eaccf64af0f3a4c4fe64f4e2dd3fd, TVP_Stub_3a4d2602c392a8d1f4c38d537a8c95e0, TVP_Stub_8d915d35ef8e857f245c5d46798618e4, TVP_Stub_1e463482afa8ca30f5fa7bea4fa5741d, TVP_Stub_fdf270e4080c986abd1649fa9fffdeab, TVP_Stub_972e0f9a6ec4648a9fb82bcf5d9095ff, TVP_Stub_9d76731c37c4664d654db026644c64b4, TVP_Stub_4f1620cb699874b9c8cedf6e321c606e, TVP_Stub_ef1c6b2b601d1b0ff70272a4d447aa3c, TVP_Stub_9b7872860c95cfdafb056ab30318e99c, TVP_Stub_53360f194a04fc142ddae2b9a3ab4c92, TVP_Stub_ce1dcb05e5e7c4cafbc4ed37f63b256e, TVP_Stub_841ce4492b37321eea0c1b500de9b352, TVP_Stub_61785de870894968cd9d95e17e88eafc, TVP_Stub_ad3236e727398311c3b8e1ddd5f4b293, TVP_Stub_80e0b7be488545ff9b8bc52c9ab5fba5, TVP_Stub_4eaa3e4efb319707db6ef81db1c6f147, TVP_Stub_693a0152f098caee7fc77f545dd3e954, TVP_Stub_42840710f5fba9bb32b95290b1796a55, TVP_Stub_adec3f9ef429aa9a284081f0fc6a1b5b, TVP_Stub_674a7948152a1d7a49050b9d98796403, TVP_Stub_aa6f132b2031c83062f6149c90f2df5f, TVP_Stub_b52f446e22bb92d495f7e65ac71c9bf9, TVP_Stub_d4899fd4a8beb06f192dcb1d300e3319, TVP_Stub_d3f5ec78464d29ee6988a1f90c2e3e1b, TVP_Stub_a463ad6a757c3f04e09a72e288737d06, TVP_Stub_27857bb89d35113183b682c3917d6c7a, TVP_Stub_a5f80951cfb882ac6a3e06c0b9a95807, TVP_Stub_35aadb63079c8bd84ebc0389bae306e0, TVP_Stub_fb6573df5887c2020ae58136f8342ed4, TVP_Stub_86c67d2197c46824ab10f59e568ad13a, TVP_Stub_263a0c5b335b2c4d5bc1f55b51b8315e, TVP_Stub_975c1099e57ab67122ddef0f44fd7dd5, TVP_Stub_04493e5237a7ca97afd391cb7e831ba0, TVP_Stub_9996100acc7705cb2b0c904d6bad4401, TVP_Stub_5d91cff3b2a26ff7c0543e0f6d737117, TVP_Stub_ef1dedc2cb58dc4e1afc14238b6fc518, TVP_Stub_f18397fe81c043ba2346e31b359f6a73, TVP_Stub_2ee45ad60b0c06a8d0feebc3a6aad9e7, TVP_Stub_44500491c57e17032951fe6ed268ff1d, TVP_Stub_056f5d278c75750df792bf8b081fbf7d, TVP_Stub_04233bc4f7d4df92c260d23110320afe, TVP_Stub_cdc475c4419e77c22508e337428c4074, TVP_Stub_06bacb2910308a47bbe27ff7efa1226d, TVP_Stub_521e053199a4aeb4e0f24d9f4a6cc682, TVP_Stub_02164e6fb4c925843ac774ec1e4c6e5d, TVP_Stub_5110cbbcddbd9688281ee5418e3f9023, TVP_Stub_1db54b61f00bf931452218c4a39e79ef, TVP_Stub_9d0edd8f51f155767301017bd3d256da, TVP_Stub_8f744c5aa8df5471939b960bc759f12b, TVP_Stub_ba7ff7b0b4192bd2cc7f49c7b688ad57, TVP_Stub_7773ac921bb82c85de3be69ef86265fd, TVP_Stub_114a781ed71edace31abb352a2671f41, TVP_Stub_2bc5f4a97decfa82c625430479ec512b, TVP_Stub_066fb79f94523d95d12480f23c58cc8e, TVP_Stub_803906b8de16ff825d4e69e1952d872f, TVP_Stub_34cc96a5118ee1e12b0750ea64d40b1f, TVP_Stub_dbe821fb8b651d42a9c8e730517c408c, TVP_Stub_8970ba46068ac74746c3e84299937d8f, TVP_Stub_438e27dcbb077284213eb4d7dcd43f8f, TVP_Stub_a98d712ca19a49afe07d0a7c5d064cef, TVP_Stub_08aef69683bcfe2a5c63d4c7866de8e9, TVP_Stub_dbc9bc2e27068c8426b1c6a7f89424e0, TVP_Stub_5eeb98ca016123f57966457533bb639e, TVP_Stub_98fdc846d0b4a83412f3521f65bb98b4, TVP_Stub_3309591d3c7f6f688e81588f169dba21, TVP_Stub_d83a866389246d824efcc83303a04484, TVP_Stub_6cf6f332a6a14a15e8dce62301f5c840, TVP_Stub_566eeea3c5f009b0fc6fa123ba30f496, TVP_Stub_88806e38e35c73b36acadd4061a4fe0b, TVP_Stub_3bb69d3886159aaecc333b6ff17287bf, TVP_Stub_3e36278551a9c8b29cb2e8017db6af0d, TVP_Stub_5de99d84f3dc902cb0812fb85a7d5c88, TVP_Stub_31e85cbc73f8fbd4cea895a751480059, TVP_Stub_6ae29e405ede762f1a89a9dd526cb36e, TVP_Stub_c95bd66d95c153cdac41b5243e555f5f, TVP_Stub_72a67e9c52fd27dbb66eded47efeea74, TVP_Stub_fb13e41bda53e4e59403e3e14effccd6, TVP_Stub_9a5c710e620e47f105752453ad5d6ab1, TVP_Stub_18f1ad16c11429707cbf8ea4d1d4a21e, TVP_Stub_550f317b573a1256af00586890ae82f1, TVP_Stub_cd50da721dfb63f36c1ebb1226830428, TVP_Stub_fbba3dd6a087599d1277ae58f6cec18e, TVP_Stub_43cc5b5a61a6090af83333d115b5b868, TVP_Stub_616fb5060d81eb5bab58647596582df4, TVP_Stub_168cf4c1b9ef70b98f2e0ab3695a4f3b, TVP_Stub_314573cca30a7c2aecc9166fbf5400c9, TVP_Stub_03da356426c038fad663c836c3e330ef, TVP_Stub_31dbebdedc08d75e34a2cd564ce60586, TVP_Stub_d9224ad7a0de743a7eea15fdb2c5f934, TVP_Stub_c01b0720b49ce4f792446d8965d2c31f, TVP_Stub_4af47e46a11e1357cb994f405289d13e, TVP_Stub_25b6dafa19bfa5bde1a8b519da248f82, TVP_Stub_72425405819c900aec719491cbd90c6d, TVP_Stub_a79942af73f33bff6e432c9fd808e469, TVP_Stub_df106470a4141ebc7eda22160859ffdc, TVP_Stub_469bc225b0ecd9561aae5a46b85ded42, TVP_Stub_a6663c078b3aa79b39ee2d09f3875765, TVP_Stub_efbe634ce4f13633e220cae167cf63fb, TVP_Stub_57f4147bcc09e4e4442ffc9b0895727e, TVP_Stub_1fb2d2e44cf83aebef7b26fd6b20bc2b, TVP_Stub_bd6aa777bac947f5cffd891e9c724794, TVP_Stub_83c662330b75d616cdc8a4e11d7ababa, TVP_Stub_bbde02fe30c8a6cadb7073174ea3a874, TVP_Stub_cc1c14f63867f90bc883de03e9212cbc, TVP_Stub_236e007b32bc2631b5f6dc1eda6be0a9, TVP_Stub_cfbb9809e0e6d954b2652856e935ced9, TVP_Stub_60ee96ae4a7704340bef20fb35ba6ade, TVP_Stub_564b37278b50f4e5597dff6540868d49, TVP_Stub_890b3a4831b824653e919b4a5197358d, TVP_Stub_2dfa6c77c5051d160b8a06f540e0d68b, TVP_Stub_05f88567d510fd84659ccbf493f647ed, TVP_Stub_7166b8f7bb9688c980e4fa172f06f30c, TVP_Stub_b9456ecba8b7898d80d2e5caa64035c9, TVP_Stub_dd44464bd8430a5be5fef0cffcd97117, TVP_Stub_a57696ca0c157cd7d3cd4e58c1df957c, TVP_Stub_1aea9f8a38bbb875b6d052f330da9178, TVP_Stub_2d3b3d6e22ee139cda9eee47dc031945, TVP_Stub_8ff49e56c3c4c566561dcdd5c9ecc4db, TVP_Stub_490b547e93e40082d0b83312467104f9, TVP_Stub_2c1ef06748df47df52b586ac0fbc6a34, TVP_Stub_b6b2a03160b88239eccd18d89b1537d3, TVP_Stub_8becefbd52c76c7ecb0ea7b7f50b7915, TVP_Stub_74b9687a3bfd3b2c7abe226efc4225c1, TVP_Stub_7cafc2bf5965b594e60830e3057bbd58, TVP_Stub_80f111939c5694cbf43d07cf0ad1726c, TVP_Stub_8dc9cef84191f79b38403a2070952fd4, TVP_Stub_1d42bd1e659b36886c20567497b7ee96, TVP_Stub_0848fbdc7eeddb12c80bcd9c31383a64, TVP_Stub_1f1123c906c28ab6d16b6bef3f7ae978, TVP_Stub_b84394e20cc73a90349cf5be4e783111, TVP_Stub_76e0db3797851fe8ff90cf84780c50ad, TVP_Stub_6616241156c22bced42cd9f2f647677e, TVP_Stub_1ace346a3dd546c66ad115a33d8cf693, TVP_Stub_96fb9bbe33531d4268573355c658e165, TVP_Stub_c90b5737134c76f9ed0bb5da7cfaad8c, TVP_Stub_070ed05259a265cabdd82bfedabdd638, TVP_Stub_008b7e3a4c5bb23ee991f684a5064737, TVP_Stub_b64741dc4544ed43c44ddb6d0eb838ea, TVP_Stub_5b83e28b2d9ab0f75d7c7f6f61b5ded6, TVP_Stub_b948c9f43837efa489b0b91f3f675710, TVP_Stub_eb83216f6f718245468ef48b97ab4c2d, TVP_Stub_c66ab4868b743de9c0ba8b26c67b23da, TVP_Stub_586e16d502a6ad98b08161bdb090f8b6, TVP_Stub_d8bc9c71c80b200c39b29167d795cad0, TVP_Stub_85df4beb87f6503891e116ce046353c3, TVP_Stub_35b6a7e1c73f257aae91e05fa9826e84, TVP_Stub_a25b46701e25030af1ed847e0df229eb, TVP_Stub_c8906bf1efa5e86f9fddfab55a01c8f6, TVP_Stub_8141059f613820f694608af28e20cbad, TVP_Stub_cf2690e47099ac6378ed50df4a8a8e90, TVP_Stub_810c7054e44f535cf250f00707105417, TVP_Stub_52a9af7905ddc71d8b4e0ef7366eebdd, TVP_Stub_1635dbae2d91b338ddfd0430f8aa7f10, TVP_Stub_30df0c29ad8f672f7fe0742b4b11cd7f, TVP_Stub_61c82dec644c58290a25f34a69478870, TVP_Stub_f08e347d2d47dc5fc9a3cb59355b4fbb, TVP_Stub_5c62e59c2062f658d4c79d5257a9a586, TVP_Stub_259c72d8bfed1210ca71c54f24cacc7a, TVP_Stub_801a92ace08eb7ed001406869a39a75f, TVP_Stub_e22e647af4ded8e51b1e76c845b4c8e2, TVP_Stub_12902221314df9bcf7f7cb74a5242fe0, TVP_Stub_b10feea1619ba8ac11237c12002cdb3e, TVP_Stub_19755b50d241edcb477bdcac22663778, TVP_Stub_040a0ecf46963e094ee8ec32ab3f1962, TVP_Stub_525c529dc687b5d86424d775d00bdfce, TVP_Stub_c96107b91e2a215f560a2612c6e85931, TVP_Stub_b8788eaa2ca495263c6ea2df264af5f5, TVP_Stub_4c6494008c520d896d699f82aca30b25, TVP_Stub_7d8f8d5e0832ecf248b19a89801ead0e, TVP_Stub_70849965060a6402f41b0b11ec2bb3a7, TVP_Stub_c72efa6b4efaa6664ae637a03e98e866, TVP_Stub_a250e46575d0df1166e1542613218a5c, TVP_Stub_a7bcff67b8d380c225b9d0d83921b3ae, TVP_Stub_fb68a3aa16bd2eb7d7550283170321bf, TVP_Stub_35b4299ede11f511b331b713ba9f38a8, TVP_Stub_efe52691cff20b2dfaa16e8e16caac0a, TVP_Stub_38eed43ef69251c34dc45695b8cf35c0, TVP_Stub_2058b65abdfb7598910f0d584d40a19d, TVP_Stub_1ebecaefe2ffdc811fccbac42e67e544, TVP_Stub_09e0f0912f8d758d3736ece9478c2686, TVP_Stub_23d61eda3959b087b618e348471e2c36, TVP_Stub_e99b22c79b5bf04f3382f959c7bb69ca, TVP_Stub_9c4bb9ebee4db0fcebeae11c34950f97, TVP_Stub_505a9563aeb1b0255cfcc8197bee7d9e, TVP_Stub_f5ab80fc67ee04570330b9035144e760, TVP_Stub_af50188bbaa019ee88b19ecd931f7cce, TVP_Stub_268c452e85a6ac75301a6132f4f5e38b, TVP_Stub_646770a19b1768b372c9991ef0d3de85, TVP_Stub_5ec88e04fcb8e1877752281e172173ed, TVP_Stub_923f8161f2d2ba0e883bc4edc2901960, TVP_Stub_6f70cdb7586cbe571204f286f43c9780, TVP_Stub_9a4eaa6a627038799015c093609bdde7, TVP_Stub_c8bb6590f4a7adc906d7b3e42d907267, TVP_Stub_8323d57f26876d87271dbfa257b7f7e2, TVP_Stub_4d6f148e8997e1ae0cc0006ec1bd9618, TVP_Stub_7f03a4ddb254d0518642d15513eaea85, TVP_Stub_4add3926c72ba9df9259be58b680de0d, TVP_Stub_075d42cff8dc0c1fbd99c7459a63e526, TVP_Stub_b6bc45b28e194c7ac98bfdea88edee36, TVP_Stub_6dff6abb075da1a304520e60c011ef7b, TVP_Stub_892ffbdb8375851fc557e4abe9589b77, TVP_Stub_b2f3538284fc2adda2a43272ee654a96, TVP_Stub_e0ff899ea4a9cc49a0e3b38deaf93b45, TVP_Stub_4b9c9ac2aafad07af4b16f34e9d4bba2, TVP_Stub_c2e423356d9ca3f26f9c1d294ee9b742, TVP_Stub_c07314686fdf5815ce9b058020da942b, TVP_Stub_4a197be1985d45ee86d5672d24134560, TVP_Stub_dec720a9c3cd2b378f195cf71a9ff8b0, TVP_Stub_5726a5c7af641ebaa504dc9ec8380938, TVP_Stub_1c53bc96ac9dfd483c2227bc5fa44825, TVP_Stub_1940c8fa03145aa029d0b7718ce0c809, TVP_Stub_b37f047c0f9bd143b34a2fc87ce5f16e, TVP_Stub_dec35fbd2a24fc32e5c220174d864cf4, TVP_Stub_86fd45a126296891aee413388597203e, TVP_Stub_603243e54f3508c37d993e8359b735dc, TVP_Stub_c3eadbd75b32dabe6faecebf492eb486, TVP_Stub_725e49de1d970ef04b179776666f2c34, TVP_Stub_55a9b73f877bfd4c6d8157e7b1c458df, TVP_Stub_d070209f152dd22087e6e996e02c85cf, TVP_Stub_308f905626bc51c7ef9b65b2c0ca34b2, TVP_Stub_95aab2a1ac9491e8026f4977e0918760, TVP_Stub_e0ac94325eb783ca2fe7856a54444c90, TVP_Stub_0c99a79e866f08b4df3914e83fc203dc, TVP_Stub_f2de531a016173057ff3540e47fed4e6, TVP_Stub_4224a9066d8d13d6d7e12f1ace6a5beb, TVP_Stub_900476efbc2031e643c042ca8e63a3d7, TVP_Stub_07dfce61d490cf671a2d5359d713d64a, TVP_Stub_52d30ac8479ef7e870b5aff076482799, TVP_Stub_8e4d0392ed46e87f94e5fcf675a124a1, TVP_Stub_73f46e08d17e707725f433b454f05a89, TVP_Stub_80d60e682fa72973071e335db272a2a2, TVP_Stub_6bd6262185fa0b9cf1750f6a525d893a, TVP_Stub_cf29f737d4eb450b26789d421d0ec69a, TVP_Stub_13c0e371c08fd1b9da2f0c103d01c59a, TVP_Stub_82693e38df8f033ea98f9b7969d66d7b, TVP_Stub_6e3f8a3b18f55dae6153a889f00a3e87, TVP_Stub_efe14a197131b4813656d6669cc3475b, TVP_Stub_ba4ecf60f872f757b69c84f457b3e941, TVP_Stub_dffedabe32ce886e3b7e695b44ad3547, TVP_Stub_f518c60b165658d19a0fadd8f69586aa, TVP_Stub_6fefcb1c2ca01a876c301ab41dbdab9f, TVP_Stub_df55083347df0483b4ca6ba1e4f0b9a0, TVP_Stub_d8d28310f702714733c4c5dc850058df, TVP_Stub_52d24c38b05be174bc5c4fdcf02e9b9f, TVP_Stub_f27f455c8f30cbaf1706faac3c7b8e02, TVP_Stub_78ec453a50b2800bb01347e8ebbac000, TVP_Stub_0936d0f6fc53339d255893e58bcc6699, TVP_Stub_f4f7181b7fd679784c50b0cc7ba4c60e, TVP_Stub_79816d7e5741c2416fefe2c2a8baef00, TVP_Stub_42a3d248fab928f16555abcceca62834, TVP_Stub_926d6212b8b1b238e7bef9b17a3ee643, TVP_Stub_236e3d626784d80ca2cc5b2fe14cd9c6, TVP_Stub_1bfac11a5f95c842f97a8bb57d4019de, TVP_Stub_198ce21c54b0cea4c1bf5eeba35349ab, TVP_Stub_590a1ec7f64904eaa32b5c771bb5f8cd, TVP_Stub_dd13d4bc2b48540a92f047bf015b829b, TVP_Stub_0ff502d492598d2211405180bfb4d1e1, TVP_Stub_cf5401746759bfe38918087aaab6c57b, TVP_Stub_04e84aa7d8cf0477d55c700164544b38, TVP_Stub_449039d3afbfbd52a63130a3b227a490, TVP_Stub_347a4fa85af84e223c4b61d33ead694a, TVP_Stub_4ad1dd24b3b4769ee10149eea006af7a, TVP_Stub_b246b17b62d273bdc04e9d9e827f5c74, TVP_Stub_9974ebc6296f925cff55d8bcb2d52ce9, TVP_Stub_0e0c9d9107d8c56b8bc4d4198ae9208a, TVP_Stub_c23ece207f6ec2dd7c76ef873047aee3, TVP_Stub_81507020bc646be2f53ab95b9430ba27, TVP_Stub_acc0d3861d1b971abcbdda1c075dd681, TVP_Stub_ff2dccead1b31e3f34e8be3e2ba5bbf1, TVP_Stub_e17db0d4f69625c61aba7fffe540dded, TVP_Stub_5bbc872e7bba5b761c509d31116e4460, TVP_Stub_4adf361303eae78829250c7b732a5722, TVP_Stub_bf172364c57c1aa561b145fd5cacda0c, TVP_Stub_d7687aa80dac10f88deac7aa7e70538a, TVP_Stub_b18b7259f98029f745c75291d6855ab1, TVP_Stub_b79e5d877116025576ca1f76af124009, TVP_Stub_8aea098dfe8a36c705cc2a9e1a189b84, TVP_Stub_4ccd3f6ab60d61be6dbfc59e8e3d1726, TVP_Stub_3d70bb72a7d7765c7e8ea580079ab7e9, TVP_Stub_eba9b272d78a4b0cd7f9212e29a58607, TVP_Stub_cfbe8ee9d43aa64ae4190eac91f7c55f, TVP_Stub_a4308a386968ef5d23025ab8a9e8c6db, TVP_Stub_5a4fcbe1e398e3d9690d571acbbbae9f, TVP_Stub_5b62f504fe6d22428d7518d6c52d775d, TVP_Stub_fb3b405f8747b54f26c332b9e6af81cd, TVP_Stub_b7ccd11d130f186883c109d2ba17b598, TVP_Stub_cf8ab6c24f25993ccc7663e572ac2991, TVP_Stub_ba40ffbca76695b54a02aa8c1f1e047b, TVP_Stub_c97720e639e95ba5130ce9dd78d30403, TVP_Stub_c5557ac5391b1b831a22e64b65d1746c, TVP_Stub_3243a4c32d4f674f1bbc8d3895257568, TVP_Stub_78390a3d08879903ee9558e9df68db4d, TVP_Stub_58e9454d7096a52808f9a83b9ce25ff0, TVP_Stub_cdefadd0c3bf15b4639b2f0338a40585, TVP_Stub_4bf80e9bac16b9e3f9bf385b2fbce657, TVP_Stub_51aeacf2b6ef9deb01c3b3db201d6bf9, TVP_Stub_9ed5432d73448da47991df9577ee97bc, TVP_Stub_cf1d02d1cc1aff0aae6c038c95dac80f, TVP_Stub_ddb0e05c72c0692e78af885ac7ec82dc, TVP_Stub_a3029db6292616cd16c228b91dc4af13, TVP_Stub_2d90871c6bc15a9e8d97d24c29e78e3b, TVP_Stub_0af6744e35e38276d6a98c1f382b1519, TVP_Stub_ad40567a051208757642e5e087f3e741, TVP_Stub_6a15185daab9b274963fe5ef46305775, TVP_Stub_073a2332a8ab3ed31ab81daea3d3f2c4, TVP_Stub_01216e91225e06c7422bef0c2febc0cc, TVP_Stub_16ce22ad500a5bdfd5d5743c847a28b6, TVP_Stub_59251c4104f736fa2690c5f77fb0a908, TVP_Stub_f923750e0fdb51a6fc6c304832cb3dd3, TVP_Stub_bc77a1e312ff7827d90387fb92f0f5b0, TVP_Stub_2090afd7ae8bcb021ec4d04947d0d845, TVP_Stub_3a0f858bdf86199dc2d00b583a3b915f, TVP_Stub_0d316a141f7a502ff8d9ffe2d38d25a8, TVP_Stub_b31ff64ae2d8f93dbf28161d5080b295, TVP_Stub_d9b1c73516daea6a9c6564e2b731615a, TVP_Stub_003f9d3de568fcd71dd532f33d38839c, TVP_Stub_5da29a19bbe279a89be00e16c59d7641, TVP_Stub_c1b52e8f3578d11f369552a887e13c5b, TVP_Stub_b94ead6de9316bc65758c5aefb564078, TVP_Stub_8a35be936d2aca049e398a081e511c97, TVP_Stub_5b1fa785e397e643dd09cb43c2f2f4db, TVP_Stub_29af78765c764c566e6adc77e0ea7041, TVP_Stub_9e0df54e4c24ee28d5517c1743faa3a3, TVP_Stub_d3aaa55d66777d7308ffa7a348c84841, TVP_Stub_b426fbfb6ccb4e89c252b6af566995b8, TVP_Stub_c145419db7b63f7488ea05a2a8826c1d, TVP_Stub_d795cd5ebfb6ca6f1b91bafbe66d7a65, TVP_Stub_4564a3ce5cf48cb47e63a3948cef03be, TVP_Stub_bee2775f2e4042043b7cb08056d2ae5c, TVP_Stub_5fd8dfd2816a2cfd4a51cab41053d575, TVP_Stub_9982ebedc12d343cb098e2a7b25bdef1, TVP_Stub_81eeacbed5ee6129bef4b370e28b5d10, TVP_Stub_6ed1088905d99012d2fb5827ea19527e, TVP_Stub_b4d6c64cc0004ffaba804f0e8f02ab9b, TVP_Stub_2c3e08b8df93ec50451edd916c707030, TVP_Stub_eba070d1583ca5f5d02630ba33a5504b, TVP_Stub_ee474537852ce5eb165cb1761950faba, TVP_Stub_eed221c603243522667e2f1c6ace3ba4, TVP_Stub_1f973c5e3cfaf00fa752b7e22d7ba481, TVP_Stub_b9d5260bba9edd7503f1adf882218979, TVP_Stub_aedbd2eda61145de808e295331884245, TVP_Stub_ce0f184e84752eb279e4f900d8b53c18, TVP_Stub_0217d49393163b80897d044c1d93092f, TVP_Stub_5bbd9d5b364840e9615af35a62f69d7d, TVP_Stub_2b2837e81fcaeec35f61a2a3ecf2fb2d, TVP_Stub_bb0706a78e9066944bfbffd1406be2d4, TVP_Stub_770e67c91215292980b88cc6efb9f2a5, TVP_Stub_068ab11f05731f2c2e9ea8c5fdb16a9f, TVP_Stub_b9873a0ad2653952cb2948b817e786e4, TVP_Stub_11d9804ae4db32d731af69c397769cbf, TVP_Stub_421f5aa6dbaaaf946f74942c77aac9bc, TVP_Stub_563ee9dcb14a2914fc246e64679f42b5, TVP_Stub_e23a54b6b80bd03111a40f669524724f, TVP_Stub_c90c8bbd18a7190636ae4269c36ad005, TVP_Stub_03c54a8e8c86e171f868a624e490691f, TVP_Stub_30b63f3cc59b39f1a71829bbbdf6e45d, TVP_Stub_705bcc30a0561ec679c2267e1a573b23, TVP_Stub_5c627d080007e455b0393a9b4457cd4d, TVP_Stub_72a64cecd44d80f95fc93faf0d239e32, TVP_Stub_ef838904712bfdc614dbc689fbe7fb18, TVP_Stub_acc97936adc40656e824cfdf7a34e20c, TVP_Stub_5ea1ba3602f9d9fee344de6c3406d7a3, TVP_Stub_d25f0771b8fc7715d69f01d950463a49, TVP_Stub_f8ab11c930782ce058e517d0440ec87f, TVP_Stub_b8157e369d53c2d944b76494980ced7b, TVP_Stub_aba94f656b4c1de827d11c72b36a5e9c, TVP_Stub_0656942f5a95783a4de73ca6e654d3b5, TVP_Stub_5c2b7d12713dd5a94ef8e6eff1f79752, TVP_Stub_6f1d30ac7e812cc5a059459c47638cd0, TVP_Stub_1d51684322635e7848ef53f7f6be8a1e, TVP_Stub_a1f2d56d138a4038fe1678328910a81d, TVP_Stub_c135ef491b533febfd49696d22a1dd3d, TVP_Stub_579117a873b466d78bf93e49c4a078da, TVP_Stub_ec8fa08705639eb7ae5d44ab63dea5e8, TVP_Stub_b49dc1cda6109256815dae7b4293725d, TVP_Stub_912a670f56707ac70f2fee13660c2af8, TVP_Stub_d0159986645df76b8c66fdb662efffde, TVP_Stub_cd7a2e6f91bf8d2daa3e28139d7d9f5c, TVP_Stub_676004ca892b2bfee6859d0bb132fdd7, TVP_Stub_d4b161d8a745baa5e2113669773a758f, TVP_Stub_ef7537293f6e3b6127480f6c5fd018a1, TVP_Stub_6f6f73b75cffe40a28566d1832ae1224, TVP_Stub_7adc5aad39e459e01543d07c239efe57, TVP_Stub_3ff6b480097eec3f5fdb7bfad685fd2a, TVP_Stub_b2c50c3a1dfea7e9d05fed69818bafc3, TVP_Stub_8024df9077e2c85b5b718ad2c87e57e7, TVP_Stub_989769d4eb8e42e9c9bbe721b296406c, TVP_Stub_cc1ac928b5c31570dfba7ed8f565be4b, TVP_Stub_62931efed5729a332e60bd1f7c7cecdf, TVP_Stub_53c18160b157088f72a9afd79737b48b, TVP_Stub_48135697fd7f4df87402a7dd4d761555, TVP_Stub_e2c71cf04e876069eb7315c800a96898, TVP_Stub_1f63c018cf805ca1168af192cf8a4b41, TVP_Stub_704a9574dafd3669e10d546549948e03, TVP_Stub_97905c510b9502c20c9322c9f5fb4188, TVP_Stub_b23e84230c4736667279c7a71f4ca53e, TVP_Stub_eb41fc900b0a6e3aba9d531f266137f1, TVP_Stub_5bd02c627b74bbb22d5a525b8bcbbd27, TVP_Stub_cc82e6a6b31ea743b9ebbdeed1ddedc3, TVP_Stub_247b25d497e48bc0191fdb2ac530f4ca, TVP_Stub_6bbea3af36c35631641cc8356ff65475, TVP_Stub_cac02dfd62ba94abf6a346bef0bf3ab9, TVP_Stub_68eeb36d76d88ff00014f04b23454254, TVP_Stub_65e03b1c849b6e9cb5c478024aa9a5b7, TVP_Stub_7670c0c5630625ee6a73b7b9ee093650, TVP_Stub_68a0abce6eefa08e74353ec48c4c87a8, TVP_Stub_ccb6e098b9a0791a0f20e9f1af55e341, TVP_Stub_0f817efe47b451fd719c05a104c2b803, TVP_Stub_efad1a3d774747bd2b5adb221ede2678, TVP_Stub_563285ed004ddd2945f91db7b5347d3c, TVP_Stub_4c032260ef83d44bfe05fdc16843a8f9, TVP_Stub_96fd614457f06499a430b0c6e0e8a941, TVP_Stub_d6e36d304ff7253088ab4bc1aaf13a98, TVP_Stub_eddacf49735189e23d9d49831851ffdb, TVP_Stub_20275a5de4aef464b85d3f6db2800063, TVP_Stub_872d1c626e6d4e3d5e86a257f0b14536, TVP_Stub_a7ebb70cdec339f26c2ea7fd9a471b88, TVP_Stub_d748ffef5cde2a6a3333e75b7fa3fb49, TVP_Stub_15e1fe0e6230e7b60e216e266f927f7b, TVP_Stub_f8179eafd0cbe8116874310519207dc0, TVP_Stub_accbc3bed3223d552de2723366cfc2b6, TVP_Stub_e2c3e74d2a20a601c1f393348f58aeb2, TVP_Stub_e0163a6ca3397c2e71715132cccefa1d, TVP_Stub_2c3ea1ea88799dfde81025bf1959333a, TVP_Stub_a6bb56b3f4b7a89fe78d63956a0f444c, TVP_Stub_09a81ac18a121d8fbb67285a081bf9c6, TVP_Stub_46fdfe0f5369bf234c3ed60a43947d9d, TVP_Stub_d866cb6c8a47444bbac60eeffbfc6d96, TVP_Stub_7b5718fc67458089c685dbb900126890, TVP_Stub_5713dfe9525662357d3819229e0204c2, TVP_Stub_8954a6b4a7f8b378c2af16a00d5059b0, TVP_Stub_2ed4faa38db6f3dee0dea18ebe973d35, TVP_Stub_d0338dedb0af532d22f2075a85373548, TVP_Stub_583d57c3bb9491f8f9904c266d3f52e8, TVP_Stub_8ac206da43e322eb8e34fce2b0959656, TVP_Stub_14f5f97d90bd8da89b68d035367f4ba4, TVP_Stub_ac3b21181ef4c1be73cf5e0edb4e1a8f, TVP_Stub_1d7d97509292a4ca9269f2539dcc70fd, TVP_Stub_c4033f54a99517783b8d6ad23c90aeed, TVP_Stub_f19e38d48755c971fc35408ac65562fa, TVP_Stub_e01204e226d8aa9520b3620b68da6196, TVP_Stub_b50000da98f1257cf789fc63fb1fda02, TVP_Stub_c55f38b1a7623646aa5cc45d4f4f479b, TVP_Stub_983d270549ec0e83e2a863b43e1e6f70, TVP_Stub_b48d779dc6a881c67c5f8fa12655aa28, TVP_Stub_d3967c6e24d0c4ad107a03c1cadd57b1, TVP_Stub_6b6f416b5725a7cafb4774ffc3a00f10, TVP_Stub_bc7fc5dfa228152a09d2230823c2fe71, TVP_Stub_a1cb941317b947beb88e29fa8d46a2be, TVP_Stub_8e185e82bb27a7fb40f0b08f560a57e9, TVP_Stub_4b7b264b61ee0eea68213934217f5865, TVP_Stub_e872f12593d6853ebdffebbb5d003c10, TVP_Stub_e86fcf60fa658129d937de3728d3c432, TVP_Stub_350741a7398a187628866f5b397c7a99, TVP_Stub_3b5a3e187077b0b5eac9a040c99dd9e7, TVP_Stub_2d9b2bb2cd57220048fe170f1e960cb7, TVP_Stub_260624e275a20115e8861eb7b0383971, TVP_Stub_15b31724287dbbecb775b2e46dc35fb9, TVP_Stub_ff652293eef07b5a7ec4f372e5504e2c, TVP_Stub_99b773033e9a2c631b483d4d0e3881f8, TVP_Stub_3787960fc29b8545629d894ff46d4641, TVP_Stub_3fc76257bb1639de4bfa0c0fcedf9c4a, TVP_Stub_292ee2eeb8131e34368ba9ee144b737a, TVP_Stub_ec144655bc61bfa2c6e9505cc1a0a298, TVP_Stub_230218bdabfc34178a8306a54276a3c8, TVP_Stub_617dfb046aaf40078ee76715fa4756af, TVP_Stub_8116bb2b26dcafd9fefca76e9f1d9b24, TVP_Stub_12962f857563cd39b3cb1f9894775cc7, TVP_Stub_50c0d25cd9af311a5fb0aca78f691c3b, TVP_Stub_6c37a1ccda816c4fbab4f0117ca75e8a, TVP_Stub_e21c21762dd0e36d6f7d2cedaac97383, TVP_Stub_487ee86557f94113db9a981e08d29caa, TVP_Stub_dfdfe0e494845bf484612cc97145f85c, TVP_Stub_e74dc11dbd56fb450eed1388a65d3102, TVP_Stub_6981c02247de5799ea7dfbd79fdc208d, TVP_Stub_7c559043315f6ecd7a86ec7d8d820f6d, TVP_Stub_3a8b6aca73c83d6fc9ce813661ec734d, TVP_Stub_20d7ce65e240b745b10616bb5da1f897, TVP_Stub_f4d1217249674ac9274d358c381afc0b, TVP_Stub_ca77323bbe361f88f68536018fa94c50, TVP_Stub_17983ecc7e7fe370bce664281a84c948, TVP_Stub_61a2f61030362903d00ba21a3cebecdd, TVP_Stub_e9f985403dbd18540d8230a2af6ed76b, TVP_Stub_be0523c9a72ba26cb4bfa3cb188cacf6, TVP_Stub_8ac7cf651223c8ba53df90cf4f3d3bbc, TVP_Stub_873e73aa35096ad4c684d394a10135a6, TVP_Stub_3342548f105147c86019ae31ece01d4e, TVP_Stub_607ee0956cbb16b2afb7cb2227aa6267, TVP_Stub_816d84c86e86d5e7c0018d551e741e4f, TVP_Stub_985fcda0141eb3b4c6bd8342e947f130, TVP_Stub_d00e4f9e493334d2f65ea379ff03d717, TVP_Stub_0c246e6c7c8798e4c10d2bbfc66326c9, TVP_Stub_501015843a83368b3ff1c7c9ef5f3bcb, TVP_Stub_61d5fc5a060f346752a3a8b6886d17bc, TVP_Stub_0debe3e1caf0f57572a59917851676d3, TVP_Stub_ee3a36682f48639166ba04a19fe1b332, TVP_Stub_4d99b9e38121251b40a90cd2bd5fea63, TVP_Stub_f1509827696ebf5627bee1a45d675fb8, TVP_Stub_bbb625e23229350453161810c41419dd, TVP_Stub_489a6aae30de0feff5d3c5fbd42ae325, TVP_Stub_6b9a349305f8c689dcfdbcea2566769c, TVP_Stub_6320d208ce1a570aca52c3cdf7421f7c, TVP_Stub_0f83f0459badd1cd352041b9243d712f, TVP_Stub_186a94b2fed609ed2d2a7ac1a2bed87f, TVP_Stub_bde8efb9971664f2b52fe912745e2791, TVP_Stub_386d6fa5cb73e3519b62d20470e5414b, TVP_Stub_c61f97ec3d99bdbb23afe93870001bbf, TVP_Stub_f92821f2b23662c6f1256511a626cd3f, TVP_Stub_76b0732e3e2886897d5f26b4b0545dee, TVP_Stub_903ed11ef3863850e837bd4b3b1d61a1, TVP_Stub_2661124b39595ffafe2fb0bfb7bd2efc, TVP_Stub_d0b7170e54398c2f9d27dcc513c4cf46, TVP_Stub_31bdd2a1eed3785c1422fab5ea6b3ce7, TVP_Stub_dbc300d1dadc1a60cb0dcadfb92f1aee, TVP_Stub_1d4d9f8bdf55bd4c78abd90656af0364, TVP_Stub_5c7049e712e84b40ac05942421202de5, TVP_Stub_5dca8992bb340d70ba65ddab65c28371, TVP_Stub_85f1f38f783ebfcf638f3c443bc9b204, TVP_Stub_7d61d143884bfa4b6c50dae11c2b659f, TVP_Stub_793a2ad7ad3411be3670576a8e6ddcf8, TVP_Stub_68d8eec33254f1684e53bbc0aa8b2466, TVP_Stub_b09652d2197b29f7d38aff0298c69f17, TVP_Stub_be7db03ddcf1886cb7233e58f19c8c77, TVP_Stub_b4c8fedc1ffbe30d9703cb2b8d3c0e7b, TVP_Stub_77efef3b4ffc0cb577b76304e06e39f3, TVP_Stub_0e55187bde599d6585eaabd2c4ac3f02, TVP_Stub_f72e3fc3b97a9141b6f516f5e53bf9b8, TVP_Stub_e7a1ac237f00bb6320d0e0ac7e6d51c6, TVP_Stub_d87682f6d691350878077bd101b7f0fc, TVP_Stub_d7ae155eaabd8e65d6b4d356fe4af496, TVP_Stub_be3a1844ea6af533bd4e7b0a76c826a1, TVP_Stub_aa531d2c3c87f456e48a14722faa1c1f, TVP_Stub_6889cd886e1c2e7faf541528636c16c3, TVP_Stub_5d9266e6a8a154fe4ba80b0995e109ab, TVP_Stub_a7dc19b023737979ad1ae1ae01d560d2, TVP_Stub_d20444b7a6243d668a0d3956d95af510, TVP_Stub_1458dec9eee36816c8002d4049840355, TVP_Stub_21137ff5351245b1611852301b7f5796, TVP_Stub_c07fc4e45fc2dc44d839c5e012d0be60, TVP_Stub_6815b962a3122ae967284239932cc656, TVP_Stub_e96cccbe1f16b0fb74673f2ec3343ff8, TVP_Stub_e8cd7494f919b18a992cb8c2722b2bf0, TVP_Stub_990fdefcafc0de5e8e1f502c1b341e44, TVP_Stub_de5d83ba307e822825062377fb76c2ba, TVP_Stub_5e28bcc0f5ad6a038eb5a6535b56386c, TVP_Stub_e33419e8ede4bb501ab1787cf17c7ca5, TVP_Stub_1cd7cb9580c0cf723dea402b85a720b1, TVP_Stub_d18ca17fad389ff60ce3caa769083798, TVP_Stub_0a959a5ff02530a8eb122e7e1f8ceed3, TVP_Stub_a4774ea559e64b4667b3845f8540d207, TVP_Stub_52eae3e8106494bfa604c15492ecb9f4, TVP_Stub_882f458df5e05bb9ab2222e79f6c81cf, TVP_Stub_6069a18bf7d3f394c230cdcf2f574ef4, TVP_Stub_75b60565caf44027cc52b2b5cf6b0ea3, TVP_Stub_9d735149c3ad586363895f76645abf2e, TVP_Stub_ea5168fae254acdd8c8db6f1f3d2da03, TVP_Stub_f5a42bd5239e1a0be29f92eb838d2c8c, TVP_Stub_7cc8cd9f415b183b42c546635aeade7f, TVP_Stub_ad2fefa53e05528f9c1fe29d27db0f37, TVP_Stub_f3e06fed4c82a9bd1b53252abaf50847, TVP_Stub_960db7ea36202bf7ec3bf6b767cc045e, TVP_Stub_7bf5d357eb52dd206a269b54c8136e0e, TVP_Stub_ba1c9b771c5cdb725128de684af3c9ca, TVP_Stub_69cc6311196adc134fd153c4c5346bc5, TVP_Stub_8ed68f8e79efe1c767f92e7d92eb8b54, TVP_Stub_60da1e9ec15b251ff18ddcdf8a3e93e0, TVP_Stub_ef47304bad87a036e38f0319b48c1f6e, TVP_Stub_182d19020e4e2d5cd1462d7c8ef24d1f, TVP_Stub_9e1fa429a92a5c99d397a06c20fd6705, TVP_Stub_74ac7c291299eb928aa4c2899df5567e, TVP_Stub_fb645d9ec0ef3fd2aba2b762ef6b9a15, TVP_Stub_f988626275257574050ac789f9060a3b, TVP_Stub_1831064ed23493cef407648763ba4d69, TVP_Stub_305390c94750daa7124db3ff6e77931c, TVP_Stub_4fb384a391bfcf6a3a2932661d3051aa, TVP_Stub_305537c4820e23cf217a15efb56dba1c, TVP_Stub_aacf83677ca7df75117f7bafa7a53791, TVP_Stub_d14b922fefc6c07aa536b94762579fe5, TVP_Stub_00fd650a79c603bdeb2f8e36f667a782, TVP_Stub_a36ee133c07c30185b0bbc6375954e88, TVP_Stub_dc657ecacf8e578870314427216864d9, TVP_Stub_e79d02b58a8bfdee439bc0694d7edd6d, TVP_Stub_6b7537b66b71d27384bea45bc2bf24b4, TVP_Stub_b3456dbad652b52f5bce1889b6f4d0ef, TVP_Stub_9a50803a03e1ccb60120dff8b92ecdcd, TVP_Stub_0f6b3940dc72e3e56cd15216b53b9126, TVP_Stub_23b647f1c825e214a7465de3ebe9968d, TVP_Stub_8ec96bc7b777180f23e1a2e43bf9a413, TVP_Stub_cffd45014652659638d59abe11daf3be, TVP_Stub_a784285a35b1bc76bb367305b5099e35, TVP_Stub_03773751329896facf2003ab79bbc475, TVP_Stub_923884216edf134d07d8e70f8f57e827, TVP_Stub_e48798dc69498f80b6633bb405eda6eb, TVP_Stub_998a5e1aa5cd85689795348fc540a655, TVP_Stub_5f6d263c0d48d03f6eb0dc44c9dd0be2, TVP_Stub_bf363ba3d5b54df9d6df35a518deb6b0, TVP_Stub_6cc8a24cc7ce23179d1d4ccab7a8c97b, }; void TVPExportFunctions() { const unsigned long compressed_size = 5173; const unsigned long decompressed_size = 42625; const tjs_int function_count = 653; unsigned char * dest = new unsigned char [decompressed_size]; try { unsigned long dest_size = decompressed_size; int result = uncompress(dest, &dest_size, (unsigned char*)compressed_functable, compressed_size); if(result != Z_OK || dest_size != decompressed_size) { TVPThrowInternalError; } const unsigned char *p = dest; for(tjs_int i = 0; i < function_count; i++) { TVPAddExportFunction((const char *)p, ((void **)func_ptrs)[i]); while(*p) p++; p++; } } catch(...) { delete [] dest; throw; } delete [] dest; } ================================================ FILE: src/core/base/win32/FuncStubs.h ================================================ /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000-2009 W.Dee and contributors See details of license at "license.txt" */ /* This file is always generated by makestub.pl . */ /* Modification by hand will be lost. */ extern void TVPExportFunctions(); ================================================ FILE: src/core/base/win32/NativeEventQueue.cpp ================================================ #include "tjsCommHead.h" #include "NativeEventQueue.h" #include "Application.h" void NativeEventQueueImplement::PostEvent(const NativeEvent& ev) { Application->PostUserMessage([this, ev](){ Dispatch(*const_cast(&ev)); }, this); } void NativeEventQueueImplement::Clear(int msg) { Application->FilterUserMessage([this, msg](std::vector > &lst){ for (auto it = lst.begin(); it != lst.end();) { if (std::get<0>(*it) == this && (!msg || std::get<1>(*it) == msg)) { it = lst.erase(it); } else { ++it; } } }); } ================================================ FILE: src/core/base/win32/NativeEventQueue.h ================================================ #ifndef __NATIVE_EVENT_QUEUE_H__ #define __NATIVE_EVENT_QUEUE_H__ // ĂяonhVOXbhœ삷CxgL[ class NativeEvent { public: // LRESULT Result; // HWND HWnd; unsigned int Message; intptr_t WParam; intptr_t LParam; // NativeEvent(){} NativeEvent( int mes ) : /*Result(0), HWnd(NULL),*/ Message(mes), WParam(0), LParam(0) {} }; #if 0 class NativeEventQueueIntarface { public: // ftHgnh virtual void HandlerDefault( class NativeEvent& event ) = 0; // Queue ̐ virtual void Allocate() = 0; // Queue ̍폜 virtual void Deallocate() = 0; virtual void Dispatch( class NativeEvent& event ) = 0; virtual void PostEvent( const NativeEvent& event ) = 0; }; #endif class NativeEventQueueImplement/* : public NativeEventQueueIntarface*/ { // HWND window_handle_; // WNDCLASSEX wc_; int CreateUtilWindow(); // static LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); public: // NativeEventQueueImplement() : window_handle_(NULL) {} // ftHgnh void HandlerDefault(NativeEvent& event) {} // Queue ̐ void Allocate() {} // Queue ̍폜 void Deallocate() {} void PostEvent( const NativeEvent& event ); void Clear(int msg = 0); // void* GetOwner() { return window_handle_; } virtual void Dispatch(class NativeEvent& event) = 0; }; template class NativeEventQueue : public NativeEventQueueImplement { void (T::*handler_)(NativeEvent&); T* owner_; public: NativeEventQueue( T* owner, void (T::*Handler)(NativeEvent&) ) : owner_(owner), handler_(Handler) {} void Dispatch( NativeEvent &ev ) { (owner_->*handler_)(ev); } T* GetOwner() { return owner_; } }; #endif // __NATIVE_EVENT_QUEUE_H__ ================================================ FILE: src/core/base/win32/PluginImpl.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // "Plugins" class implementation / Service for plug-ins //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include #include #include "ScriptMgnIntf.h" #include "PluginImpl.h" #include "StorageImpl.h" #include "GraphicsLoaderImpl.h" #include "MsgImpl.h" #include "SysInitIntf.h" #include "tjsHashSearch.h" #include "EventIntf.h" #include "TransIntf.h" #include "tjsArray.h" #include "tjsDictionary.h" #include "DebugIntf.h" #include "FuncStubs.h" #include "tjs.h" #ifdef TVP_SUPPORT_OLD_WAVEUNPACKER #include "oldwaveunpacker.h" #endif #pragma pack(push, 8) /// tvpsnd.h needs packing size of 8 //#include "tvpsnd.h" #pragma pack(pop) #ifdef TVP_SUPPORT_KPI #include "kmp_pi.h" #endif #include "FilePathUtil.h" #include "Application.h" #include "SysInitImpl.h" #include #ifdef _MSC_VER #define strcasecmp _stricmp #endif #if 0 //--------------------------------------------------------------------------- // export table //--------------------------------------------------------------------------- static tTJSHashTable TVPExportFuncs; static bool TVPExportFuncsInit = false; void TVPAddExportFunction(const char *name, void *ptr) { TVPExportFuncs.Add(name, ptr); } void TVPAddExportFunction(const tjs_char *name, void *ptr) { TVPExportFuncs.Add(name, ptr); } static void TVPInitExportFuncs() { if(TVPExportFuncsInit) return; TVPExportFuncsInit = true; // Export functions TVPExportFunctions(); } //--------------------------------------------------------------------------- struct tTVPFunctionExporter : iTVPFunctionExporter { bool TJS_INTF_METHOD QueryFunctions(const tjs_char **name, void **function, tjs_uint count); bool TJS_INTF_METHOD QueryFunctionsByNarrowString(const char **name, void **function, tjs_uint count); } static TVPFunctionExporter; //--------------------------------------------------------------------------- bool TJS_INTF_METHOD tTVPFunctionExporter::QueryFunctions(const tjs_char **name, void **function, tjs_uint count) { // retrieve function table by given name table. // return false if any function is missing. bool ret = true; ttstr tname; for(tjs_uint i = 0; i SupportedExts; tTVPPlugin(const ttstr & name, ITSSStorageProvider *storageprovider); ~tTVPPlugin(); bool Uninit(); }; //--------------------------------------------------------------------------- tTVPPlugin::tTVPPlugin(const ttstr & name, ITSSStorageProvider *storageprovider) { Name = name; Instance = NULL; Holder = NULL; IsSusiePicturePlugin = false; IsSusieArchivePlugin = false; TSSModule = NULL; #ifdef TVP_SUPPORT_KPI KMPModule = NULL; #endif V2Link = NULL; V2Unlink = NULL; GetModuleInstance = NULL; GetModuleThreadModel = NULL; ShowConfigWindow = NULL; CanUnloadNow = NULL; #ifdef TVP_SUPPORT_OLD_WAVEUNPACKER CreateWaveUnpacker = NULL; #endif #ifdef TVP_SUPPORT_KPI GetKMPModule = NULL; #endif // load DLL Holder = new tTVPPluginHolder(name); Instance = LoadLibrary(Holder->GetLocalName().AsStdString().c_str()); if(!Instance) { delete Holder; TVPThrowExceptionMessage(TVPCannotLoadPlugin, name); } try { // retrieve each functions V2Link = (tTVPV2LinkProc) GetProcAddress(Instance, "V2Link"); V2Unlink = (tTVPV2UnlinkProc) GetProcAddress(Instance, "V2Unlink"); GetModuleInstance = (tTVPGetModuleInstanceProc) GetProcAddress(Instance, "GetModuleInstance"); GetModuleThreadModel = (tTVPGetModuleThreadModelProc) GetProcAddress(Instance, "GetModuleThreadModel"); ShowConfigWindow = (tTVPShowConfigWindowProc) GetProcAddress(Instance, "ShowConfigWindow"); CanUnloadNow = (tTVPCanUnloadNowProc) GetProcAddress(Instance, "CanUnloadNow"); #ifdef TVP_SUPPORT_OLD_WAVEUNPACKER CreateWaveUnpacker = (tTVPCreateWaveUnpackerProc) GetProcAddress(Instance, "CreateWaveUnpacker"); #endif #ifdef TVP_SUPPORT_KPI GetKMPModule = (pfnGetKMPModule) GetProcAddress(Instance, SZ_KMP_GETMODULE); #endif // link if(V2Link) { V2Link(TVPGetFunctionExporter()); } // retrieve ModuleInstance // Susie Plug-in check if(GetProcAddress(Instance, "GetPicture")) { IsSusiePicturePlugin = true; TVPLoadPictureSPI(Instance); return; } if(GetProcAddress(Instance, "GetFile")) { IsSusieArchivePlugin = true; TVPLoadArchiveSPI(Instance); return; } if(GetModuleInstance) { HRESULT hr = GetModuleInstance(&TSSModule, storageprovider, NULL, Application->GetHandle()); if(FAILED(hr) || TSSModule == NULL) TVPThrowExceptionMessage(TVPCannotLoadPlugin, name); // get supported extensions unsigned long index = 0; while(true) { wchar_t mediashortname[33]; wchar_t buf[256]; HRESULT hr = TSSModule->GetSupportExts(index, mediashortname, buf, 255); if(hr == S_OK) SupportedExts.push_back(ttstr(buf).AsLowerCase()); else break; index ++; } } #ifdef TVP_SUPPORT_KPI // retrieve KbMediaPlayer Plug-in module instance if(GetKMPModule) { KMPModule = GetKMPModule(); if(KMPModule->dwVersion != 100) TVPThrowExceptionMessage(TVPCannotLoadPlugin, name + TJS_W(" (invalid version)")); if(!KMPModule->dwReentrant) TVPThrowExceptionMessage(TVPCannotLoadPlugin, name + TJS_W(" (is not re-entrant)")); if(KMPModule->Init) KMPModule->Init(); } #endif } catch(...) { FreeLibrary(Instance); delete Holder; throw; } } //--------------------------------------------------------------------------- tTVPPlugin::~tTVPPlugin() { } //--------------------------------------------------------------------------- bool tTVPPlugin::Uninit() { tTJS *tjs = TVPGetScriptEngine(); if(tjs) tjs->DoGarbageCollection(); // to release unused objects if(V2Unlink) { if(FAILED(V2Unlink())) return false; } #ifdef TVP_SUPPORT_KPI if(KMPModule) if(KMPModule->Deinit) KMPModule->Deinit(); #endif if(TSSModule) TSSModule->Release(); if(IsSusiePicturePlugin) TVPUnloadPictureSPI(Instance); if(IsSusieArchivePlugin) TVPUnloadArchiveSPI(Instance); FreeLibrary(Instance); delete Holder; return true; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- bool TVPPluginUnloadedAtSystemExit = false; typedef std::vector tTVPPluginVectorType; struct tTVPPluginVectorStruc { tTVPPluginVectorType Vector; tTVPStorageProvider StorageProvider; } static TVPPluginVector; static void TVPDestroyPluginVector(void) { // state all plugins are to be released TVPPluginUnloadedAtSystemExit = true; // delete all objects tTVPPluginVectorType::iterator i; while(TVPPluginVector.Vector.size()) { i = TVPPluginVector.Vector.end() - 1; try { (*i)->Uninit(); delete *i; } catch(...) { } TVPPluginVector.Vector.pop_back(); } } tTVPAtExit TVPDestroyPluginVectorAtExit (TVP_ATEXIT_PRI_RELEASE, TVPDestroyPluginVector); #endif //--------------------------------------------------------------------------- bool TVPLoadInternalPlugin(const ttstr &_name); extern std::set TVPRegisteredPlugins; static bool TVPPluginLoading = false; void TVPLoadPlugin(const ttstr & name) { bool success = TVPLoadInternalPlugin(name); return; // seal all plugins #if 0 // load plugin if(TVPPluginLoading) TVPThrowExceptionMessage(TVPCannnotLinkPluginWhilePluginLinking); // linking plugin while other plugin is linking, is prohibited // by data security reason. // check whether the same plugin was already loaded tTVPPluginVectorType::iterator i; for(i = TVPPluginVector.Vector.begin(); i != TVPPluginVector.Vector.end(); i++) { if((*i)->Name == name) return; } tTVPPlugin * p; try { TVPPluginLoading = true; p = new tTVPPlugin(name, &TVPPluginVector.StorageProvider); TVPPluginLoading = false; } catch(...) { TVPPluginLoading = false; throw; } TVPPluginVector.Vector.push_back(p); #endif } //--------------------------------------------------------------------------- bool TVPUnloadPlugin(const ttstr & name) { // unload plugin #if 0 tTVPPluginVectorType::iterator i; for(i = TVPPluginVector.Vector.begin(); i != TVPPluginVector.Vector.end(); i++) { if((*i)->Name == name) { if(!(*i)->Uninit()) return false; delete *i; TVPPluginVector.Vector.erase(i); return true; } } TVPThrowExceptionMessage(TVPNotLoadedPlugin, name); return false; #endif return true; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // plug-in autoload support //--------------------------------------------------------------------------- struct tTVPFoundPlugin { std::string Path; std::string Name; bool operator < (const tTVPFoundPlugin &rhs) const { return Name < rhs.Name; } }; static tjs_int TVPAutoLoadPluginCount = 0; static void TVPSearchPluginsAt(std::vector &list, std::string folder) { TVPListDir(folder, [&](const std::string &filename, int mask){ if (mask & S_IFREG) { if (!strcasecmp(filename.c_str() + filename.length() - 4, ".tpm")) { tTVPFoundPlugin fp; fp.Path = folder; fp.Name = filename; list.emplace_back(fp); } } }); #if 0 WIN32_FIND_DATA ffd; HANDLE handle = ::FindFirstFile((folder + L"*.tpm").c_str(), &ffd); if(handle != INVALID_HANDLE_VALUE) { BOOL cont; do { if(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { tTVPFoundPlugin fp; fp.Path = folder; fp.Name = ffd.cFileName; list.push_back(fp); } cont = FindNextFile(handle, &ffd); } while(cont); FindClose(handle); } #endif } void TVPLoadInternalPlugins(); void TVPLoadPluigins(void) { TVPLoadInternalPlugins(); // This function searches plugins which have an extension of ".tpm" // in the default path: // 1. a folder which holds kirikiri executable // 2. "plugin" folder of it // Plugin load order is to be decided using its name; // aaa.tpm is to be loaded before aab.tpm (sorted by ASCII order) // search plugins from path: (exepath), (exepath)\system, (exepath)\plugin std::vector list; std::string exepath = ExtractFileDir(TVPNativeProjectDir.AsNarrowStdString()); TVPSearchPluginsAt(list, exepath); TVPSearchPluginsAt(list, exepath + "/system"); TVPSearchPluginsAt(list, exepath + "/plugin"); // sort by filename std::sort(list.begin(), list.end()); // load each plugin TVPAutoLoadPluginCount = (tjs_int)list.size(); for(std::vector::iterator i = list.begin(); i != list.end(); i++) { TVPAddImportantLog(ttstr(TJS_W("(info) Loading ")) + ttstr(i->Name.c_str())); TVPLoadPlugin((i->Path + "/" + i->Name).c_str()); } } //--------------------------------------------------------------------------- tjs_int TVPGetAutoLoadPluginCount() { return TVPAutoLoadPluginCount; } //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // interface to Wave decode plugins //--------------------------------------------------------------------------- ITSSWaveDecoder * TVPSearchAvailTSSWaveDecoder(const ttstr & storage, const ttstr & extension) { tTVPPluginVectorType::iterator i; for(i = TVPPluginVector.Vector.begin(); i != TVPPluginVector.Vector.end(); i++) { if((*i)->TSSModule) { // check whether the plugin supports extension bool supported = false; std::vector::iterator ei; for(ei = (*i)->SupportedExts.begin(); ei != (*i)->SupportedExts.end(); ei++) { if(ei->GetLen() == 0) { supported = true; break; } if(extension == *ei) { supported = true; break; } } if(!supported) continue; // retrieve instance from (*i)->TSSModule IUnknown *intf = NULL; HRESULT hr = (*i)->TSSModule->GetMediaInstance( (wchar_t*)storage.c_str(), &intf); if(SUCCEEDED(hr)) { try { // check whether the instance has IID_ITSSWaveDecoder // interface. ITSSWaveDecoder * decoder; if(SUCCEEDED(intf->QueryInterface(IID_ITSSWaveDecoder, (void**) &decoder))) { intf->Release(); return decoder; // OK } } catch(...) { intf->Release(); throw; } intf->Release(); } } } return NULL; // not found } //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- #ifdef TVP_SUPPORT_OLD_WAVEUNPACKER IWaveUnpacker * TVPSearchAvailWaveUnpacker(const ttstr & storage, IStream **stream) { tTVPPluginVectorType::iterator i; for(i = TVPPluginVector.Vector.begin(); i != TVPPluginVector.Vector.end(); i++) { if((*i)->CreateWaveUnpacker) break; } if(i == TVPPluginVector.Vector.end()) return NULL; // KPI not found // retrieve IStream interface AnsiString ansiname = storage.AsAnsiString(); tTJSBinaryStream *stream0 = NULL; long size; try { stream0 = TVPCreateStream(storage); size = (long)stream0->GetSize(); } catch(...) { if(stream0) delete stream0; return NULL; } IStream *istream = new tTVPIStreamAdapter(stream0); try { for(i = TVPPluginVector.Vector.begin(); i != TVPPluginVector.Vector.end(); i++) { if((*i)->CreateWaveUnpacker) { // call CreateWaveUnpacker to retrieve decoder instance IWaveUnpacker *out; HRESULT hr = (*i)->CreateWaveUnpacker(istream, size, ansiname.c_str(), &out); if(SUCCEEDED(hr)) { *stream = istream; return out; } } } } catch(...) { istream->Release(); return NULL; } istream->Release(); return NULL; // not found } #endif //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #ifdef TVP_SUPPORT_KPI void * TVPSearchAvailKMPWaveDecoder(const ttstr & storage, KMPMODULE ** module, SOUNDINFO * info) { tTVPPluginVectorType::iterator i; for(i = TVPPluginVector.Vector.begin(); i != TVPPluginVector.Vector.end(); i++) { if((*i)->KMPModule) break; } if(i == TVPPluginVector.Vector.end()) return NULL; // KPI not found AnsiString localname; if(TJS_strchr(storage.c_str(), TVPArchiveDelimiter)) return NULL; // in-archive storage is not supported try { ttstr ln(TVPSearchPlacedPath(storage)); TVPGetLocalName(ln); localname = ln.AsAnsiString(); } catch(...) { return NULL; } AnsiString ext = TVPExtractStorageExt(storage).AsAnsiString(); for(i = TVPPluginVector.Vector.begin(); i != TVPPluginVector.Vector.end(); i++) { if((*i)->KMPModule) { // search over available extensions const char **module_ext = (*i)->KMPModule->ppszSupportExts; while(*module_ext) { if(!strcmpi(ext.c_str(), *module_ext)) break; module_ext ++; } if(!*module_ext) continue; // not found in this plug-in *module = (*i)->KMPModule; HKMP hkmp = (*i)->KMPModule->Open(localname.c_str(), info); if(hkmp) (*i)->KMPModule->SetPosition(hkmp, 0); // rewind; some plug-ins crash when the initial rewind is // not processed... return hkmp; } } return NULL; // not found } #endif //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // some service functions for plugin //--------------------------------------------------------------------------- #include int ZLIB_uncompress(unsigned char *dest, unsigned long *destlen, const unsigned char *source, unsigned long sourcelen) { return uncompress(dest, destlen, source, sourcelen); } //--------------------------------------------------------------------------- int ZLIB_compress(unsigned char *dest, unsigned long *destlen, const unsigned char *source, unsigned long sourcelen) { return compress(dest, destlen, source, sourcelen); } //--------------------------------------------------------------------------- int ZLIB_compress2(unsigned char *dest, unsigned long *destlen, const unsigned char *source, unsigned long sourcelen, int level) { return compress2(dest, destlen, source, sourcelen, level); } //--------------------------------------------------------------------------- #include "md5.h" static char TVP_assert_md5_state_t_size[ (sizeof(TVP_md5_state_t) >= sizeof(md5_state_t))]; // if this errors, sizeof(TVP_md5_state_t) is not equal to sizeof(md5_state_t). // sizeof(TVP_md5_state_t) must be equal to sizeof(md5_state_t). //--------------------------------------------------------------------------- void TVP_md5_init(TVP_md5_state_t *pms) { md5_init((md5_state_t*)pms); } //--------------------------------------------------------------------------- void TVP_md5_append(TVP_md5_state_t *pms, const tjs_uint8 *data, int nbytes) { md5_append((md5_state_t*)pms, (const md5_byte_t*)data, nbytes); } //--------------------------------------------------------------------------- void TVP_md5_finish(TVP_md5_state_t *pms, tjs_uint8 *digest) { md5_finish((md5_state_t*)pms, digest); } #if 0 //--------------------------------------------------------------------------- HWND TVPGetApplicationWindowHandle() { return Application->GetHandle(); } //--------------------------------------------------------------------------- void TVPProcessApplicationMessages() { Application->ProcessMessages(); } //--------------------------------------------------------------------------- void TVPHandleApplicationMessage() { Application->HandleMessage(); } #endif //--------------------------------------------------------------------------- bool TVPRegisterGlobalObject(const tjs_char *name, iTJSDispatch2 * dsp) { // register given object to global object tTJSVariant val(dsp); iTJSDispatch2 *global = TVPGetScriptDispatch(); tjs_error er; try { er = global->PropSet(TJS_MEMBERENSURE, name, NULL, &val, global); } catch(...) { global->Release(); return false; } global->Release(); return TJS_SUCCEEDED(er); } //--------------------------------------------------------------------------- bool TVPRemoveGlobalObject(const tjs_char *name) { // remove registration of global object iTJSDispatch2 *global = TVPGetScriptDispatch(); if(!global) return false; tjs_error er; try { er = global->DeleteMember(0, name, NULL, global); } catch(...) { global->Release(); return false; } global->Release(); return TJS_SUCCEEDED(er); } //--------------------------------------------------------------------------- void TVPDoTryBlock( tTVPTryBlockFunction tryblock, tTVPCatchBlockFunction catchblock, tTVPFinallyBlockFunction finallyblock, void *data) { try { tryblock(data); } catch(const eTJS & e) { if(finallyblock) finallyblock(data); tTVPExceptionDesc desc; desc.type = TJS_W("eTJS"); desc.message = e.GetMessage(); if(catchblock(data, desc)) throw; return; } catch(...) { if(finallyblock) finallyblock(data); tTVPExceptionDesc desc; desc.type = TJS_W("unknown"); if(catchblock(data, desc)) throw; return; } if(finallyblock) finallyblock(data); } //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // TVPGetFileVersionOf //--------------------------------------------------------------------------- bool TVPGetFileVersionOf(const wchar_t* module_filename, tjs_int &major, tjs_int &minor, tjs_int &release, tjs_int &build) { // retrieve file version major = minor = release = build = 0; VS_FIXEDFILEINFO *FixedFileInfo; BYTE *VersionInfo; bool got = false; UINT dum; DWORD dum2; wchar_t* filename = new wchar_t[TJS_strlen(module_filename) + 1]; try { TJS_strcpy(filename, module_filename); DWORD size = ::GetFileVersionInfoSize (filename, &dum2); if(size) { VersionInfo = new BYTE[size + 2]; try { if(::GetFileVersionInfo(filename, 0, size, (void*)VersionInfo)) { if(::VerQueryValue((void*)VersionInfo, L"\\", (void**)(&FixedFileInfo), &dum)) { major = FixedFileInfo->dwFileVersionMS >> 16; minor = FixedFileInfo->dwFileVersionMS & 0xffff; release = FixedFileInfo->dwFileVersionLS >> 16; build = FixedFileInfo->dwFileVersionLS & 0xffff; got = true; } } } catch(...) { delete [] VersionInfo; throw; } delete [] VersionInfo; } } catch(...) { delete [] filename; throw; } delete [] filename; return got; } //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- // TVPCreateNativeClass_Plugins //--------------------------------------------------------------------------- tTJSNativeClass * TVPCreateNativeClass_Plugins() { tTJSNC_Plugins *cls = new tTJSNC_Plugins(); // setup some platform-specific members //--------------------------------------------------------------------------- //-- methods //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/link) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr name = *param[0]; TVPLoadPlugin(name); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/link) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/unlink) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr name = *param[0]; bool res = TVPUnloadPlugin(name); if(result) *result = (tjs_int)res; return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/unlink) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(getList) { iTJSDispatch2 * array = TJSCreateArrayObject(); try { tjs_int idx = 0; for (ttstr name : TVPRegisteredPlugins) { tTJSVariant val(name); array->PropSetByNum(TJS_MEMBERENSURE, idx++, &val, array); } #if 0 tTVPPluginVectorType::iterator i; tjs_int idx = 0; for(i = TVPPluginVector.Vector.begin(); i != TVPPluginVector.Vector.end(); i++) { tTJSVariant val = (*i)->Name.c_str(); array->PropSetByNum(TJS_MEMBERENSURE, idx++, &val, array); } #endif if (result) *result = tTJSVariant(array, array); } catch(...) { array->Release(); throw; } array->Release(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(cls, getList) //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- return cls; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/win32/PluginImpl.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // "Plugins" class implementation / Service for plug-ins //--------------------------------------------------------------------------- #ifndef PluginImplH #define PluginImplH //--------------------------------------------------------------------------- #include #include "PluginIntf.h" #include "win32type.h" #ifdef TVP_SUPPORT_KPI #include "kmp_pi.h" #endif #if 0 //--------------------------------------------------------------------------- /*[*/ //--------------------------------------------------------------------------- // iTVPFunctionExporter, exporting main module's functions //--------------------------------------------------------------------------- struct iTVPFunctionExporter { virtual bool TJS_INTF_METHOD QueryFunctions(const tjs_char **name, void **function, tjs_uint count) = 0; virtual bool TJS_INTF_METHOD QueryFunctionsByNarrowString(const char **name, void **function, tjs_uint count) = 0; }; //--------------------------------------------------------------------------- /*]*/ //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- struct ITSSModule; struct IWaveUnpacker; struct ITSSStorageProvider; extern "C" { iTVPFunctionExporter * __stdcall TVPGetFunctionExporter(); // V2 plug-in typedef HRESULT (_stdcall * tTVPV2LinkProc)(iTVPFunctionExporter *); typedef HRESULT (_stdcall * tTVPV2UnlinkProc)(); // TSS typedef HRESULT (_stdcall * tTVPGetModuleInstanceProc)(ITSSModule **out, ITSSStorageProvider *provider, IStream * config, HWND mainwin); typedef ULONG (_stdcall * tTVPGetModuleThreadModelProc)(void); typedef HRESULT (_stdcall * tTVPShowConfigWindowProc)(HWND parentwin, IStream * storage ); typedef ULONG (_stdcall * tTVPCanUnloadNowProc)(void); #ifdef TVP_SUPPORT_OLD_WAVEUNPACKER // WaveUnpacker typedef HRESULT (_stdcall * tTVPCreateWaveUnpackerProc)(IStream *storage,long size, char *name,IWaveUnpacker **out); // old WaveUnpacker stuff #endif } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- struct ITSSWaveDecoder; extern ITSSWaveDecoder * TVPSearchAvailTSSWaveDecoder(const ttstr & storage, const ttstr & extension); #ifdef TVP_SUPPORT_OLD_WAVEUNPACKER class IWaveUnpacker; extern IWaveUnpacker * TVPSearchAvailWaveUnpacker(const ttstr & storage, IStream **stream); #endif #ifdef TVP_SUPPORT_KPI extern void * TVPSearchAvailKMPWaveDecoder(const ttstr & storage, KMPMODULE ** module, SOUNDINFO * info); #endif extern void TVPAddExportFunction(const tjs_char *name, void *ptr); extern void TVPAddExportFunction(const char *name, void *ptr); TJS_EXP_FUNC_DEF(void, TVPThrowPluginUnboundFunctionError, (const char *funcname)); TJS_EXP_FUNC_DEF(void, TVPThrowPluginUnboundFunctionError, (const tjs_char *funcname)); #endif inline TJS_EXP_FUNC_DEF(void *, TVP_malloc, (size_t size)) { return malloc(size); } // inline TJS_EXP_FUNC_DEF(void *, TVP_realloc, (void *pp, size_t size)) { return realloc(pp, size); } inline TJS_EXP_FUNC_DEF(void, TVP_free, (void *pp)) { return free(pp); } TJS_EXP_FUNC_DEF(tjs_int, TVPGetAutoLoadPluginCount, ()); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(int, ZLIB_uncompress, (unsigned char *dest, unsigned long *destlen, const unsigned char *source, unsigned long sourcelen)); TJS_EXP_FUNC_DEF(int, ZLIB_compress, (unsigned char *dest, unsigned long *destlen, const unsigned char *source, unsigned long sourcelen)); TJS_EXP_FUNC_DEF(int, ZLIB_compress2, (unsigned char *dest, unsigned long *destlen, const unsigned char *source, unsigned long sourcelen, int level)); /*[*/ //--------------------------------------------------------------------------- // this stub includes exported function from Independent implementation of // MD5 (RFC 1321) by Aladdin Enterprises. //--------------------------------------------------------------------------- // TVP_md5_init, TVP_md5_append, TVP_md5_finish are exported typedef struct TVP_md5_state_s { tjs_uint8 buffer[4*2+8+4*4+8+64]; } TVP_md5_state_t; // md5_state_t //--------------------------------------------------------------------------- /*]*/ TJS_EXP_FUNC_DEF(void, TVP_md5_init, (TVP_md5_state_t *pms)); TJS_EXP_FUNC_DEF(void, TVP_md5_append, (TVP_md5_state_t *pms, const tjs_uint8 *data, int nbytes)); TJS_EXP_FUNC_DEF(void, TVP_md5_finish, (TVP_md5_state_t *pms, tjs_uint8 *digest)); //TJS_EXP_FUNC_DEF(HWND, TVPGetApplicationWindowHandle, ()); TJS_EXP_FUNC_DEF(void, TVPProcessApplicationMessages, ()); TJS_EXP_FUNC_DEF(void, TVPHandleApplicationMessage, ()); TJS_EXP_FUNC_DEF(bool, TVPRegisterGlobalObject, (const tjs_char *name, iTJSDispatch2 * dsp)); TJS_EXP_FUNC_DEF(bool, TVPRemoveGlobalObject, (const tjs_char *name)); /*[*/ //--------------------------------------------------------------------------- // data types for TVPDoTryBlock //--------------------------------------------------------------------------- // TVPDoTryBlock executes specified 'tryblock' in try block. // If any exception occured, // 'catchblock' is to be executed. 'data' is applicatoin defined data // block passed to 'tryblock' and 'catchblock' and 'finallyblock'. // if the 'catchblock' returns true, the exception is to be rethrown. // if false then the exception is to be vanished. // 'finallyblock' can be null, is to be executed whatever the exception // is generated or not. struct tTVPExceptionDesc { ttstr type; // the exception type, currently 'eTJS' or 'unknown' ttstr message; // the exception message (if exists. otherwise empty). }; typedef void (TJS_USERENTRY *tTVPTryBlockFunction)(void * data); typedef bool (TJS_USERENTRY *tTVPCatchBlockFunction)(void * data, const tTVPExceptionDesc & desc); typedef void (TJS_USERENTRY *tTVPFinallyBlockFunction)(void *data); //--------------------------------------------------------------------------- /*]*/ TJS_EXP_FUNC_DEF(void, TVPDoTryBlock, (tTVPTryBlockFunction tryblock, tTVPCatchBlockFunction catchblock, tTVPFinallyBlockFunction finallyblock, void *data)); //TJS_EXP_FUNC_DEF(bool, TVPGetFileVersionOf, (const wchar_t* module_filename, tjs_int &major, tjs_int &minor, tjs_int &release, tjs_int &build)); //--------------------------------------------------------------------------- extern bool TVPPluginUnloadedAtSystemExit; extern void TVPLoadPluigins(void); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/win32/ScriptMgnImpl.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // TJS2 Script Managing //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include "SystemControl.h" #include "WindowIntf.h" #include "ScriptMgnIntf.h" #include "MsgIntf.h" #include "tjsScriptBlock.h" #include "EventIntf.h" #include "SysInitImpl.h" #include "SysInitIntf.h" #include "DebugIntf.h" #include "StorageImpl.h" #include "tjsDebug.h" #include "Application.h" //--------------------------------------------------------------------------- /* Object Hash Map (implemented in tjsDebug) is a simple object memory leak detector. Object Hash Map rely on TVP logging facility for logging unfreed objects. But TVP logging facility ends before some of TJS2 objects had been freed. To solve this problem, TJS2 uses two method to track objects; on-memory hash map and interprocess communication (IPC). On-memory hash map is a simple method, tracking object's creation and destruction on one hash map. Interprocess communication throws all object creation/destruction log to a process, which is specially created as a child-process for processing received log. Interprocess communication is implemented using low-level API, works very end of the parent process. TVP switches these two methods at framework finalization. On-memory hash map is used during most of the time. At the end of the framework, the framework switches to interprocess communication method. This continues rest of Object Hash Map operation until the process ends. Process of receiving object hash map log is implemented as the same executable of Kirikiri (There is a command line option for running this facility). */ #if 0 //--------------------------------------------------------------------------- // tTVPPipeStream to do IPC (used for Object Hash Map) //--------------------------------------------------------------------------- class tTVPPipeStream : public tTJSBinaryStream { private: HANDLE Handle; public: tTVPPipeStream(HANDLE handle) { Handle = handle; } ~tTVPPipeStream() { CloseHandle(Handle); } tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence) { return 0; // pipes does not support seeking } tjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size) { DWORD ret = 0; ReadFile(Handle, buffer, read_size, &ret, NULL); return ret; } tjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size) { DWORD ret = 0; WriteFile(Handle, buffer, write_size, &ret, NULL); FlushFileBuffers(Handle); return ret; } void TJS_INTF_METHOD SetEndOfStorage() { return; } tjs_uint64 TJS_INTF_METHOD GetSize() { return 0; } }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // Object Hash Map (memory leak detector) related //--------------------------------------------------------------------------- static char TVPObjectHashMapLogStream[sizeof(tTVPPipeStream)]; //--------------------------------------------------------------------------- void TVPStartObjectHashMapLog(void) { #ifndef ENABLE_DEBUGGER if(TJSObjectHashMapEnabled()) { // begin logging // create anonymous pipe to communicate with child kirikiri process HANDLE read, write; SECURITY_ATTRIBUTES sa; ZeroMemory(&sa, sizeof(sa)); sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; CreatePipe(&read, &write, &sa, 0); // redirect stdin to output the object hash map log HANDLE org_stdin = GetStdHandle(STD_INPUT_HANDLE); HANDLE childdupwrite; SetStdHandle(STD_INPUT_HANDLE, read); DuplicateHandle(GetCurrentProcess(), write, GetCurrentProcess(), &childdupwrite, 0, FALSE, DUPLICATE_SAME_ACCESS); CloseHandle(write); write = childdupwrite; // create child kirikiri process STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; wchar_t szFull[_MAX_PATH]; ::GetModuleFileName(NULL, szFull, sizeof(szFull) / sizeof(wchar_t)); std::wstring exepath(szFull); BOOL ret = ::CreateProcess( NULL, const_cast((exepath + L" -@processohmlog").c_str()), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); if(ret) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } // close unneeded handle CloseHandle(read); // restore original stdin handle SetStdHandle(STD_INPUT_HANDLE, org_stdin); // create tTJSBinaryStream object in STATIC AREA ::new (TVPObjectHashMapLogStream) tTVPPipeStream(write); // set object hash map log TJSObjectHashMapSetLog((tTVPLocalFileStream*)TVPObjectHashMapLogStream); // write all objects to log TJSWriteAllUnfreedObjectsToLog(); // end object mapping TJSReleaseObjectHashMap(); } #endif } //--------------------------------------------------------------------------- static tTVPAtExit TVPReportUnfreedObjectsAtExit (TVP_ATEXIT_PRI_CLEANUP - 1, TVPStartObjectHashMapLog); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- bool TVPCheckProcessLog() { // process object hash map log int argc = Application->ArgC; char** argv = Application->ArgV; tjs_int i; for(i=1; i and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // TJS2 Script Managing //--------------------------------------------------------------------------- #ifndef ScriptMgnImplH #define ScriptMgnImplH #include "ScriptMgnIntf.h" //--------------------------------------------------------------------------- // TVPInitializeStartupScript //--------------------------------------------------------------------------- extern void TVPInitializeStartupScript(); //extern bool TVPCheckProcessLog(int argc, char *argv[]); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/win32/StorageImpl.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Universal Storage System //--------------------------------------------------------------------------- #include "tjsCommHead.h" // #include // #include #include "MsgIntf.h" #include "StorageImpl.h" #include "WindowImpl.h" #include "GraphicsLoaderImpl.h" #include "SysInitIntf.h" #include "DebugIntf.h" #include "Random.h" #include "XP3Archive.h" //#include "SusieArchive.h" #include "FileSelector.h" #include "Random.h" #include #include "Application.h" #include "StringUtil.h" #include "FilePathUtil.h" #include "Platform.h" #include "platform/CCPlatformConfig.h" #include "dirent.h" #include "TickCount.h" #include #include #include "combase.h" #include "win32io.h" //--------------------------------------------------------------------------- // tTVPFileMedia //--------------------------------------------------------------------------- class tTVPFileMedia : public iTVPStorageMedia { tjs_uint RefCount; public: tTVPFileMedia() { RefCount = 1; } ~tTVPFileMedia() {;} void TJS_INTF_METHOD AddRef() { RefCount ++; } void TJS_INTF_METHOD Release() { if(RefCount == 1) delete this; else RefCount --; } void TJS_INTF_METHOD GetName(ttstr &name) { name = TJS_W("file"); } void TJS_INTF_METHOD NormalizeDomainName(ttstr &name); void TJS_INTF_METHOD NormalizePathName(ttstr &name); bool TJS_INTF_METHOD CheckExistentStorage(const ttstr &name); tTJSBinaryStream * TJS_INTF_METHOD Open(const ttstr & name, tjs_uint32 flags); void TJS_INTF_METHOD GetListAt(const ttstr &name, iTVPStorageLister *lister); void TJS_INTF_METHOD GetLocallyAccessibleName(ttstr &name); public: void TJS_INTF_METHOD GetLocalName(ttstr &name); }; //--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPFileMedia::NormalizeDomainName(ttstr &name) { // normalize domain name // make all characters small tjs_char *p = name.Independ(); while(*p) { if(*p >= TJS_W('A') && *p <= TJS_W('Z')) *p += TJS_W('a') - TJS_W('A'); p++; } } //--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPFileMedia::NormalizePathName(ttstr &name) { // normalize path name // make all characters small tjs_char *p = name.Independ(); while(*p) { if(*p >= TJS_W('A') && *p <= TJS_W('Z')) *p += TJS_W('a') - TJS_W('A'); p++; } } //--------------------------------------------------------------------------- bool TJS_INTF_METHOD tTVPFileMedia::CheckExistentStorage(const ttstr &name) { if(name.IsEmpty()) return false; ttstr _name(name); GetLocalName(_name); return TVPCheckExistentLocalFile(_name); } //--------------------------------------------------------------------------- tTJSBinaryStream * TJS_INTF_METHOD tTVPFileMedia::Open(const ttstr & name, tjs_uint32 flags) { // open storage named "name". // currently only local/network(by OS) storage systems are supported. if(name.IsEmpty()) TVPThrowExceptionMessage(TVPCannotOpenStorage, TJS_W("\"\"")); ttstr origname = name; ttstr _name(name); GetLocalName(_name); return new tTVPLocalFileStream(origname, _name, flags); } void TVPListDir(const std::string &folder, std::function cb) { DIR *dirp; struct dirent *direntp; tTVP_stat stat_buf; if ((dirp = opendir(folder.c_str()))) { while ((direntp = readdir(dirp)) != NULL) { std::string fullpath = folder + "/" + direntp->d_name; if (!TVP_stat(fullpath.c_str(), stat_buf)) continue; cb(direntp->d_name, stat_buf.st_mode); } closedir(dirp); } } void TVPGetLocalFileListAt(const ttstr &name, const std::function& cb) { DIR *dirp; struct dirent *direntp; tTVP_stat stat_buf; std::string folder(name.AsNarrowStdString()); if ((dirp = opendir(folder.c_str()))) { while ((direntp = readdir(dirp)) != NULL) { std::string fullpath = folder + "/" + direntp->d_name; if (!TVP_stat(fullpath.c_str(), stat_buf)) continue; ttstr file(direntp->d_name); if (file.length() <= 2) { if (file == TJS_W(".") || file == TJS_W("..")) continue; } tjs_char *p = file.Independ(); while (*p) { // make all characters small if (*p >= TJS_W('A') && *p <= TJS_W('Z')) *p += TJS_W('a') - TJS_W('A'); p++; } tTVPLocalFileInfo info; info.NativeName = direntp->d_name; info.Mode = stat_buf.st_mode; info.Size = stat_buf.st_size; info.AccessTime = stat_buf.st_atime; info.ModifyTime = stat_buf.st_mtime; info.CreationTime = stat_buf.st_ctime; cb(file, &info); } closedir(dirp); } } //--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPFileMedia::GetListAt(const ttstr &_name, iTVPStorageLister *lister) { ttstr name(_name); GetLocalName(name); #if 0 name += TJS_W("*.*"); // perform UNICODE operation WIN32_FIND_DATAW ffd; HANDLE handle = ::FindFirstFile(name.c_str(), &ffd); if(handle != INVALID_HANDLE_VALUE) { BOOL cont; do { if(!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { ttstr file(ffd.cFileName); tjs_char *p = file.Independ(); while(*p) { // make all characters small if(*p >= TJS_W('A') && *p <= TJS_W('Z')) *p += TJS_W('a') - TJS_W('A'); p++; } lister->Add(file); } cont = ::FindNextFile(handle, &ffd); } while(cont); FindClose(handle); } #endif TVPGetLocalFileListAt(name, [lister](const ttstr &name, tTVPLocalFileInfo* s) { if (s->Mode & (S_IFREG)) { lister->Add(name); } }); } static int _utf8_strcasecmp(const char *a, const char *b) { for(; *a && *b; ++a, ++b) { int ca = *a, cb = *b; if('A' <= ca && ca <= 'Z') ca += 'a' - 'A'; if('A' <= cb && cb <= 'Z') cb += 'a' - 'A'; int ret = ca - cb; if(ret) return ret; } return *a - *b; } #if CC_TARGET_PLATFORM == CC_PLATFORM_IOS const std::vector &TVPGetApplicationHomeDirectory(); const std::vector &_getPrefixPath() { static std::vector ret; if (ret.empty()) { for (const std::string &path : TVPGetApplicationHomeDirectory()) { ret.emplace_back(path); } } return ret; } const std::vector &_getHomeDir() { static std::vector ret; if (ret.empty()) { for (const std::string &path : TVPGetApplicationHomeDirectory()) { ret.emplace_back(path + "/"); } } return ret; } #endif //--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPFileMedia::GetLocallyAccessibleName(ttstr &name) { ttstr newname; const tjs_char *ptr = name.c_str(); #ifdef WIN32 if(TJS_strncmp(ptr, TJS_W("./"), 2)) { // differs from "./", // this may be a UNC file name. // UNC first two chars must be "\\\\" ? // AFAIK 32-bit version of Windows assumes that '/' can be used as a path // delimiter. Can UNC "\\\\" be replaced by "//" though ? newname = ttstr(TJS_W("\\\\")) + ptr; } else { ptr += 2; // skip "./" if(!*ptr) { newname = TJS_W(""); } else { tjs_char dch = *ptr; if(*ptr < TJS_W('a') || *ptr > TJS_W('z')) { newname = TJS_W(""); } else { ptr++; if(*ptr != TJS_W('/')) { newname = TJS_W(""); } else { newname = ttstr(dch) + TJS_W(":") + ptr; } } } } // change path delimiter to '\\' tjs_char *pp = newname.Independ(); while(*pp) { if(*pp == TJS_W('/')) *pp = TJS_W('\\'); pp++; } #else // posix if(!TJS_strncmp(ptr, TJS_W("./"), 2)) { ptr += 2; // skip "./" newname.Clear(); } #if CC_TARGET_PLATFORM == CC_PLATFORM_IOS { std::string prefix = "/"; prefix += tTJSNarrowStringHolder(ptr).Buf; static const std::vector &prefixPath = _getPrefixPath(); static const std::vector &homeDir = _getHomeDir(); for (int i = 0; i < prefixPath.size(); ++i) { const std::string &dir = homeDir[i]; if (prefix.length() < dir.length()) continue; std::string actualPrefix = prefix.substr(0, dir.length()); if (!_utf8_strcasecmp(actualPrefix.c_str(), dir.c_str())) { newname = prefixPath[i]; ptr += prefixPath[i].length(); while (*ptr && *ptr == TJS_W('/')) ++ptr; break; } } } #endif while(*ptr) { const tjs_char *ptr_end = ptr; while(*ptr_end && *ptr_end != TJS_W('/')) ++ptr_end; if(ptr_end == ptr) break; const tjs_char *ptr_cur = ptr; tTJSNarrowStringHolder walker(ttstr(ptr, ptr_end - ptr).c_str()); while(*ptr_end && *ptr_end == TJS_W('/')) ++ptr_end; ptr = ptr_end; DIR *dirp; struct dirent *direntp; newname += "/"; if ((dirp = opendir( tTJSNarrowStringHolder(newname.c_str()) ))) { bool found = false; while ((direntp = readdir( dirp)) != NULL) { if(!_utf8_strcasecmp(walker, direntp->d_name)) { newname += direntp->d_name; found = true; break; } } closedir(dirp); if(!found) { newname += ptr_cur; break; } } else { newname += ptr_cur; break; } } #endif name = newname; } //--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPFileMedia::GetLocalName(ttstr &name) { ttstr tmp = name; GetLocallyAccessibleName(tmp); if(tmp.IsEmpty()) TVPThrowExceptionMessage(TVPCannotGetLocalName, name); name = tmp; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- iTVPStorageMedia * TVPCreateFileMedia() { return new tTVPFileMedia; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPPreNormalizeStorageName //--------------------------------------------------------------------------- void TVPPreNormalizeStorageName(ttstr &name) { // if the name is an OS's native expression, change it according with the // TVP storage system naming rule. tjs_int namelen = name.GetLen(); if(namelen == 0) return; #ifdef WIN32 if(namelen >= 2) { if((name[0] >= TJS_W('a') && name[0]<=TJS_W('z') || name[0] >= TJS_W('A') && name[0]<=TJS_W('Z') ) && name[1] == TJS_W(':')) { // Windows drive:path expression ttstr newname(TJS_W("file://./")); newname += name[0]; newname += (name.c_str()+2); name = newname; return; } } if(namelen>=3) { if(name[0] == TJS_W('\\') && name[1] == TJS_W('\\') || name[0] == TJS_W('/') && name[1] == TJS_W('/')) { // unc expression name = ttstr(TJS_W("file:")) + name; return; } } #else // posix if(namelen>=1) { if(name[0] == TJS_W('/')) { name = ttstr(TJS_W("file://.")) + name; return; } } #endif } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetTemporaryName //--------------------------------------------------------------------------- static tjs_int TVPTempUniqueNum = 0; static tTJSCriticalSection TVPTempUniqueNumCS; static ttstr TVPTempPath; bool TVPTempPathInit = false; static tjs_int TVPProcessID; ttstr TVPGetTemporaryName() { static tjs_int TVPTempUniqueNum = (tjs_int)TVPGetRoughTickCount32(); tjs_int num = TVPTempUniqueNum++; ttstr TVPTempPath = TVPGetAppPath(); #if 0 tjs_int num; { tTJSCriticalSectionHolder holder(TVPTempUniqueNumCS); if(!TVPTempPathInit) { wchar_t tmp[MAX_PATH+1]; ::GetTempPath(MAX_PATH, tmp); TVPTempPath = tmp; if(TVPTempPath.GetLastChar() != TJS_W('\\')) TVPTempPath += TJS_W("\\"); TVPProcessID = (tjs_int) GetCurrentProcessId(); TVPTempUniqueNum = (tjs_int) GetTickCount(); TVPTempPathInit = true; } num = TVPTempUniqueNum ++; } #endif unsigned char buf[16]; TVPGetRandomBits128(buf); tjs_char random[128]; TJS_snprintf(random, sizeof(random)/sizeof(tjs_char), TJS_W("%02x%02x%02x%02x%02x%02x"), buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); return TVPTempPath + TJS_W("krkr_") + ttstr(random) + TJS_W("_") + ttstr(num) + TJS_W("_") + ttstr(TVPProcessID); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPRemoveFile //--------------------------------------------------------------------------- bool TVPRemoveFile(const ttstr &name) { tTJSNarrowStringHolder holder(name.c_str()); return !remove(holder); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPRemoveFolder //--------------------------------------------------------------------------- bool TVPRemoveFolder(const ttstr &name) { tTJSNarrowStringHolder holder(name.c_str()); return !unlink(holder); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetAppPath //--------------------------------------------------------------------------- ttstr TVPGetAppPath() { #if 0 static ttstr exepath(TVPExtractStoragePath(TVPNormalizeStorageName(ExePath()))); return exepath; #endif static ttstr apppath(TVPExtractStoragePath(TVPProjectDir)); return apppath; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPOpenStream //--------------------------------------------------------------------------- tTJSBinaryStream * TVPOpenStream(const ttstr & _name, tjs_uint32 flags) { // open storage named "name". // currently only local/network(by OS) storage systems are supported. if(_name.IsEmpty()) TVPThrowExceptionMessage(TVPCannotOpenStorage, TJS_W("\"\"")); ttstr origname = _name; ttstr name(_name); TVPGetLocalName(name); return new tTVPLocalFileStream(origname, name, flags); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCheckExistantLocalFile //--------------------------------------------------------------------------- bool TVPCheckExistentLocalFile(const ttstr &name) { #if 0 DWORD attrib = ::GetFileAttributes(name.c_str()); if(attrib == 0xffffffff || (attrib & FILE_ATTRIBUTE_DIRECTORY)) return false; // not a file else return true; // a file #endif tTVP_stat s; if(!TVP_stat(name.c_str(), s)) { return false; // not exist } return s.st_mode & S_IFREG; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCheckExistantLocalFolder //--------------------------------------------------------------------------- bool TVPCheckExistentLocalFolder(const ttstr &name) { #if 0 DWORD attrib = GetFileAttributes(name.c_str()); if(attrib != 0xffffffff && (attrib & FILE_ATTRIBUTE_DIRECTORY)) return true; // a folder else return false; // not a folder #endif tTVP_stat s; if (!TVP_stat(name.c_str(), s)) { return false; // not exist } return s.st_mode & S_IFDIR; } //--------------------------------------------------------------------------- tTVPArchive * TVPOpenZIPArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName); tTVPArchive * TVPOpen7ZArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName); tTVPArchive * TVPOpenTARArchive(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName); static tTVPArchive*(*ArchiveCreators[])(const ttstr & name, tTJSBinaryStream *st, bool normalizeFileName) = { TVPOpenZIPArchive, TVPOpen7ZArchive, TVPOpenTARArchive, tTVPXP3Archive::Create }; //--------------------------------------------------------------------------- // TVPOpenArchive //--------------------------------------------------------------------------- tTVPArchive * TVPOpenArchive(const ttstr & name, bool normalizeFileName) { #if 0 tTVPArchive * archive = TVPOpenSusieArchive(name); // in SusieArchive.h if(!archive) return new tTVPXP3Archive(name); else return archive; #endif tTJSBinaryStream *st = TVPCreateStream(name); if (!st) return nullptr; for (int i = 0; i < sizeof(ArchiveCreators) / sizeof(ArchiveCreators[0]); ++i) { tTVPArchive*(*creator)(const ttstr &, tTJSBinaryStream*, bool) = ArchiveCreators[i]; tTVPArchive * archive = creator(name, st, normalizeFileName); if (archive) return archive; st->SetPosition(0); } delete st; return nullptr; } //--------------------------------------------------------------------------- int TVPCheckArchive(const ttstr &localname) { tTVPArchive *arc = nullptr; int validArchive = 2; // archive but no startup.tjs try { arc = TVPOpenArchive(TVPNormalizeStorageName(localname), false); if (arc) { tjs_uint count = arc->GetCount(); ttstr str_startup_tjs = TJS_W("startup.tjs"); //ttstr str_sys_init_tjs = TJS_W("system/initialize.tjs"); for (int i = 0; i < count; ++i) { ttstr name = arc->GetName(i); if (name.length() == str_startup_tjs.length()) { arc->NormalizeInArchiveStorageName(name); if (name == str_startup_tjs) { validArchive = 1; break; } } // else if (name.length() == str_sys_init_tjs.length()) { // arc->NormalizeInArchiveStorageName(name); // if (name == str_sys_init_tjs) { // validArchive = true; // break; // } // } } } } catch (eTJSError e) { //arc = nullptr; } if (arc) { delete arc; return validArchive; } return 0; // not archive } //--------------------------------------------------------------------------- // TVPLocalExtrectFilePath //--------------------------------------------------------------------------- ttstr TVPLocalExtractFilePath(const ttstr & name) { // this extracts given name's path under local filename rule const tjs_char *p = name.c_str(); tjs_int i = name.GetLen() -1; for(; i >= 0; i--) { if(p[i] == TJS_W(':') || p[i] == TJS_W('/') || p[i] == TJS_W('\\')) break; } return ttstr(p, i + 1); } //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // TVPCreateFolders //--------------------------------------------------------------------------- static bool _TVPCreateFolders(const ttstr &folder) { // create directories along with "folder" if(folder.IsEmpty()) return true; if(TVPCheckExistentLocalFolder(folder)) return true; // already created const tjs_char *p = folder.c_str(); tjs_int i = folder.GetLen() - 1; if(p[i] == TJS_W(':')) return true; while(i >= 0 && (p[i] == TJS_W('/') || p[i] == TJS_W('\\'))) i--; if(i >= 0 && p[i] == TJS_W(':')) return true; for(; i >= 0; i--) { if(p[i] == TJS_W(':') || p[i] == TJS_W('/') || p[i] == TJS_W('\\')) break; } ttstr parent(p, i + 1); if(!_TVPCreateFolders(parent)) return false; BOOL res = ::CreateDirectory(folder.c_str(), NULL); return 0!=res; } bool TVPCreateFolders(const ttstr &folder) { if(folder.IsEmpty()) return true; const tjs_char *p = folder.c_str(); tjs_int i = folder.GetLen() - 1; if(p[i] == TJS_W(':')) return true; if(p[i] == TJS_W('/') || p[i] == TJS_W('\\')) i--; return _TVPCreateFolders(ttstr(p, i+1)); } //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- // tTVPLocalFileStream //--------------------------------------------------------------------------- tTVPLocalFileStream::tTVPLocalFileStream(const ttstr &origname, const ttstr &localname, tjs_uint32 flag) : MemBuffer(nullptr), FileName(localname), Handle(-1) { tjs_uint32 access = flag & TJS_BS_ACCESS_MASK; if(access == TJS_BS_WRITE) { if (TVPCheckExistentLocalFile(localname)) { } else { ttstr dirpath = TVPLocalExtractFilePath(localname); const tjs_char *p = dirpath.c_str(); tjs_int i = dirpath.GetLen(); if (p[i-1] == TJS_W('/') || p[i-1] == TJS_W('\\')) i--; dirpath = dirpath.SubString(0, i); if (!TVPCheckExistentLocalFolder(dirpath) && !TVPCreateFolders(dirpath)) { TVPThrowExceptionMessage(TVPCannotOpenStorage, origname); } // _lastFileSystemChanged = true; } MemBuffer = new tTVPMemoryStream(); return; } unsigned int rw = 0; switch(access) { case TJS_BS_READ: rw |= O_RDONLY; break; case TJS_BS_WRITE: rw |= O_RDWR | O_CREAT | O_TRUNC; break; case TJS_BS_APPEND: rw |= O_APPEND; break; case TJS_BS_UPDATE: rw |= O_RDWR; break; } tTJSNarrowStringHolder holder(localname.c_str()); Handle = open(holder, rw, 0666); if (Handle < 0) { if (access == TJS_BS_APPEND || access == TJS_BS_UPDATE) { // use whole file writing Handle = open(holder, O_RDONLY, 0666); if (Handle >= 0) { tjs_uint64 size = GetSize(); if (size < 4 * 1024 * 1024) { // only support file size <= 4M MemBuffer = new tTVPMemoryStream(); MemBuffer->SetSize(size); read(Handle, MemBuffer->GetInternalBuffer(), size); } close(Handle); Handle = -1; } } if (!MemBuffer) TVPThrowExceptionMessage(TVPCannotOpenStorage, origname); } // push current tick as an environment noise uint32_t tick = TVPGetRoughTickCount32(); TVPPushEnvironNoise(&tick, sizeof(tick)); } //--------------------------------------------------------------------------- bool TVPWriteDataToFile(const ttstr &filepath, const void *data, unsigned int len); tTVPLocalFileStream::~tTVPLocalFileStream() { if(MemBuffer) { if (!TVPWriteDataToFile(FileName, MemBuffer->GetInternalBuffer(), MemBuffer->GetSize())) { delete MemBuffer; ttstr filename(FileName); FileName.~tTJSString(); free(this); TVPThrowExceptionMessage(TJS_W("File Writing Error: %1"), filename); } delete MemBuffer; } if (Handle >= 0) { close(Handle); } // push current tick as an environment noise // (timing information from file accesses may be good noises) uint32_t tick = TVPGetRoughTickCount32(); TVPPushEnvironNoise(&tick, sizeof(tick)); } //--------------------------------------------------------------------------- tjs_uint64 TJS_INTF_METHOD tTVPLocalFileStream::Seek(tjs_int64 offset, tjs_int whence) { if(MemBuffer) { return MemBuffer->Seek(offset, whence); } return lseek64(Handle, offset, whence); } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPLocalFileStream::Read(void *buffer, tjs_uint read_size) { if(MemBuffer) { return MemBuffer->Read(buffer, read_size); } return read(Handle, buffer, read_size); } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPLocalFileStream::Write(const void *buffer, tjs_uint write_size) { if(MemBuffer) { return MemBuffer->Write(buffer, write_size); } return write(Handle, buffer, write_size); } //--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPLocalFileStream::SetEndOfStorage() { if(MemBuffer) { return MemBuffer->SetEndOfStorage(); } lseek64(Handle, 0, SEEK_END); } //--------------------------------------------------------------------------- tjs_uint64 TJS_INTF_METHOD tTVPLocalFileStream::GetSize() { if(MemBuffer) { return MemBuffer->GetSize(); } tjs_uint64 ret; tjs_int64 curpos = lseek64(Handle, 0, SEEK_CUR); ret = lseek64(Handle, 0, SEEK_END); lseek64(Handle, curpos, SEEK_SET); return ret; } //--------------------------------------------------------------------------- #ifdef TJS_SUPPORT_VCL //--------------------------------------------------------------------------- // TTVPStreamAdapter //--------------------------------------------------------------------------- __fastcall TTVPStreamAdapter::TTVPStreamAdapter(tTJSBinaryStream *ref) { Stream = ref; Stream->SetPosition(0); } //--------------------------------------------------------------------------- __fastcall TTVPStreamAdapter::~TTVPStreamAdapter() { delete Stream; } //--------------------------------------------------------------------------- int __fastcall TTVPStreamAdapter::Read(void *Buffer, int Count) { return (int)Stream->Read(Buffer, Count); } //--------------------------------------------------------------------------- int __fastcall TTVPStreamAdapter::Seek(int Offset, WORD Origin) { tjs_int whence; switch(Origin) { case soFromBeginning: whence = TJS_BS_SEEK_SET; break; case soFromCurrent: whence = TJS_BS_SEEK_CUR; break; case soFromEnd: whence = TJS_BS_SEEK_END; break; } return (int)Stream->Seek(Offset, whence); } //--------------------------------------------------------------------------- int __fastcall TTVPStreamAdapter::Write(const void *Buffer,int Count) { return (int)Stream->Write(Buffer, Count); } //--------------------------------------------------------------------------- #endif #if 1 //--------------------------------------------------------------------------- // tTVPIStreamAdapter //--------------------------------------------------------------------------- /* this class provides COM's IStream adapter for tTJSBinaryStream */ class tTVPIStreamAdapter : public IStream { private: tTJSBinaryStream *Stream; ULONG RefCount; public: tTVPIStreamAdapter(tTJSBinaryStream *ref); /* the stream passed by argument here is freed by this instance' destruction. */ ~tTVPIStreamAdapter(); // IUnknown HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); ULONG STDMETHODCALLTYPE AddRef(void); ULONG STDMETHODCALLTYPE Release(void); // ISequentialStream HRESULT STDMETHODCALLTYPE Read(void *pv, ULONG cb, ULONG *pcbRead); HRESULT STDMETHODCALLTYPE Write(const void *pv, ULONG cb, ULONG *pcbWritten); // IStream HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition); HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER libNewSize); HRESULT STDMETHODCALLTYPE CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten); HRESULT STDMETHODCALLTYPE Commit(DWORD grfCommitFlags); HRESULT STDMETHODCALLTYPE Revert(void); HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType); HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType); HRESULT STDMETHODCALLTYPE Stat(STATSTG *pstatstg, DWORD grfStatFlag); HRESULT STDMETHODCALLTYPE Clone(IStream **ppstm); void ClearStream() { Stream = NULL; } }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPIStreamAdapter //--------------------------------------------------------------------------- /* this class provides adapter for COM's IStream */ tTVPIStreamAdapter::tTVPIStreamAdapter(tTJSBinaryStream *ref) { Stream = ref; RefCount = 1; } //--------------------------------------------------------------------------- tTVPIStreamAdapter::~tTVPIStreamAdapter() { delete Stream; } //--------------------------------------------------------------------------- extern "C" const IID IID_IUnknown; extern "C" const IID IID_IStream; extern "C" const IID IID_ISequentialStream; HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::QueryInterface(REFIID riid, void **ppvObject) { if(!ppvObject) return E_INVALIDARG; *ppvObject=NULL; if(!memcmp(&riid,&IID_IUnknown,16)) *ppvObject=(IUnknown*)this; else if(!memcmp(&riid,&IID_ISequentialStream,16)) *ppvObject=(ISequentialStream*)this; else if(!memcmp(&riid,&IID_IStream,16)) *ppvObject=(IStream*)this; if(*ppvObject) { AddRef(); return S_OK; } return E_NOINTERFACE; } //--------------------------------------------------------------------------- ULONG STDMETHODCALLTYPE tTVPIStreamAdapter::AddRef(void) { return ++ RefCount; } //--------------------------------------------------------------------------- ULONG STDMETHODCALLTYPE tTVPIStreamAdapter::Release(void) { if(RefCount == 1) { delete this; return 0; } else { return --RefCount; } } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Read(void *pv, ULONG cb, ULONG *pcbRead) { try { ULONG read; read = Stream->Read(pv, cb); if(pcbRead) *pcbRead = read; } catch(...) { return E_FAIL; } return S_OK; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Write(const void *pv, ULONG cb, ULONG *pcbWritten) { try { ULONG written; written = Stream->Write(pv, cb); if(pcbWritten) *pcbWritten = written; } catch(...) { return E_FAIL; } return S_OK; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { try { switch(dwOrigin) { case STREAM_SEEK_SET: if(plibNewPosition) (*plibNewPosition).QuadPart = Stream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_SET); else Stream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_SET); break; case STREAM_SEEK_CUR: if(plibNewPosition) (*plibNewPosition).QuadPart = Stream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_CUR); else Stream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_CUR); break; case STREAM_SEEK_END: if(plibNewPosition) (*plibNewPosition).QuadPart = Stream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_END); else Stream->Seek(dlibMove.QuadPart, TJS_BS_SEEK_END); break; default: return E_FAIL; } } catch(...) { return E_FAIL; } return S_OK; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::SetSize(ULARGE_INTEGER libNewSize) { return E_NOTIMPL; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::CopyTo(IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten) { return E_NOTIMPL; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Commit(DWORD grfCommitFlags) { return E_NOTIMPL; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Revert(void) { return E_NOTIMPL; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { return E_NOTIMPL; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { return E_NOTIMPL; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Stat(STATSTG *pstatstg, DWORD grfStatFlag) { // This method imcompletely fills the target structure, because some // informations like access mode or stream name are already lost // at this point. if(pstatstg) { memset(pstatstg, 0, sizeof(*pstatstg)); // pwcsName // this object's storage pointer does not have a name ... if(!(grfStatFlag & STATFLAG_NONAME)) { // anyway returns an empty string pstatstg->pwcsName = (LPOLESTR)TJS_W(""); } // type pstatstg->type = STGTY_STREAM; // cbSize pstatstg->cbSize.QuadPart = Stream->GetSize(); // mtime, ctime, atime unknown // grfMode unknown pstatstg->grfMode = STGM_DIRECT | STGM_READWRITE | STGM_SHARE_DENY_WRITE ; // Note that this method always returns flags above, regardless of the // actual mode. // In the return value, the stream is to be indicated that the // stream can be written, but of cource, the Write method will fail // if the stream is read-only. // grfLockSuppoted pstatstg->grfLocksSupported = 0; // grfStatBits unknown } else { return E_INVALIDARG; } return S_OK; } //--------------------------------------------------------------------------- HRESULT STDMETHODCALLTYPE tTVPIStreamAdapter::Clone(IStream **ppstm) { return E_NOTIMPL; } //--------------------------------------------------------------------------- #endif IStream * TVPCreateIStream(tTJSBinaryStream *s) { return new tTVPIStreamAdapter(s); } //--------------------------------------------------------------------------- // IStream creator //--------------------------------------------------------------------------- IStream * TVPCreateIStream(const ttstr &name, tjs_uint32 flags) { // convert tTJSBinaryStream to IStream thru TStream tTJSBinaryStream *stream0 = NULL; try { stream0 = TVPCreateStream(name, flags); } catch(...) { if(stream0) delete stream0; return NULL; } IStream *istream = new tTVPIStreamAdapter(stream0); return istream; } //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // tTVPBinaryStreamAdapter //--------------------------------------------------------------------------- tTVPBinaryStreamAdapter::tTVPBinaryStreamAdapter(IStream *ref) { Stream = ref; Stream->AddRef(); } //--------------------------------------------------------------------------- tTVPBinaryStreamAdapter::~tTVPBinaryStreamAdapter() { Stream->Release(); } //--------------------------------------------------------------------------- tjs_uint64 TJS_INTF_METHOD tTVPBinaryStreamAdapter::Seek(tjs_int64 offset, tjs_int whence) { DWORD origin; switch(whence) { case TJS_BS_SEEK_SET: origin = STREAM_SEEK_SET; break; case TJS_BS_SEEK_CUR: origin = STREAM_SEEK_CUR; break; case TJS_BS_SEEK_END: origin = STREAM_SEEK_END; break; default: origin = STREAM_SEEK_SET; break; } LARGE_INTEGER ofs; ULARGE_INTEGER newpos; ofs.QuadPart = 0; HRESULT hr = Stream->Seek(ofs, STREAM_SEEK_CUR, &newpos); bool orgpossaved; LARGE_INTEGER orgpos; if(FAILED(hr)) { orgpossaved = false; } else { orgpossaved = true; *(LARGE_INTEGER*)&orgpos = *(LARGE_INTEGER*)&newpos; } ofs.QuadPart = offset; hr = Stream->Seek(ofs, origin, &newpos); if(FAILED(hr)) { if(orgpossaved) { Stream->Seek(orgpos, STREAM_SEEK_SET, &newpos); } else { TVPThrowExceptionMessage(TVPSeekError); } } return newpos.QuadPart; } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPBinaryStreamAdapter::Read(void *buffer, tjs_uint read_size) { ULONG cb = read_size; ULONG read; HRESULT hr = Stream->Read(buffer, cb, &read); if(FAILED(hr)) read = 0; return read; } //--------------------------------------------------------------------------- tjs_uint TJS_INTF_METHOD tTVPBinaryStreamAdapter::Write(const void *buffer, tjs_uint write_size) { ULONG cb = write_size; ULONG written; HRESULT hr = Stream->Write(buffer, cb, &written); if(FAILED(hr)) written = 0; return written; } //--------------------------------------------------------------------------- tjs_uint64 TJS_INTF_METHOD tTVPBinaryStreamAdapter::GetSize() { HRESULT hr; STATSTG stg; hr = Stream->Stat(&stg, STATFLAG_NONAME); if(FAILED(hr)) { return inherited::GetSize(); // use default routine } return stg.cbSize.QuadPart; } //--------------------------------------------------------------------------- void TJS_INTF_METHOD tTVPBinaryStreamAdapter::SetEndOfStorage() { ULARGE_INTEGER pos; pos.QuadPart = GetPosition(); HRESULT hr = Stream->SetSize(pos); if(FAILED(hr)) TVPThrowExceptionMessage(TVPTruncateError); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCreateBinaryStreamAdapter //--------------------------------------------------------------------------- tTJSBinaryStream * TVPCreateBinaryStreamAdapter(IStream *refstream) { return new tTVPBinaryStreamAdapter(refstream); } //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- // tTVPPluginHolder //--------------------------------------------------------------------------- tTVPPluginHolder::tTVPPluginHolder(const ttstr &aname) { LocalTempStorageHolder = NULL; // search in TVP storage system ttstr place(TVPGetPlacedPath(aname)); if(!place.IsEmpty()) { LocalTempStorageHolder = new tTVPLocalTempStorageHolder(place); } else { // not found in TVP storage system; search exepath, exepath\system, exepath\plugin #if 0 ttstr exepath = IncludeTrailingBackslash(ExtractFileDir(ExePath())); ttstr pname = exepath + aname; if(TVPCheckExistentLocalFile(pname)) { LocalName = pname; return; } pname = exepath + TJS_W("system\\") + aname; if(TVPCheckExistentLocalFile(pname)) { LocalName = pname; return; } #ifdef TJS_64BIT_OS pname = exepath + TJS_W("plugin64\\") + aname; #else pname = exepath + TJS_W("plugin\\") + aname; #endif if(TVPCheckExistentLocalFile(pname)) { LocalName = pname; return; } #endif } } //--------------------------------------------------------------------------- tTVPPluginHolder::~tTVPPluginHolder() { if(LocalTempStorageHolder) { delete LocalTempStorageHolder; } } //--------------------------------------------------------------------------- const ttstr & tTVPPluginHolder::GetLocalName() const { if(LocalTempStorageHolder) return LocalTempStorageHolder->GetLocalName(); return LocalName; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPSearchCD //--------------------------------------------------------------------------- ttstr TVPSearchCD(const ttstr & name) { // search CD which has specified volume label name. // return drive letter ( such as 'A' or 'B' ) // return empty string if not found. #if 0 std::wstring narrow_name = name.AsStdString(); wchar_t dr[4]; for(dr[0]=L'A',dr[1]=L':',dr[2]=L'\\',dr[3]=0;dr[0]<=L'Z';dr[0]++) { if(::GetDriveType(dr) == DRIVE_CDROM) { wchar_t vlabel[256]; wchar_t fs[256]; DWORD mcl = 0,sfs = 0; GetVolumeInformation(dr, vlabel, 255, NULL, &mcl, &sfs, fs, 255); if( icomp(std::wstring(vlabel),narrow_name) ) //if(std::string(vlabel).AnsiCompareIC(narrow_name)==0) return ttstr((tjs_char)dr[0]); } } #endif return ttstr(); } //--------------------------------------------------------------------------- tTJSBinaryStream * TVPGetCachedArchiveHandle(void * pointer, const ttstr & name); void TVPReleaseCachedArchiveHandle(void * pointer, tTJSBinaryStream * stream); TArchiveStream::TArchiveStream(tTVPArchive *owner, tjs_uint64 off, tjs_uint64 len) : Owner(owner), StartPos(off), DataLength(len) { Owner->AddRef(); _instr = TVPGetCachedArchiveHandle(Owner, Owner->ArchiveName); CurrentPos = 0; _instr->SetPosition(off); } TArchiveStream::~TArchiveStream() { TVPReleaseCachedArchiveHandle(Owner, _instr); Owner->Release(); } //--------------------------------------------------------------------------- // TVPCreateNativeClass_Storages //--------------------------------------------------------------------------- tTJSNativeClass * TVPCreateNativeClass_Storages() { tTJSNC_Storages *cls = new tTJSNC_Storages(); // setup some platform-specific members //---------------------------------------------------------------------- //-- methods //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/searchCD) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; if(result) *result = TVPSearchCD(*param[0]); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/searchCD) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getLocalName) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; if(result) { ttstr str(TVPNormalizeStorageName(*param[0])); TVPGetLocalName(str); *result = str; } return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/getLocalName) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/selectFile) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; iTJSDispatch2 * dsp = param[0]->AsObjectNoAddRef(); bool res = TVPSelectFile(dsp); if(result) *result = (tjs_int)res; return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/selectFile) //---------------------------------------------------------------------- return cls; } //--------------------------------------------------------------------------- static FILE *_fileopen(ttstr path) { std::string strpath = path.AsStdString(); FILE *fp = fopen(strpath.c_str(), "wb"); if (!fp) { // make dirs path = TVPExtractStoragePath(path); TVPCreateFolders(path); fp = fopen(strpath.c_str(), "wb"); } return fp; } bool TVPSaveStreamToFile(tTJSBinaryStream *st, tjs_uint64 offset, tjs_uint64 size, ttstr outpath) { FILE *fp = _fileopen(outpath); if (!fp) return false; tjs_uint64 origpos = st->GetPosition(); st->SetPosition(offset); std::vector buffer; buffer.resize(2 * 1024 * 1024); while (size > 0) { unsigned int readsize = size > buffer.size() ? buffer.size() : size; readsize = st->Read(&buffer.front(), readsize); fwrite(&buffer.front(), 1, readsize, fp); size -= readsize; } fclose(fp); st->SetPosition(origpos); return true; } ================================================ FILE: src/core/base/win32/StorageImpl.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Universal Storage System //--------------------------------------------------------------------------- #ifndef StorageImplH #define StorageImplH //--------------------------------------------------------------------------- #include "StorageIntf.h" #include "UtilStreams.h" #include //#include // for IStream #if 0 //--------------------------------------------------------------------------- // Susie plug-in related //--------------------------------------------------------------------------- void TVPLoadArchiveSPI(HINSTANCE inst); void TVPUnloadArchiveSPI(HINSTANCE inst); //--------------------------------------------------------------------------- #endif #ifndef S_IFMT #define S_IFDIR 0x4000 // Directory #define S_IFREG 0x8000 // Regular #endif struct tTVPLocalFileInfo { const char * NativeName; unsigned short Mode; // S_IFMT tjs_uint64 Size; time_t AccessTime; time_t ModifyTime; time_t CreationTime; }; void TVPGetLocalFileListAt(const ttstr &name, const std::function& cb); //--------------------------------------------------------------------------- // tTVPLocalFileStream //--------------------------------------------------------------------------- class tTVPLocalFileStream : public tTJSBinaryStream { private: //HANDLE Handle; int Handle; tTVPMemoryStream *MemBuffer = nullptr; ttstr FileName; public: tTVPLocalFileStream(const ttstr &origname, const ttstr & localname, tjs_uint32 flag); ~tTVPLocalFileStream(); tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence); tjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size); tjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size); void TJS_INTF_METHOD SetEndOfStorage(); tjs_uint64 TJS_INTF_METHOD GetSize(); int GetHandle() const { return Handle; } }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(bool, TVPCheckExistentLocalFolder, (const ttstr &name)); /* name must be an OS's NATIVE folder name */ TJS_EXP_FUNC_DEF(bool, TVPCheckExistentLocalFile, (const ttstr &name)); /* name must be an OS's NATIVE file name */ TJS_EXP_FUNC_DEF(bool, TVPCreateFolders, (const ttstr &folder)); /* make folders recursively, like mkdir -p. folder must be OS NATIVE folder name */ //--------------------------------------------------------------------------- #ifdef TJS_SUPPORT_VCL //--------------------------------------------------------------------------- // TTVPStreamAdapter //--------------------------------------------------------------------------- /* this class provides VCL's TStream adapter for tTJSBinaryStream */ class TTVPStreamAdapter : public TStream { private: tTJSBinaryStream *Stream; public: __fastcall TTVPStreamAdapter(tTJSBinaryStream *ref); /* the stream passed by argument here is freed by this instance' destruction. */ __fastcall ~TTVPStreamAdapter(); int __fastcall Read(void *Buffer,int Count); // read int __fastcall Seek(int Offset,WORD Origin); // seek int __fastcall Write(const void *Buffer,int Count); __property Size; __property Position; }; //--------------------------------------------------------------------------- #endif class tTVPIStreamAdapter; struct IStream; //--------------------------------------------------------------------------- // IStream creator //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(IStream *, TVPCreateIStream, (const ttstr &name, tjs_uint32 flags)); TJS_EXP_FUNC_DEF(IStream *, TVPCreateIStream, (tTJSBinaryStream *)); //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // tTVPBinaryStreamAdapter //--------------------------------------------------------------------------- /* this class provides tTJSBinaryStream adapter for IStream */ class tTVPBinaryStreamAdapter : public tTJSBinaryStream { typedef tTJSBinaryStream inherited; private: IStream *Stream; public: tTVPBinaryStreamAdapter(IStream *ref); /* the stream passed by argument here is freed by this instance' destruction. */ ~tTVPBinaryStreamAdapter(); tjs_uint64 TJS_INTF_METHOD Seek(tjs_int64 offset, tjs_int whence); tjs_uint TJS_INTF_METHOD Read(void *buffer, tjs_uint read_size); tjs_uint TJS_INTF_METHOD Write(const void *buffer, tjs_uint write_size); tjs_uint64 TJS_INTF_METHOD GetSize(); void TJS_INTF_METHOD SetEndOfStorage(); }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPBinaryStreamAdapter creator //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(tTJSBinaryStream *, TVPCreateBinaryStreamAdapter, (IStream *refstream)); //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- // tTVPPluginHolder //--------------------------------------------------------------------------- /* tTVPPluginHolder holds plug-in. if the plug-in is not a local storage, plug-in is to be extracted to temporary directory and be held until the program done using it. */ class tTVPPluginHolder { private: ttstr LocalName; tTVPLocalTempStorageHolder * LocalTempStorageHolder; public: tTVPPluginHolder(const ttstr &aname); ~tTVPPluginHolder(); const ttstr & GetLocalName() const; }; //--------------------------------------------------------------------------- void TVPListDir(const std::string &folder, std::function cb); bool TVPSaveStreamToFile(tTJSBinaryStream *st, tjs_uint64 offset, tjs_uint64 size, ttstr outpath); #endif ================================================ FILE: src/core/base/win32/SusieArchive.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Archive eXtractor Susie plug-in support //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include #include "StorageImpl.h" #include "SusieArchive.h" #include "GraphicsLoaderImpl.h" #include "DebugIntf.h" #include "XP3Archive.h" #include "MsgIntf.h" #include "SysInitIntf.h" #include //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPSusieArchivePlugin //--------------------------------------------------------------------------- #pragma pack(push, 1) struct tTVPSusieFileInfo { unsigned char method[8]; // compression method unsigned long position; // position in archive file unsigned long compsize; // compressed size unsigned long filesize; // original size time_t timestamp; // update timestamp char path[200]; // relative path char filename[200]; // filename unsigned long crc; // CRC }; #pragma pack(pop) struct tTVPSusieFileRecord { ttstr Name; unsigned long Position; unsigned long Size; bool operator < (const tTVPSusieFileRecord & rhs) const { return this->Name < rhs.Name; } }; //--------------------------------------------------------------------------- // tTVPSusiePlugin is defined in GraphicLoaderImpl.h class tTVPSusieArchivePlugin : public tTVPSusiePlugin { tTJSCriticalSection CS; tjs_int LockCount; public: tTVPSusieArchivePlugin(HINSTANCE inst); ~tTVPSusieArchivePlugin(); void Lock(); void Unlock(); bool CanRelease() { return LockCount <= 0; } bool CheckSupported(tTVPLocalFileStream * stream, std::string localname); void GetFileList(std::wstring localname, std::vector &dest); tTJSBinaryStream * CreateStream(std::wstring localname, unsigned long pos, unsigned long sise); tTJSCriticalSection & GetCS() { return CS; } }; //--------------------------------------------------------------------------- tTVPSusieArchivePlugin::tTVPSusieArchivePlugin(HINSTANCE inst) : tTVPSusiePlugin(inst, "00AM") { LockCount = 0; } //--------------------------------------------------------------------------- tTVPSusieArchivePlugin::~tTVPSusieArchivePlugin() { } //--------------------------------------------------------------------------- void tTVPSusieArchivePlugin::Lock() { tTJSCriticalSectionHolder holder(CS); LockCount++; } //--------------------------------------------------------------------------- void tTVPSusieArchivePlugin::Unlock() { tTJSCriticalSectionHolder holder(CS); LockCount--; } //--------------------------------------------------------------------------- bool tTVPSusieArchivePlugin::CheckSupported(tTVPLocalFileStream * stream, std::string localname) { int res = IsSupported(const_cast(localname.c_str()), (DWORD)stream->GetHandle()); return 0!=res; } //--------------------------------------------------------------------------- void tTVPSusieArchivePlugin::GetFileList(std::wstring localname, std::vector &dest) { // retrieve file list TVPAddLog( TVPFormatMessage(TVPInfoListingFiles, ttstr(localname.c_str()) ) ); HLOCAL infohandle = NULL; int errorcode = 0xff&GetArchiveInfo(const_cast(ttstr(localname).AsNarrowStdString().c_str()), 0, 0x00, &infohandle); if(infohandle == NULL) { TVPThrowExceptionMessage(TVPSusiePluginError, ttstr(TJS_W("tTVPSusieArchivePlugin::GetArchiveInfo failed, errorcode = ")) + ttstr((tjs_int)errorcode)); } else { if(errorcode != 0) { TVPAddLog(TJS_W("Warning : invalid errorcode ") + ttstr((tjs_int)errorcode) + TJS_W(" was returned from tTVPSusieArchivePlugin::GetArchiveInfo, ") TJS_W("continuing anyway.")); } } const tTVPSusieFileInfo *info = (const tTVPSusieFileInfo*)LocalLock(infohandle); if(info == NULL) { TVPThrowExceptionMessage(TVPSusiePluginError, ttstr(TJS_W("tTVPSusieArchivePlugin::GetArchiveInfo failed : invalid memory block."))); } try { while(info->method[0]) { if(info->filename[0]) { char buf[401]; TJS_nstrcpy(buf, info->path); TJS_nstrcat(buf, "/"); TJS_nstrcat(buf, info->filename); tTVPSusieFileRecord record; record.Name = buf; tTVPArchive::NormalizeInArchiveStorageName(record.Name); record.Position = info->position; record.Size = info->filesize; dest.push_back(record); } info++; } // sort item vector by its name (required for tTVPArchive specification) std::stable_sort(dest.begin(), dest.end()); } catch(...) { LocalUnlock(infohandle); LocalFree(infohandle); throw; } LocalUnlock(infohandle); LocalFree(infohandle); TVPAddLog(TJS_W("(info) ") + ttstr((tjs_int)dest.size()) + TJS_W(" files found.")); } //--------------------------------------------------------------------------- tTJSBinaryStream * tTVPSusieArchivePlugin::CreateStream(std::wstring localname, unsigned long pos, unsigned long size) { HLOCAL memhandle = NULL; int errorcode = 0xff & GetFile(const_cast(ttstr(localname).AsNarrowStdString().c_str()), pos, (LPSTR)(void*)&memhandle, 0x0100, (FARPROC)ProgressCallback, 0); if(errorcode || memhandle == NULL) { TVPThrowExceptionMessage(TVPSusiePluginError, ttstr(TJS_W("tTVPSusieArchivePlugin::GetFile failed, errorcode = ")) + ttstr((tjs_int)errorcode)); } tTVPMemoryStream *memstream = new tTVPMemoryStream; void *memblock = NULL; try { memblock = LocalLock(memhandle); if(memblock == NULL) { TVPThrowExceptionMessage(TVPSusiePluginError, ttstr(TJS_W("tTVPSusieArchivePlugin::GetFile failed : invalid memory block."))); } // write to on-memory stream memstream->WriteBuffer(memblock, size); memstream->SetPosition(0); } catch(...) { if(memblock) LocalUnlock(memhandle); LocalFree(memhandle); delete memstream; throw; } if(memblock) LocalUnlock(memhandle); LocalFree(memhandle); return memstream; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- static std::vector TVPSusiePluginVector; static void TVPDestroySusiePluginList() { std::vector::iterator i; for(i = TVPSusiePluginVector.begin(); i != TVPSusiePluginVector.end(); i++) { delete *i; } } static tTVPAtExit TVPDestroySusiePluginListAtExit (TVP_ATEXIT_PRI_CLEANUP, TVPDestroySusiePluginList); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPLoadArchiveSPI/TVPUnloadArchiveSPI : load/unload archive spi //--------------------------------------------------------------------------- void TVPLoadArchiveSPI(HINSTANCE inst) { // load specified Susie plug-in. std::vector::iterator i; for(i = TVPSusiePluginVector.begin(); i != TVPSusiePluginVector.end(); i++) { if((*i)->GetModuleInstance() == inst) TVPThrowInternalError; } tTVPSusieArchivePlugin *spi = new tTVPSusieArchivePlugin(inst); TVPSusiePluginVector.push_back(spi); } //--------------------------------------------------------------------------- void TVPUnloadArchiveSPI(HINSTANCE inst) { // unload specified Susie plug-in from system. std::vector::iterator i; for(i = TVPSusiePluginVector.begin(); i != TVPSusiePluginVector.end(); i++) { if((*i)->GetModuleInstance() == inst) break; } if(i == TVPSusiePluginVector.end()) TVPThrowExceptionMessage(TVPNotLoadedPlugin); if(!(*i)->CanRelease()) TVPThrowExceptionMessage(TVPCannotReleasePlugin); for(i = TVPSusiePluginVector.begin(); i != TVPSusiePluginVector.end();) { if((*i)->GetModuleInstance() == inst) i = TVPSusiePluginVector.erase(i); else i++; } delete *i; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCheckSusieSupport : checks which plugin supports specified archive //--------------------------------------------------------------------------- tTVPSusieArchivePlugin * TVPCheckSusieSupport(const ttstr &name, std::wstring &a_localname) { if(TVPSusiePluginVector.size() == 0) return NULL; ttstr localname = TVPGetLocallyAccessibleName(name); tTVPLocalFileStream stream(name, localname, TJS_BS_READ); if(localname.GetLen() == 0) return NULL; // only local filesystem stream is supported a_localname = localname.AsStdString(); std::vector::iterator i; for(i = TVPSusiePluginVector.end() - 1; i >= TVPSusiePluginVector.begin(); i--) { stream.SetPosition(0); if((*i)->CheckSupported(&stream, localname.AsNarrowStdString())) return *i; } return NULL; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // tTVPSusieArchive //--------------------------------------------------------------------------- class tTVPSusieArchive : public tTVPArchive { tTVPSusieArchivePlugin *Plugin; std::wstring LocalName; std::vector FileRecords; public: tTVPSusieArchive(tTVPSusieArchivePlugin *plugin, const ttstr & name, std::wstring localname); ~tTVPSusieArchive(); tjs_uint GetCount(); ttstr GetName(tjs_uint idx); tTJSBinaryStream * CreateStreamByIndex(tjs_uint idx); }; //--------------------------------------------------------------------------- tTVPSusieArchive::tTVPSusieArchive(tTVPSusieArchivePlugin *plugin, const ttstr &name, std::wstring localname) : tTVPArchive(name) { LocalName = localname; Plugin = plugin; tTJSCriticalSectionHolder(Plugin->GetCS()); Plugin->Lock(); Plugin->GetFileList(LocalName, FileRecords); } //--------------------------------------------------------------------------- tTVPSusieArchive::~tTVPSusieArchive() { Plugin->Unlock(); } //--------------------------------------------------------------------------- tjs_uint tTVPSusieArchive::GetCount() { return (tjs_uint)FileRecords.size(); } //--------------------------------------------------------------------------- ttstr tTVPSusieArchive::GetName(tjs_uint idx) { return FileRecords[idx].Name; } //--------------------------------------------------------------------------- tTJSBinaryStream * tTVPSusieArchive::CreateStreamByIndex(tjs_uint idx) { tTJSCriticalSectionHolder(Plugin->GetCS()); return Plugin->CreateStream(LocalName, FileRecords[idx].Position, FileRecords[idx].Size); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPOpenSusieArchive //--------------------------------------------------------------------------- tTVPArchive * TVPOpenSusieArchive(const ttstr & name) { std::wstring localname; tTVPSusieArchivePlugin *plugin = TVPCheckSusieSupport(name, localname); if(plugin) { return new tTVPSusieArchive(plugin, name, localname); } else { return NULL; } } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/win32/SusieArchive.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // Archive eXtractor Susie plug-in support //--------------------------------------------------------------------------- #ifndef SusieArchiveH #define SusieArchiveH //--------------------------------------------------------------------------- #include "StorageIntf.h" void TVPLoadArchiveSPI(HINSTANCE inst); void TVPUnloadArchiveSPI(HINSTANCE inst); class tTVPArchive; tTVPArchive * TVPOpenSusieArchive(const ttstr & name); #endif ================================================ FILE: src/core/base/win32/SysInitImpl.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // System Initialization and Uninitialization //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include "FilePathUtil.h" // #include // #include // #include // #include #include "SysInitImpl.h" #include "StorageIntf.h" #include "StorageImpl.h" #include "MsgIntf.h" #include "GraphicsLoaderIntf.h" #include "SystemControl.h" #include "DebugIntf.h" #include "tjsLex.h" #include "LayerIntf.h" #include "Random.h" #include "DetectCPU.h" #include "XP3Archive.h" #include "ScriptMgnIntf.h" #include "XP3Archive.h" //#include "VersionFormUnit.h" #include "EmergencyExit.h" //#include "tvpgl_ia32_intf.h" #include "BinaryStream.h" #include "Application.h" #include "Exception.h" #include "ApplicationSpecialPath.h" //#include "resource.h" //#include "ConfigFormUnit.h" #include "TickCount.h" #ifdef IID #undef IID #endif #define uint32_t unsigned int #include #undef uint32_t #include "Platform.h" #include "ConfigManager/IndividualConfigManager.h" //--------------------------------------------------------------------------- // global data //--------------------------------------------------------------------------- ttstr TVPNativeProjectDir; ttstr TVPNativeDataPath; bool TVPProjectDirSelected = false; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // System security options //--------------------------------------------------------------------------- // system security options are held inside the executable, where // signature checker will refer. This enables the signature checker // (or other security modules like XP3 encryption module) to check // the changes which is not intended by the contents author. const static char TVPSystemSecurityOptions[] = "-- TVPSystemSecurityOptions disablemsgmap(0):forcedataxp3(0):acceptfilenameargument(0) --"; //--------------------------------------------------------------------------- int GetSystemSecurityOption(const char *name) { size_t namelen = TJS_nstrlen(name); const char *p = TJS_nstrstr(TVPSystemSecurityOptions, name); if(!p) return 0; if(p[namelen] == '(' && p[namelen + 2] == ')') return p[namelen+1] - '0'; return 0; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // delayed DLL load procedure hook //--------------------------------------------------------------------------- // for supporting of "_inmm.dll" (C) irori // http://www.geocities.co.jp/Playtown-Domino/8282/ //--------------------------------------------------------------------------- /* note: _inmm.dll is a replacement of winmm.dll ( windows multimedia system dll ). _inmm.dll enables "MCI CD-DA supporting applications" to play musics using various way, including midi, mp3, wave or digital CD-DA, by applying a patch on those applications. TVP(kirikiri) system has a special structure of executable file -- delayed loading of winmm.dll, in addition to compressed code/data area by the UPX executable packer. _inmm.dll's patcher can not recognize TVP's import area. So we must implement supporting of _inmm.dll alternatively. This function only works when -_inmm=yes or -inmm=yes option is specified at command line or embeded options area. */ //--------------------------------------------------------------------------- #if 0 static HMODULE _inmm = NULL; static FARPROC WINAPI DllLoadHook(dliNotification dliNotify, DelayLoadInfo * pdli) { if(dliNotify == dliNotePreLoadLibrary) { if(!stricmp(pdli->szDll, "winmm.dll")) { HMODULE mod = LoadLibrary("_inmm.dll"); if(mod) _inmm = mod; return (FARPROC)mod; } } else if(dliNotify == dliNotePreGetProcAddress) { if(_inmm == pdli->hmodCur) { char buf[256]; buf[1] = 0; TJS_nstrcpy(buf, pdli->dlp.szProcName); buf[0] = '_'; return (FARPROC)GetProcAddress(_inmm, buf); } } return 0; } //--------------------------------------------------------------------------- static void RegisterDllLoadHook(void) { bool flag = false; tTJSVariant val; if( TVPGetCommandLine(TJS_W("-_inmm"), &val) || TVPGetCommandLine(TJS_W("-inmm" ), &val) ) { // _inmm support ttstr str(val); if(str == TJS_W("yes")) flag = true; } if(flag) __pfnDliNotifyHook = DllLoadHook; } //--------------------------------------------------------------------------- #endif #ifdef TVP_REPORT_HW_EXCEPTION //--------------------------------------------------------------------------- // Hardware Exception Report Related //--------------------------------------------------------------------------- // TVP's Hardware Exception Report comes with hacking RTL source. // insert following code into rtl/soruce/except/xx.cpp /* typedef void __cdecl (*__dee_hacked_getExceptionObjectHook_type)(int ErrorCode, EXCEPTION_RECORD *P, unsigned long osEsp, unsigned long osERR, PCONTEXT ctx); static __dee_hacked_getExceptionObjectHook_type __dee_hacked_getExceptionObjectHook = NULL; extern "C" { __dee_hacked_getExceptionObjectHook_type __cdecl __dee_hacked_set_getExceptionObjectHook( __dee_hacked_getExceptionObjectHook_type handler) { __dee_hacked_getExceptionObjectHook_type oldhandler; oldhandler = __dee_hacked_getExceptionObjectHook; __dee_hacked_getExceptionObjectHook = handler; return oldhandler; } } */ // and insert following code into getExceptionObject /* if(__dee_hacked_getExceptionObjectHook) __dee_hacked_getExceptionObjectHook(ErrorCode, P, osEsp, osERR, ctx); */ //--------------------------------------------------------------------------- /* typedef void __cdecl (*__dee_hacked_getExceptionObjectHook_type)(int ErrorCode, EXCEPTION_RECORD *P, unsigned long osEsp, unsigned long osERR, PCONTEXT ctx); extern "C" { extern __dee_hacked_getExceptionObjectHook_type __cdecl __dee_hacked_set_getExceptionObjectHook( __dee_hacked_getExceptionObjectHook_type handler); } */ //--------------------------------------------------------------------------- // data #define TVP_HWE_MAX_CODES_AT_EIP 96 #define TVP_HWE_MAX_STACK_AT_ESP 80 #define TVP_HWE_MAX_STACK_DATA_DUMP 16 #define TVP_HWE_MAX_CALL_TRACE 32 #define TVP_HWE_MAX_CALL_CODE_DUMP 26 static bool TVPHWExcRaised = false; struct tTVPHWExceptionData { tjs_int Code; tjs_uint8 *EIP; tjs_uint32 *ESP; ULONG_PTR AccessFlag; // for EAccessViolation (0=read, 1=write, 8=execute) void *AccessTarget; // for EAccessViolation CONTEXT Context; // OS exception context wchar_t Module[MAX_PATH]; // module name which caused the exception tjs_uint8 CodesAtEIP[TVP_HWE_MAX_CODES_AT_EIP]; tjs_int CodesAtEIPLen; void * StackAtESP[TVP_HWE_MAX_STACK_AT_ESP]; tjs_int StackAtESPLen; tjs_uint8 StackDumps[TVP_HWE_MAX_STACK_AT_ESP][TVP_HWE_MAX_STACK_DATA_DUMP]; tjs_int StackDumpsLen[TVP_HWE_MAX_STACK_AT_ESP]; void * CallTrace[TVP_HWE_MAX_CALL_TRACE]; tjs_int CallTraceLen; tjs_uint8 CallTraceDumps[TVP_HWE_MAX_CALL_TRACE][TVP_HWE_MAX_CALL_CODE_DUMP]; tjs_int CallTraceDumpsLen[TVP_HWE_MAX_CALL_TRACE]; }; static tTVPHWExceptionData TVPLastHWExceptionData; HANDLE TVPHWExceptionLogHandle = NULL; //--------------------------------------------------------------------------- static wchar_t TVPHWExceptionLogFilename[MAX_PATH]; static void TVPWriteHWELogFile() { TVPEnsureDataPathDirectory(); TJS_strcpy(TVPHWExceptionLogFilename, TVPNativeDataPath.c_str()); TJS_strcat(TVPHWExceptionLogFilename, L"hwexcept.log"); TVPHWExceptionLogHandle = CreateFile(TVPHWExceptionLogFilename, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(TVPHWExceptionLogHandle == INVALID_HANDLE_VALUE) return; DWORD filesize; filesize = GetFileSize(TVPHWExceptionLogHandle, NULL); SetFilePointer(TVPHWExceptionLogHandle, filesize, NULL, FILE_BEGIN); // write header const wchar_t headercomment[] = L"THIS IS A HARDWARE EXCEPTION LOG FILE OF KIRIKIRI. " L"PLEASE SEND THIS FILE TO THE AUTHOR WITH *.console.log FILE. "; DWORD written = 0; for(int i = 0; i < 4; i++) WriteFile(TVPHWExceptionLogHandle, L"----", 4*sizeof(wchar_t), &written, NULL); WriteFile(TVPHWExceptionLogHandle, headercomment, sizeof(headercomment)-1, &written, NULL); for(int i = 0; i < 4; i++) WriteFile(TVPHWExceptionLogHandle, L"----", 4*sizeof(wchar_t), &written, NULL); // write version WriteFile(TVPHWExceptionLogHandle, &TVPVersionMajor, sizeof(TVPVersionMajor), &written, NULL); WriteFile(TVPHWExceptionLogHandle, &TVPVersionMinor, sizeof(TVPVersionMinor), &written, NULL); WriteFile(TVPHWExceptionLogHandle, &TVPVersionRelease, sizeof(TVPVersionRelease), &written, NULL); WriteFile(TVPHWExceptionLogHandle, &TVPVersionBuild, sizeof(TVPVersionBuild), &written, NULL); // write tTVPHWExceptionData WriteFile(TVPHWExceptionLogHandle, &TVPLastHWExceptionData, sizeof(TVPLastHWExceptionData), &written, NULL); // close the handle if(TVPHWExceptionLogHandle != INVALID_HANDLE_VALUE) CloseHandle(TVPHWExceptionLogHandle); } //--------------------------------------------------------------------------- //void __cdecl TVP__dee_hacked_getExceptionObjectHook(int ErrorCode, // EXCEPTION_RECORD *P, unsigned long osEsp, unsigned long osERR, PCONTEXT ctx) #ifdef TJS_64BIT_OS void TVPHandleSEHException( int ErrorCode, EXCEPTION_RECORD *P, unsigned long long osEsp, PCONTEXT ctx) #else void TVPHandleSEHException( int ErrorCode, EXCEPTION_RECORD *P, unsigned long osEsp, PCONTEXT ctx) #endif { // exception hook function int len; tTVPHWExceptionData * d = &TVPLastHWExceptionData; d->Code = ErrorCode; // get AccessFlag and AccessTarget if(d->Code == 11) // EAccessViolation { d->AccessFlag = P->ExceptionInformation[0]; d->AccessTarget = (void*)P->ExceptionInformation[1]; } // get OS context if(!IsBadReadPtr(ctx, sizeof(*ctx))) { memcpy(&(d->Context), ctx, sizeof(*ctx)); } else { memset(&(d->Context), 0, sizeof(*ctx)); } // get codes at eip d->EIP = (tjs_uint8*)P->ExceptionAddress; len = TVP_HWE_MAX_CODES_AT_EIP; while(len) { if(!IsBadReadPtr(d->EIP, len)) { memcpy(d->CodesAtEIP, d->EIP, len); d->CodesAtEIPLen = len; break; } len--; } // get module name MEMORY_BASIC_INFORMATION mbi; VirtualQuery(d->EIP, &mbi, sizeof(mbi)); if(mbi.State == MEM_COMMIT) { if(!GetModuleFileName((HMODULE)mbi.AllocationBase, d->Module, MAX_PATH)) { d->Module[0] = 0; } } else { d->Module[0] = 0; } // get stack at esp d->ESP = (tjs_uint32*)osEsp; len = TVP_HWE_MAX_STACK_AT_ESP; while(len) { if(!IsBadReadPtr(d->ESP, len * sizeof(tjs_uint32))) { memcpy(d->StackAtESP, d->ESP, len * sizeof(tjs_uint32)); d->StackAtESPLen = len; break; } len--; } // get data pointed by each stack data for(tjs_int i = 0; iStackAtESPLen; i++) { void * base = d->StackAtESP[i]; len = TVP_HWE_MAX_STACK_DATA_DUMP; while(len) { if(!IsBadReadPtr(base, len)) { memcpy(d->StackDumps[i], base, len); d->StackDumpsLen[i] = len; break; } len--; } } // get call trace at esp d->CallTraceLen = 0; tjs_int p = 0; while(d->CallTraceLen < TVP_HWE_MAX_CALL_TRACE) { if(IsBadReadPtr(d->ESP + p, sizeof(tjs_uint32))) break; if(!IsBadReadPtr((void*)d->ESP[p], 4)) { VirtualQuery((void*)d->ESP[p], &mbi, sizeof(mbi)); if(mbi.State == MEM_COMMIT) { wchar_t module[MAX_PATH]; if(::GetModuleFileName((HMODULE)mbi.AllocationBase, module, MAX_PATH)) { tjs_uint8 buf[16]; if((DWORD)d->ESP[p] >= 16 && !IsBadReadPtr((void*)((DWORD)d->ESP[p] - 16), 16)) { memcpy(buf, (void*)((DWORD)d->ESP[p] - 16), 16); bool flag = false; if(buf[11] == 0xe8) flag = true; if(!flag) { for(tjs_int i = 0; i<15; i++) { if(buf[i] == 0xff && (buf[i+1] & 0x38) == 0x10) { flag = true; break; } } } if(flag) { // this seems to be a call code d->CallTrace[d->CallTraceLen] = (void *) d->ESP[p]; d->CallTraceLen ++; } } } } } p ++; } // get data pointed by each call trace data for(tjs_int i = 0; iCallTraceLen; i++) { void * base = d->CallTrace[i]; len = TVP_HWE_MAX_STACK_DATA_DUMP; while(len) { if(!IsBadReadPtr(base, len)) { memcpy(d->CallTraceDumps[i], base, len); d->CallTraceDumpsLen[i] = len; break; } len--; } } TVPHWExcRaised = true; TVPWriteHWELogFile(); } //--------------------------------------------------------------------------- static void TVPDumpCPUFlags(ttstr &line, DWORD flags, DWORD bit, tjs_char *name) { line += name; if(flags & bit) line += TJS_W("+ "); else line += TJS_W("- "); } //--------------------------------------------------------------------------- void TVPDumpOSContext(const CONTEXT &ctx) { // dump OS context block static const int BUF_SIZE = 256; tjs_char buf[BUF_SIZE]; // mask FP exception TJSSetFPUE(); // - context flags ttstr line; TJS_snprintf(buf, BUF_SIZE, TJS_W("Context Flags : 0x%08X [ "), ctx.ContextFlags); line += buf; if(ctx.ContextFlags & CONTEXT_DEBUG_REGISTERS) line += TJS_W("CONTEXT_DEBUG_REGISTERS "); if(ctx.ContextFlags & CONTEXT_FLOATING_POINT) line += TJS_W("CONTEXT_FLOATING_POINT "); if(ctx.ContextFlags & CONTEXT_SEGMENTS) line += TJS_W("CONTEXT_SEGMENTS "); if(ctx.ContextFlags & CONTEXT_INTEGER) line += TJS_W("CONTEXT_INTEGER "); if(ctx.ContextFlags & CONTEXT_CONTROL) line += TJS_W("CONTEXT_CONTROL "); #ifndef TJS_64BIT_OS if(ctx.ContextFlags & CONTEXT_EXTENDED_REGISTERS) line += TJS_W("CONTEXT_EXTENDED_REGISTERS "); #endif line += TJS_W("]"); TVPAddLog(line); // - debug registers #ifndef TJS_64BIT_OS TJS_snprintf(buf, BUF_SIZE, TJS_W("Debug Registers : ") TJS_W("0:0x%08X ") TJS_W("1:0x%08X ") TJS_W("2:0x%08X ") TJS_W("3:0x%08X ") TJS_W("6:0x%08X ") TJS_W("7:0x%08X "), ctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr6, ctx.Dr7); #else TJS_snprintf(buf, BUF_SIZE, TJS_W("Debug Registers : ") TJS_W("0:0x%016lx ") TJS_W("1:0x%016lx ") TJS_W("2:0x%016lx ") TJS_W("3:0x%016lx ") TJS_W("6:0x%016lx ") TJS_W("7:0x%016lx "), ctx.Dr0, ctx.Dr1, ctx.Dr2, ctx.Dr3, ctx.Dr6, ctx.Dr7); #endif TVPAddLog(buf); // - Segment registers TJS_snprintf(buf, BUF_SIZE, TJS_W("Segment Registers : GS:0x%04X FS:0x%04X ES:0x%04X DS:0x%04X CS:0x%04X SS:0x%04X"), ctx.SegGs, ctx.SegFs, ctx.SegEs, ctx.SegDs, ctx.SegCs, ctx.SegSs); TVPAddLog(buf); // - Generic Integer Registers #ifdef TJS_64BIT_OS TJS_snprintf(buf, BUF_SIZE, TJS_W("Integer Registers : RAX:0x%016lx RBX:0x%016lx RCX:0x%016lx RDX:0x%016lx"), ctx.Rax, ctx.Rbx, ctx.Rcx, ctx.Rdx); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("R8 :0x%016lx R9 :0x%016lx R10:0x%016lx R11:0x%016lx"), ctx.R8, ctx.R9, ctx.R10, ctx.R11); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("R12:0x%016lx R13:0x%016lx R14:0x%016lx R15:0x%016lx"), ctx.R12, ctx.R13, ctx.R14, ctx.R15); TVPAddLog(buf); #else TJS_snprintf(buf, BUF_SIZE, TJS_W("Integer Registers : EAX:0x%08X EBX:0x%08X ECX:0x%08X EDX:0x%08X"), ctx.Eax, ctx.Ebx, ctx.Ecx, ctx.Edx); TVPAddLog(buf); #endif // - Index Registers #ifdef TJS_64BIT_OS TJS_snprintf(buf, BUF_SIZE, TJS_W("Index Registers : RSI:0x%016lx RDI:0x%016lx"), ctx.Rsi, ctx.Rdi); #else TJS_snprintf(buf, BUF_SIZE, TJS_W("Index Registers : ESI:0x%08X EDI:0x%08X"), ctx.Esi, ctx.Edi); #endif TVPAddLog(buf); // - Pointer Registers #ifdef TJS_64BIT_OS TJS_snprintf(buf, BUF_SIZE, TJS_W("Pointer Registers : RBP:0x%016lx RSP:0x%016lx RIP:0x%016lx"), ctx.Rbp, ctx.Rsp, ctx.Rip); #else TJS_snprintf(buf, BUF_SIZE, TJS_W("Pointer Registers : EBP:0x%08X ESP:0x%08X EIP:0x%08X"), ctx.Ebp, ctx.Esp, ctx.Eip); #endif TVPAddLog(buf); // - Flag Register TJS_snprintf(buf, BUF_SIZE, TJS_W("Flag Register : 0x%08X [ "), ctx.EFlags); line = buf; TVPDumpCPUFlags(line, ctx.EFlags, (1<< 0), TJS_W("CF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<< 2), TJS_W("PF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<< 4), TJS_W("AF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<< 6), TJS_W("ZF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<< 7), TJS_W("SF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<< 8), TJS_W("TF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<< 9), TJS_W("IF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<<10), TJS_W("DF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<<11), TJS_W("OF")); TJS_snprintf(buf, BUF_SIZE, TJS_W("IO%d "), (ctx.EFlags >> 12) & 0x03); line += buf; TVPDumpCPUFlags(line, ctx.EFlags, (1<<14), TJS_W("NF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<<16), TJS_W("RF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<<17), TJS_W("VM")); TVPDumpCPUFlags(line, ctx.EFlags, (1<<18), TJS_W("AC")); TVPDumpCPUFlags(line, ctx.EFlags, (1<<19), TJS_W("VF")); TVPDumpCPUFlags(line, ctx.EFlags, (1<<20), TJS_W("VP")); TVPDumpCPUFlags(line, ctx.EFlags, (1<<21), TJS_W("ID")); line += TJS_W("]"); TVPAddLog(line); // - FP registers // -- control words #ifdef TJS_64BIT_OS TJS_snprintf(buf, BUF_SIZE, TJS_W("FP Control Word : 0x%08X FP Status Word : 0x%08X FP Tag Word : 0x%08X"), ctx.FltSave.ControlWord, ctx.FltSave.StatusWord, ctx.FltSave.TagWord); TVPAddLog(buf); // -- offsets/selectors TJS_snprintf(buf, BUF_SIZE, TJS_W("FP Error Offset : 0x%08X FP Error Selector : 0x%08X"), ctx.FltSave.ErrorOffset, ctx.FltSave.ErrorSelector); TJS_snprintf(buf, BUF_SIZE, TJS_W("FP Data Offset : 0x%08X FP Data Selector : 0x%08X"), ctx.FltSave.DataOffset, ctx.FltSave.DataSelector); // -- registers long double *ptr = (long double *)&(ctx.FltSave.FloatRegisters[0]); for(tjs_int i = 0; i < 8; i++) { TJS_snprintf(buf, BUF_SIZE, TJS_W("FP ST(%d) : %28.20Lg 0x%04X%016I64X"), i, ptr[i], (unsigned int)*(tjs_uint16*)(((tjs_uint8*)(ptr + i)) + 8), *(tjs_uint64*)(ptr + i)); TVPAddLog(buf); } // -- Cr0NpxState TJS_snprintf(buf, BUF_SIZE,TJS_W("FP MX CSR : 0x%08X"), ctx.FltSave.MxCsr); // TVPAddLog(buf); #else TJS_snprintf(buf, BUF_SIZE, TJS_W("FP Control Word : 0x%08X FP Status Word : 0x%08X FP Tag Word : 0x%08X"), ctx.FloatSave.ControlWord, ctx.FloatSave.StatusWord, ctx.FloatSave.TagWord); TVPAddLog(buf); // -- offsets/selectors TJS_snprintf(buf, BUF_SIZE, TJS_W("FP Error Offset : 0x%08X FP Error Selector : 0x%08X"), ctx.FloatSave.ErrorOffset, ctx.FloatSave.ErrorSelector); TJS_snprintf(buf, BUF_SIZE, TJS_W("FP Data Offset : 0x%08X FP Data Selector : 0x%08X"), ctx.FloatSave.DataOffset, ctx.FloatSave.DataSelector); // -- registers long double *ptr = (long double *)&(ctx.FloatSave.RegisterArea[0]); for(tjs_int i = 0; i < 8; i++) { TJS_snprintf(buf, BUF_SIZE, TJS_W("FP ST(%d) : %28.20Lg 0x%04X%016I64X"), i, ptr[i], (unsigned int)*(tjs_uint16*)(((tjs_uint8*)(ptr + i)) + 8), *(tjs_uint64*)(ptr + i)); TVPAddLog(buf); } // -- Cr0NpxState TJS_snprintf(buf, BUF_SIZE,TJS_W("FP CR0 NPX State : 0x%08X"), ctx.FloatSave.Cr0NpxState); TVPAddLog(buf); #endif // -- SSE/SSE2 registers #ifdef TJS_64BIT_OS TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 0 : 0x%016lx 0x%016lx"),ctx.Xmm0.High, ctx.Xmm0.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 1 : 0x%016lx 0x%016lx"),ctx.Xmm1.High, ctx.Xmm1.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 2 : 0x%016lx 0x%016lx"),ctx.Xmm2.High, ctx.Xmm2.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 3 : 0x%016lx 0x%016lx"),ctx.Xmm3.High, ctx.Xmm3.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 4 : 0x%016lx 0x%016lx"),ctx.Xmm4.High, ctx.Xmm4.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 5 : 0x%016lx 0x%016lx"),ctx.Xmm5.High, ctx.Xmm5.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 6 : 0x%016lx 0x%016lx"),ctx.Xmm6.High, ctx.Xmm6.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 7 : 0x%016lx 0x%016lx"),ctx.Xmm7.High, ctx.Xmm7.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 8 : 0x%016lx 0x%016lx"),ctx.Xmm8.High, ctx.Xmm8.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 9 : 0x%016lx 0x%016lx"),ctx.Xmm9.High, ctx.Xmm9.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 10 : 0x%016lx 0x%016lx"),ctx.Xmm10.High, ctx.Xmm10.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 11 : 0x%016lx 0x%016lx"),ctx.Xmm11.High, ctx.Xmm11.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 12 : 0x%016lx 0x%016lx"),ctx.Xmm12.High, ctx.Xmm12.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 13 : 0x%016lx 0x%016lx"),ctx.Xmm13.High, ctx.Xmm13.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 14 : 0x%016lx 0x%016lx"),ctx.Xmm14.High, ctx.Xmm14.Low); TVPAddLog(buf); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM 15 : 0x%016lx 0x%016lx"),ctx.Xmm15.High, ctx.Xmm15.Low); TVPAddLog(buf); TJS_snprintf(buf,BUF_SIZE, TJS_W("MXCSR : 0x%08x"), ctx.MxCsr ); TVPAddLog(buf); #else if(ctx.ContextFlags & CONTEXT_EXTENDED_REGISTERS) { // ExtendedRegisters is a area which meets fxsave and fxrstor instruction? #pragma pack(push,1) union xmm_t { struct { float sA; float sB; float sC; float sD; }; struct { double dA; double dB; }; struct { tjs_uint64 i64A; tjs_uint64 i64B; }; }; #pragma pack(pop) for(tjs_int i = 0; i < 8; i++) { xmm_t * xmm = (xmm_t *)(ctx.ExtendedRegisters + i * 16+ 0xa0); TJS_snprintf(buf, BUF_SIZE, TJS_W("XMM %d : [ %15.8g %15.8g %15.8g %15.8g ] [ %24.16lg %24.16lg ] [ 0x%016I64X-0x%016I64X ]"), i, xmm->sD, xmm->sC, xmm->sB, xmm->sA, xmm->dB, xmm->dA, xmm->i64B, xmm->i64A); TVPAddLog(buf); } TJS_snprintf(buf,BUF_SIZE, TJS_W("MXCSR : 0x%08X"), *(DWORD*)(ctx.ExtendedRegisters + 0x18)); TVPAddLog(buf); } #endif } //--------------------------------------------------------------------------- void TVPDumpHWException() { // dump latest hardware exception if it exists if(!TVPHWExcRaised) return; TVPHWExcRaised = false; TVPOnError(); static const int BUF_SIZE = 256; tjs_char buf[BUF_SIZE]; tTVPHWExceptionData * d = &TVPLastHWExceptionData; TVPAddLog(ttstr(TVPHardwareExceptionRaised)); ttstr line; line = TJS_W("Exception : "); tjs_char *p = NULL; switch(d->Code) { case 3: p = TJS_W("Divide By Zero"); break; case 4: p = TJS_W("Range Error"); break; case 5: p = TJS_W("Integer Overflow"); break; case 6: p = TJS_W("Invalid Operation"); break; case 7: p = TJS_W("Zero Divide"); break; case 8: p = TJS_W("Overflow"); break; case 9: p = TJS_W("Underflow"); break; case 10: p = TJS_W("Invalid Cast"); break; case 11: p = TJS_W("Access Violation"); break; case 12: p = TJS_W("Privilege Violation"); break; case 13: p = TJS_W("Control C"); break; case 14: p = TJS_W("Stack Overflow"); break; } if(p) line += p; if(d->Code == 11) { // EAccessViolation const tjs_char *mode = TJS_W("unknown"); if(d->AccessFlag == 0) mode = TJS_W("read"); else if(d->AccessFlag == 1) mode = TJS_W("write"); else if(d->AccessFlag == 8) mode = TJS_W("execute"); TJS_snprintf(buf, BUF_SIZE, TJS_W("(%ls access to 0x%p)"), mode, d->AccessTarget); line += buf; } TJS_snprintf(buf, BUF_SIZE, TJS_W(" at EIP = 0x%p ESP = 0x%p"), d->EIP, d->ESP); line += buf; if(d->Module[0]) { line += TJS_W(" in ") + ttstr(d->Module); } TVPAddLog(line); // dump OS context TVPDumpOSContext(d->Context); // dump codes at EIP line = TJS_W("Codes at EIP : "); for(tjs_int i = 0; iCodesAtEIPLen; i++) { TJS_snprintf(buf, BUF_SIZE, TJS_W("0x%02X "), d->CodesAtEIP[i]); line += buf; } TVPAddLog(line); TVPAddLog(TJS_W("Stack data and data pointed by each stack data :")); // dump stack and data for(tjs_int s = 0; sStackAtESPLen; s++) { TJS_snprintf(buf, BUF_SIZE, TJS_W("0x%p (ESP+%3d) : 0x%p : "), (DWORD)d->ESP + s*sizeof(tjs_uint32), s*sizeof(tjs_uint32), d->StackAtESP[s]); line = buf; for(tjs_int i = 0; iStackDumpsLen[s]; i++) { TJS_snprintf(buf, BUF_SIZE, TJS_W("0x%02X "), d->StackDumps[s][i]); line += buf; } TVPAddLog(line); } // dump call trace TVPAddLog(TJS_W("Call Trace :")); for(tjs_int s = 0; sCallTraceLen; s++) { TJS_snprintf(buf, BUF_SIZE, TJS_W("0x%p : "), d->CallTrace[s]); line = buf; for(tjs_int i = 0; iCallTraceDumpsLen[s]; i++) { TJS_snprintf(buf, BUF_SIZE, TJS_W("0x%02X "), d->CallTraceDumps[s][i]); line += buf; } MEMORY_BASIC_INFORMATION mbi; VirtualQuery((void*)d->CallTrace[s], &mbi, sizeof(mbi)); if(mbi.State == MEM_COMMIT) { wchar_t module[MAX_PATH]; if(::GetModuleFileName((HMODULE)mbi.AllocationBase, module, MAX_PATH)) { line += ttstr(ExtractFileName(module).c_str()); TJS_snprintf(buf, BUF_SIZE, TJS_W(" base 0x%p"), mbi.AllocationBase); line += buf; } } TVPAddLog(line); } } //--------------------------------------------------------------------------- #else void TVPDumpHWException(void) { // dummy } #endif //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // random generator initializer //--------------------------------------------------------------------------- static BOOL CALLBACK TVPInitRandomEnumWinProc(HWND hwnd, LPARAM lparam) { RECT r; GetWindowRect(hwnd, &r); TVPPushEnvironNoise(&hwnd, sizeof(hwnd)); TVPPushEnvironNoise(&r, sizeof(r)); DWORD procid, threadid; threadid = GetWindowThreadProcessId(hwnd, &procid); TVPPushEnvironNoise(&procid, sizeof(procid)); TVPPushEnvironNoise(&threadid, sizeof(threadid)); return TRUE; } #endif //--------------------------------------------------------------------------- static void TVPInitRandomGenerator() { // initialize random generator #if 0 DWORD tick = GetTickCount(); TVPPushEnvironNoise(&tick, sizeof(DWORD)); GUID guid; CoCreateGuid(&guid); TVPPushEnvironNoise(&guid, sizeof(guid)); DWORD id = GetCurrentProcessId(); TVPPushEnvironNoise(&id, sizeof(id)); id = GetCurrentThreadId(); TVPPushEnvironNoise(&id, sizeof(id)); SYSTEMTIME systime; GetSystemTime(&systime); TVPPushEnvironNoise(&systime, sizeof(systime)); POINT pt; GetCursorPos(&pt); TVPPushEnvironNoise(&pt, sizeof(pt)); EnumWindows((WNDENUMPROC)TVPInitRandomEnumWinProc, 0); #endif tjs_uint32 tick = TVPGetRoughTickCount32(); TVPPushEnvironNoise(&tick, sizeof(tick)); std::thread::id tid = std::this_thread::get_id(); TVPPushEnvironNoise(&tid, sizeof(tid)); time_t curtime = time(NULL); TVPPushEnvironNoise(&curtime, sizeof(curtime)); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPInitializeBaseSystems //--------------------------------------------------------------------------- void TVPInitializeBaseSystems() { // set system archive delimiter tTJSVariant v; if(TVPGetCommandLine(TJS_W("-arcdelim"), &v)) TVPArchiveDelimiter = ttstr(v)[0]; // set default current directory { TVPSetCurrentDirectory( IncludeTrailingBackslash(ExtractFileDir(ExePath())) ); } // load message map file bool load_msgmap = GetSystemSecurityOption("disablemsgmap") == 0; if(load_msgmap) { const tjs_char name_msgmap [] = TJS_W("msgmap.tjs"); if(TVPIsExistentStorage(name_msgmap)) TVPExecuteStorage(name_msgmap, NULL, false, TJS_W("")); } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // system initializer / uninitializer //--------------------------------------------------------------------------- #if 0 // tH_I_CAÕR[obN֐ static int CALLBACK TVPBrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam,LPARAM lpData) { if(uMsg==BFFM_INITIALIZED){ wchar_t exeDir[MAX_PATH]; TJS_strcpy(exeDir, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str()); ::SendMessage(hwnd,BFFM_SETSELECTION,(WPARAM)TRUE,(LPARAM)exeDir); } return 0; } #endif static tjs_uint64 TVPTotalPhysMemory = 0; static void TVPInitProgramArgumentsAndDataPath(bool stop_after_datapath_got); void TVPBeforeSystemInit() { //RegisterDllLoadHook(); // register DLL delayed import hook to support _inmm.dll TVPInitProgramArgumentsAndDataPath(false); // ensure command line // set system archive delimiter after patch.tjs specified tTJSVariant v; if (TVPGetCommandLine(TJS_W("-arcdelim"), &v)) TVPArchiveDelimiter = ttstr(v)[0]; if (TVPIsExistentStorageNoSearchNoNormalize(TVPProjectDir)) { TVPProjectDir += TVPArchiveDelimiter; } else { TVPProjectDir += TJS_W("/"); } TVPSetCurrentDirectory(TVPProjectDir); #ifdef TVP_REPORT_HW_EXCEPTION // __dee_hacked_set_getExceptionObjectHook(TVP__dee_hacked_getExceptionObjectHook); // register hook function for hardware exceptions #endif #if 0 Application->SetHintHidePause( 24*60*60*1000 ); // not to hide tool tip hint immediately Application->SetShowHint( false ); Application->SetShowHint( true ); // to ensure assigning new HintWindow Class defined in HintWindow.cpp #endif // randomize TVPInitRandomGenerator(); // memory usage { #if 0 MEMORYSTATUSEX status = { sizeof(MEMORYSTATUSEX) }; ::GlobalMemoryStatusEx(&status); TVPPushEnvironNoise(&status, sizeof(status)); TVPTotalPhysMemory = status.ullTotalPhys; ttstr memstr( std::to_wstring(TVPTotalPhysMemory).c_str() ); TVPAddImportantLog( TVPFormatMessage(TVPInfoTotalPhysicalMemory, memstr) ); tTJSVariant opt; if(TVPGetCommandLine(TJS_W("-memusage"), &opt)) { ttstr str(opt); if(str == TJS_W("low")) TVPTotalPhysMemory = 0; // assumes zero } if(TVPTotalPhysMemory <= 36*1024*1024) { // very very low memory, forcing to assume zero memory TVPTotalPhysMemory = 0; } if(TVPTotalPhysMemory < 48*1024*1024ULL) { // extra low memory if(TJSObjectHashBitsLimit > 0) TJSObjectHashBitsLimit = 0; TVPSegmentCacheLimit = 0; TVPFreeUnusedLayerCache = true; // in LayerIntf.cpp } else if(TVPTotalPhysMemory < 64*1024*1024) { // low memory if(TJSObjectHashBitsLimit > 4) TJSObjectHashBitsLimit = 4; } #endif TVPMemoryInfo meminf; TVPGetMemoryInfo(meminf); TVPPushEnvironNoise(&meminf, sizeof(meminf)); TVPTotalPhysMemory = meminf.MemTotal * 1024; if (TVPTotalPhysMemory > 768 * 1024 * 1024) { TVPTotalPhysMemory -= 512 * 1024 * 1024; // assume that system reserved 512M memory } else { TVPTotalPhysMemory /= 2; // use half memory in small memory devices } TVPAddImportantLog(TVPFormatMessage(TVPInfoTotalPhysicalMemory, tjs_int64(TVPTotalPhysMemory))); if (TVPTotalPhysMemory > 256 * 1024 * 1024) { std::string str = IndividualConfigManager::GetInstance()->GetValue("memusage", "unlimited"); if (str == ("low")) TVPTotalPhysMemory = 0; // assumes zero else if (str == ("medium")) TVPTotalPhysMemory = 128 * 1024 * 1024; else if (str == ("high")) TVPTotalPhysMemory = 256 * 1024 * 1024; } else { // use minimum memory usage if less than 256M(512M physics) TVPTotalPhysMemory = 0; } if (TVPTotalPhysMemory < 128 * 1024 * 1024) { // very very low memory, forcing to assume zero memory TVPTotalPhysMemory = 0; } if (TVPTotalPhysMemory < 128 * 1024 * 1024) { // extra low memory if (TJSObjectHashBitsLimit > 0) TJSObjectHashBitsLimit = 0; TVPSegmentCacheLimit = 0; TVPFreeUnusedLayerCache = true; // in LayerIntf.cpp } else if (TVPTotalPhysMemory < 256 * 1024 * 1024) { // low memory if (TJSObjectHashBitsLimit > 4) TJSObjectHashBitsLimit = 4; } } #if 0 wchar_t buf[MAX_PATH]; bool bufset = false; bool nosel = false; bool forcesel = false; bool forcedataxp3 = GetSystemSecurityOption("forcedataxp3") != 0; bool acceptfilenameargument = GetSystemSecurityOption("acceptfilenameargument") != 0; if(!forcedataxp3 && !acceptfilenameargument) { if(TVPGetCommandLine(TJS_W("-nosel")) || TVPGetCommandLine(TJS_W("-about"))) { nosel = true; } else { wchar_t exeDir[MAX_PATH]; TJS_strcpy(exeDir, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str()); for(tjs_int i = 1; i<_argc; i++) { if(_argv[i][0] == '-' && _argv[i][1] == '-' && _argv[i][2] == 0) break; if(_argv[i][0] != '-') { // TODO: set the current directory ::SetCurrentDirectory( exeDir ); TJS_strncpy(buf, ttstr(_argv[i]).c_str(), MAX_PATH-1); buf[MAX_PATH-1] = TJS_W('\0'); if(DirectoryExists(buf)) // is directory? TJS_strcat(buf, TJS_W("\\")); TVPProjectDirSelected = true; bufset = true; nosel = true; } } } } // check "-sel" option, to force show folder selection window if(!forcedataxp3 && TVPGetCommandLine(TJS_W("-sel"))) { // sel option was set if(bufset) { wchar_t path[MAX_PATH]; wchar_t *dum = 0; GetFullPathName(buf, MAX_PATH-1, path, &dum); TJS_strcpy(buf, path); TVPProjectDirSelected = false; bufset = true; } nosel = true; forcesel = true; } // check "content-data" directory if(!forcedataxp3 && !nosel) { wchar_t tmp[MAX_PATH]; TJS_strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str()); TJS_strcat(tmp, TJS_W("content-data")); if(DirectoryExists(tmp)) { TJS_strcat(tmp, TJS_W("\\")); TJS_strcpy(buf, tmp); TVPProjectDirSelected = true; bufset = true; nosel = true; } } // check "data.xp3" archive if(!nosel) { wchar_t tmp[MAX_PATH]; TJS_strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str()); TJS_strcat(tmp, TJS_W("data.xp3")); if(FileExists(tmp)) { TJS_strcpy(buf, tmp); TVPProjectDirSelected = true; bufset = true; nosel = true; } } // check "data.exe" archive if(!nosel) { wchar_t tmp[MAX_PATH]; TJS_strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str()); TJS_strcat(tmp, TJS_W("data.exe")); if(FileExists(tmp)) { TJS_strcpy(buf, tmp); TVPProjectDirSelected = true; bufset = true; nosel = true; } } // check self combined xpk archive if(!nosel) { if(TVPIsXP3Archive(TVPNormalizeStorageName(ExePath()))) { TJS_strcpy(buf, ExePath().c_str()); TVPProjectDirSelected = true; bufset = true; nosel = true; } } // check "data" directory if(!forcedataxp3 && !nosel) { wchar_t tmp[MAX_PATH]; TJS_strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ExePath())).c_str()); TJS_strcat(tmp, TJS_W("data")); if(DirectoryExists(tmp)) { TJS_strcat(tmp, TJS_W("\\")); TJS_strcpy(buf, tmp); TVPProjectDirSelected = true; bufset = true; nosel = true; } } // decide a directory to execute or to show folder selection if(!bufset) { if(forcedataxp3) throw EAbort(TJS_W("Aborted")); TJS_strcpy(buf, ExtractFileDir(ExePath()).c_str()); int curdirlen = (int)TJS_strlen(buf); if(buf[curdirlen-1] != TJS_W('\\')) buf[curdirlen] = TJS_W('\\'), buf[curdirlen+1] = 0; } #ifndef TVP_DISABLE_SELECT_XP3_OR_FOLDER if(!forcedataxp3 && (!nosel || forcesel)) { BOOL bRes; wchar_t chPutFolder[MAX_PATH]; LPITEMIDLIST pidlRetFolder; BROWSEINFO stBInfo; ::ZeroMemory( &stBInfo, sizeof(stBInfo) ); stBInfo.pidlRoot = NULL; stBInfo.hwndOwner = NULL; stBInfo.pszDisplayName = chPutFolder; stBInfo.lpszTitle = TVPSelectXP3FileOrFolder; stBInfo.ulFlags = BIF_BROWSEINCLUDEFILES|BIF_RETURNFSANCESTORS|BIF_DONTGOBELOWDOMAIN|BIF_RETURNONLYFSDIRS; stBInfo.lpfn = TVPBrowseCallbackProc; stBInfo.lParam = NULL; pidlRetFolder = ::SHBrowseForFolder( &stBInfo ); if( pidlRetFolder != NULL ) { bRes = ::SHGetPathFromIDList( pidlRetFolder, chPutFolder ); if( bRes != FALSE ) { wcsncpy( buf, chPutFolder, MAX_PATH ); tjs_int buflen = (tjs_int)TJS_strlen(buf); if( buflen >= 1 ) { if( buf[buflen-1] != TJS_W('\\') && buflen < (MAX_PATH-2) ) { buf[buflen] = TJS_W('\\'); buf[buflen+1] = TJS_W('\0'); } } TVPProjectDirSelected = true; } ::CoTaskMemFree( pidlRetFolder ); } } #endif // check project dir and store some environmental variables if(TVPProjectDirSelected) { Application->SetShowMainForm( false ); } tjs_int buflen = (tjs_int)TJS_strlen(buf); if(buflen >= 1) { if(buf[buflen-1] != TJS_W('\\')) buf[buflen] = TVPArchiveDelimiter, buf[buflen+1] = 0; } TVPProjectDir = TVPNormalizeStorageName(buf); TVPSetCurrentDirectory(TVPProjectDir); TVPNativeProjectDir = buf; if(TVPProjectDirSelected) { TVPAddImportantLog( TVPFormatMessage(TVPInfoSelectedProjectDirectory, TVPProjectDir) ); } #endif } //--------------------------------------------------------------------------- static void TVPDumpOptions(); //--------------------------------------------------------------------------- extern bool TVPEnableGlobalHeapCompaction; extern void TVPGL_SSE2_Init(); extern "C" void TVPGL_ASM_Init(); extern bool TVPAutoSaveBookMark; static bool TVPHighTimerPeriod = false; static uint32_t TVPTimeBeginPeriodRes = 0; //--------------------------------------------------------------------------- void TVPAfterSystemInit() { // check CPU type TVPDetectCPU(); TVPAllocGraphicCacheOnHeap = false; // always false since beta 20 // determine maximum graphic cache limit tTJSVariant opt; tjs_int64 limitmb = -1; if(TVPGetCommandLine(TJS_W("-gclim"), &opt)) { ttstr str(opt); if(str == TJS_W("auto")) limitmb = -1; else limitmb = opt.AsInteger(); } if(limitmb == -1) { if(TVPTotalPhysMemory <= 32*1024*1024) TVPGraphicCacheSystemLimit = 0; else if(TVPTotalPhysMemory <= 48*1024*1024) TVPGraphicCacheSystemLimit = 0; else if(TVPTotalPhysMemory <= 64*1024*1024) TVPGraphicCacheSystemLimit = 0; else if(TVPTotalPhysMemory <= 96*1024*1024) TVPGraphicCacheSystemLimit = 4; else if(TVPTotalPhysMemory <= 128*1024*1024) TVPGraphicCacheSystemLimit = 8; else if(TVPTotalPhysMemory <= 192*1024*1024) TVPGraphicCacheSystemLimit = 12; else if(TVPTotalPhysMemory <= 256*1024*1024) TVPGraphicCacheSystemLimit = 20; else if(TVPTotalPhysMemory <= 512*1024*1024) TVPGraphicCacheSystemLimit = 40; else TVPGraphicCacheSystemLimit = tjs_uint64(TVPTotalPhysMemory / (1024*1024*10)); // cachemem = physmem / 10 TVPGraphicCacheSystemLimit *= 1024*1024; } else { TVPGraphicCacheSystemLimit = limitmb * 1024*1024; } // 32bit Ȃ̂ 512MB ܂łɐ if( TVPGraphicCacheSystemLimit >= 512*1024*1024 ) TVPGraphicCacheSystemLimit = 512*1024*1024; if(TVPTotalPhysMemory <= 64*1024*1024) TVPSetFontCacheForLowMem(); // TVPGraphicCacheSystemLimit = 1*1024*1024; // DEBUG if(TVPGetCommandLine(TJS_W("-autosave"), &opt)) { ttstr str(opt); if(str == TJS_W("yes")) { TVPAutoSaveBookMark = true; } } // check TVPGraphicSplitOperation option std::string _val = IndividualConfigManager::GetInstance()->GetValue("renderer", "software"); if (_val != "software") { TVPGraphicSplitOperationType = gsotNone; } else { TVPDrawThreadNum = IndividualConfigManager::GetInstance()->GetValue("software_draw_thread", 0); if (TVPGetCommandLine(TJS_W("-gsplit"), &opt)) { ttstr str(opt); if (str == TJS_W("no")) TVPGraphicSplitOperationType = gsotNone; else if (str == TJS_W("int")) TVPGraphicSplitOperationType = gsotInterlace; else if (str == TJS_W("yes") || str == TJS_W("simple")) TVPGraphicSplitOperationType = gsotSimple; else if (str == TJS_W("bidi")) TVPGraphicSplitOperationType = gsotBiDirection; } } // check TVPDefaultHoldAlpha option if(TVPGetCommandLine(TJS_W("-holdalpha"), &opt)) { ttstr str(opt); if(str == TJS_W("yes") || str == TJS_W("true")) TVPDefaultHoldAlpha = true; else TVPDefaultHoldAlpha = false; } // check TVPJPEGFastLoad option if(TVPGetCommandLine(TJS_W("-jpegdec"), &opt)) // this specifies precision for JPEG decoding { ttstr str(opt); if(str == TJS_W("normal")) TVPJPEGLoadPrecision = jlpMedium; else if(str == TJS_W("low")) TVPJPEGLoadPrecision = jlpLow; else if(str == TJS_W("high")) TVPJPEGLoadPrecision = jlpHigh; } // dump option TVPDumpOptions(); // initilaize x86 graphic routines #if 0 #ifndef TJS_64BIT_OS TVPGL_IA32_Init(); #endif TVPGL_SSE2_Init(); #endif TVPGL_ASM_Init(); // timer precision uint32_t prectick = 1; if(TVPGetCommandLine(TJS_W("-timerprec"), &opt)) { ttstr str(opt); if(str == TJS_W("high")) prectick = 1; if(str == TJS_W("higher")) prectick = 5; if(str == TJS_W("normal")) prectick = 10; } // draw thread num tjs_int drawThreadNum = 0; if (TVPGetCommandLine(TJS_W("-drawthread"), &opt)) { ttstr str(opt); if (str == TJS_W("auto")) drawThreadNum = 0; else drawThreadNum = (tjs_int)opt; } TVPDrawThreadNum = drawThreadNum; #if 0 if(prectick) { // retrieve minimum timer resolution TIMECAPS tc; timeGetDevCaps(&tc, sizeof(tc)); if(prectick < tc.wPeriodMin) TVPTimeBeginPeriodRes = tc.wPeriodMin; else TVPTimeBeginPeriodRes = prectick; if(TVPTimeBeginPeriodRes > tc.wPeriodMax) TVPTimeBeginPeriodRes = tc.wPeriodMax; // set timer resolution timeBeginPeriod(TVPTimeBeginPeriodRes); TVPHighTimerPeriod = true; } TVPPushEnvironNoise(&TVPCPUType, sizeof(TVPCPUType)); // set LFH if(TVPGetCommandLine(TJS_W("-uselfh"), &opt)) { ttstr str(opt); if(str == TJS_W("yes") || str == TJS_W("true")) { ULONG HeapInformation = 2; BOOL lfhenable = ::HeapSetInformation( GetProcessHeap(), HeapCompatibilityInformation, &HeapInformation, sizeof(HeapInformation) ); if( lfhenable ) { TVPAddLog( TJS_W("(info) Enable LFH") ); } else { TVPAddLog( TJS_W("(info) Cannot Enable LFH") ); } } } // Global Heap Compact if(TVPGetCommandLine(TJS_W("-ghcompact"), &opt)) { ttstr str(opt); if(str == TJS_W("yes") || str == TJS_W("true")) { TVPEnableGlobalHeapCompaction = true; } } #endif } //--------------------------------------------------------------------------- void TVPBeforeSystemUninit() { // TVPDumpHWException(); // dump cached hw exceptoin } //--------------------------------------------------------------------------- void TVPAfterSystemUninit() { #if 0 // restore timer precision if(TVPHighTimerPeriod) { timeEndPeriod(TVPTimeBeginPeriodRes); } #endif } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- bool TVPTerminated = false; bool TVPTerminateOnWindowClose = true; bool TVPTerminateOnNoWindowStartup = true; int TVPTerminateCode = 0; //--------------------------------------------------------------------------- void TVPTerminateAsync(int code) { // do "A"synchronous temination of application TVPTerminated = true; TVPTerminateCode = code; // posting dummy message will prevent "missing WM_QUIT bug" in Direct3D framework. if(TVPSystemControl) TVPSystemControl->CallDeliverAllEventsOnIdle(); Application->Terminate(); if(TVPSystemControl) TVPSystemControl->CallDeliverAllEventsOnIdle(); } //--------------------------------------------------------------------------- void TVPTerminateSync(int code) { // do synchronous temination of application (never return) TVPSystemUninit(); TVPExitApplication(code); } //--------------------------------------------------------------------------- void TVPMainWindowClosed() { // called from WindowIntf.cpp, caused by closing all window. if( TVPTerminateOnWindowClose) TVPTerminateAsync(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // GetCommandLine //--------------------------------------------------------------------------- static std::vector * TVPGetEmbeddedOptions() { #if 0 HMODULE hModule = ::GetModuleHandle(NULL); const char *buf = NULL; unsigned int size = 0; HRSRC hRsrc = ::FindResource(NULL, MAKEINTRESOURCE(IDR_OPTION), TEXT("TEXT")); if( hRsrc != NULL ) { size = ::SizeofResource( hModule, hRsrc ); HGLOBAL hGlobal = ::LoadResource( hModule, hRsrc ); if( hGlobal != NULL ) { buf = reinterpret_cast(::LockResource(hGlobal)); } } if( buf == NULL ) return NULL; #endif std::vector *ret = NULL; #if 0 try { ret = new std::vector(); const char *tail = buf + size; const char *start = buf; while( buf < tail ) { if( buf[0] == 0x0D && buf[1] == 0x0A ) { // CR LF ret->push_back( std::string(start,buf) ); start = buf + 2; buf++; } else if( buf[0] == 0x0D || buf[0] == 0x0A ) { // CR or LF ret->push_back( std::string(start,buf) ); start = buf + 1; } else if( buf[0] == '\0' ) { ret->push_back( std::string(start,buf) ); start = buf + 1; break; } buf++; } if( start < buf ) { ret->push_back( std::string(start,buf) ); } } catch(...) { if(ret) delete ret; throw; } TVPAddImportantLog( (const tjs_char*)TVPInfoLoadingExecutableEmbeddedOptionsSucceeded ); #endif return ret; } //--------------------------------------------------------------------------- static std::vector * TVPGetConfigFileOptions(const ttstr& filename) { #if 0 // load .cf file std::wstring errmsg; if(!FileExists(filename)) errmsg = (const tjs_char*)TVPFileNotFound; #endif std::vector * ret = NULL; // new std::vector(); #if 0 if (errmsg == TJS_W("")) { try { ret = LoadLinesFromFile(filename); } catch(Exception & e) { errmsg = e.what(); } catch(...) { delete ret; throw; } } if(errmsg != TJS_W("")) TVPAddImportantLog( TVPFormatMessage(TVPInfoLoadingConfigurationFileFailed, filename.c_str(), errmsg.c_str()) ); else TVPAddImportantLog( TVPFormatMessage(TVPInfoLoadingConfigurationFileSucceeded, filename.c_str()) ); #endif return ret; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- static ttstr TVPParseCommandLineOne(const ttstr &i) { // value is specified const tjs_char *p, *o; p = o = i.c_str(); p = TJS_strchr(p, '='); if(p == NULL) { return i + TJS_W("=yes"); } p++; ttstr optname(o, (int)(p - o)); if(*p == TJS_W('\'') || *p == TJS_W('\"')) { // as an escaped string tTJSVariant v; TJSParseString(v, &p); return optname + ttstr(v); } else { // as a string return optname + p; } } //--------------------------------------------------------------------------- std::vector TVPProgramArguments; static bool TVPProgramArgumentsInit = false; static tjs_int TVPCommandLineArgumentGeneration = 0; static bool TVPDataPathDirectoryEnsured = false; //--------------------------------------------------------------------------- tjs_int TVPGetCommandLineArgumentGeneration() { return TVPCommandLineArgumentGeneration; } //--------------------------------------------------------------------------- void TVPEnsureDataPathDirectory() { if(!TVPDataPathDirectoryEnsured) { TVPDataPathDirectoryEnsured = true; // ensure data path existence if(!TVPCheckExistentLocalFolder(TVPNativeDataPath.c_str())) { if(TVPCreateFolders(TVPNativeDataPath.c_str())) TVPAddImportantLog( TVPFormatMessage( TVPInfoDataPathDoesNotExistTryingToMakeIt, (const tjs_char*)TVPOk ) ); else TVPAddImportantLog( TVPFormatMessage( TVPInfoDataPathDoesNotExistTryingToMakeIt, (const tjs_char*)TVPFaild ) ); } } } //--------------------------------------------------------------------------- static void PushAllCommandlineArguments() { #if 0 // store arguments given by commandline to "TVPProgramArguments" bool acceptfilenameargument = GetSystemSecurityOption("acceptfilenameargument") != 0; bool argument_stopped = false; if(acceptfilenameargument) argument_stopped = true; int file_argument_count = 0; for(tjs_int i = 1; i<_argc; i++) { if(argument_stopped) { ttstr arg_name_and_value = TJS_W("-arg") + ttstr(file_argument_count) + TJS_W("=") + ttstr(_argv[i]); file_argument_count++; TVPProgramArguments.push_back(arg_name_and_value); } else { if(_argv[i][0] == '-') { if(_argv[i][1] == '-' && _argv[i][2] == 0) { // argument stopper argument_stopped = true; } else { ttstr value(_argv[i]); if(!TJS_strchr(value.c_str(), TJS_W('='))) value += TJS_W("=yes"); TVPProgramArguments.push_back(TVPParseCommandLineOne(value)); } } } } #endif } //--------------------------------------------------------------------------- static void PushConfigFileOptions(const std::vector * options) { if(!options) return; for(unsigned int j = 0; j < options->size(); j++) { if( (*options)[j].c_str()[0] != ';') // unless comment TVPProgramArguments.push_back( TVPParseCommandLineOne(TJS_W("-") + ttstr((*options)[j].c_str()))); } } //--------------------------------------------------------------------------- static void TVPInitProgramArgumentsAndDataPath(bool stop_after_datapath_got) { if(!TVPProgramArgumentsInit) { TVPProgramArgumentsInit = true; // find options from self executable image const int num_option_layers = 3; std::vector * options[num_option_layers]; for(int i = 0; i < num_option_layers; i++) options[i] = NULL; try { // read embedded options and default configuration file options[0] = TVPGetEmbeddedOptions(); // options[1] = TVPGetConfigFileOptions(ApplicationSpecialPath::GetConfigFileName(ExePath())); // at this point, we need to push all exsting known options // to be able to see datapath PushAllCommandlineArguments(); PushConfigFileOptions(options[1]); // has more priority PushConfigFileOptions(options[0]); // has lesser priority // read datapath tTJSVariant val; ttstr config_datapath; // if(TVPGetCommandLine(TJS_W("-datapath"), &val)) // config_datapath = ((ttstr)val).AsStdString(); TVPNativeDataPath = ApplicationSpecialPath::GetDataPathDirectory(config_datapath, ExePath()); if(stop_after_datapath_got) return; // read per-user configuration file // options[2] = TVPGetConfigFileOptions(ApplicationSpecialPath::GetUserConfigFileName(config_datapath, ExePath())); // push each options into option stock // we need to clear TVPProgramArguments first because of the // option priority order. TVPProgramArguments.clear(); PushAllCommandlineArguments(); PushConfigFileOptions(options[2]); // has more priority PushConfigFileOptions(options[1]); // has more priority PushConfigFileOptions(options[0]); // has lesser priority } catch(...) { for(int i = 0; i < num_option_layers; i++) if(options[i]) delete options[i]; throw; } for(int i = 0; i < num_option_layers; i++) if(options[i]) delete options[i]; // set data path TVPDataPath = TVPNormalizeStorageName(TVPNativeDataPath); TVPAddImportantLog( TVPFormatMessage( TVPInfoDataPath, TVPDataPath) ); // set log output directory TVPSetLogLocation(TVPNativeDataPath); // increment TVPCommandLineArgumentGeneration TVPCommandLineArgumentGeneration++; } } //--------------------------------------------------------------------------- static void TVPDumpOptions() { std::vector::const_iterator i; ttstr options( TVPInfoSpecifiedOptionEarlierItemHasMorePriority ); if(TVPProgramArguments.size()) { for(i = TVPProgramArguments.begin(); i != TVPProgramArguments.end(); i++) { options += TJS_W(" "); options += *i; } } else { options += (const tjs_char*)TVPNone; } TVPAddImportantLog(options); } //--------------------------------------------------------------------------- bool TVPGetCommandLine(const tjs_char * name, tTJSVariant *value) { TVPInitProgramArgumentsAndDataPath(false); tjs_int namelen = (tjs_int)TJS_strlen(name); std::vector::const_iterator i; for(i = TVPProgramArguments.begin(); i != TVPProgramArguments.end(); i++) { if(!TJS_strncmp(i->c_str(), name, namelen)) { if(i->c_str()[namelen] == TJS_W('=')) { // value is specified const tjs_char *p = i->c_str() + namelen + 1; if(value) *value = p; return true; } else if(i->c_str()[namelen] == 0) { // value is not specified if(value) *value = TJS_W("yes"); return true; } } } return false; } //--------------------------------------------------------------------------- void TVPSetCommandLine(const tjs_char * name, const ttstr & value) { // TVPInitProgramArgumentsAndDataPath(false); tjs_int namelen = (tjs_int)TJS_strlen(name); std::vector::iterator i; for(i = TVPProgramArguments.begin(); i != TVPProgramArguments.end(); i++) { if(!TJS_strncmp(i->c_str(), name, namelen)) { if(i->c_str()[namelen] == TJS_W('=') || i->c_str()[namelen] == 0) { // value found *i = ttstr(i->c_str(), namelen) + TJS_W("=") + value; TVPCommandLineArgumentGeneration ++; if(TVPCommandLineArgumentGeneration == 0) TVPCommandLineArgumentGeneration = 1; return; } } } // value not found; insert argument into front TVPProgramArguments.insert(TVPProgramArguments.begin(), ttstr(name) + TJS_W("=") + value); TVPCommandLineArgumentGeneration ++; if(TVPCommandLineArgumentGeneration == 0) TVPCommandLineArgumentGeneration = 1; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCheckPrintDataPath //--------------------------------------------------------------------------- bool TVPCheckPrintDataPath() { #if 0 // print current datapath to stdout, then exit for(int i=1; i<_argc; i++) { if(!strcmp(_argv[i], "-printdatapath")) // this does not refer TVPGetCommandLine { TVPInitProgramArgumentsAndDataPath(true); wprintf(L"%s\n", TVPNativeDataPath.c_str()); return true; // processed } } #endif return false; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCheckAbout //--------------------------------------------------------------------------- bool TVPCheckAbout(void) { #if 0 if(TVPGetCommandLine(TJS_W("-about"))) { Sleep(600); tjs_char msg[80]; TJS_snprintf(msg, sizeof(msg)/sizeof(tjs_char), TVPInfoCpuClockRoughly, (int)TVPCPUClock); TVPAddImportantLog(msg); TVPShowVersionForm(); return true; } #endif return false; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPExecuteAsync //--------------------------------------------------------------------------- static void TVPExecuteAsync( const std::wstring& progname) { #if 0 STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_SHOWNORMAL; BOOL ret = CreateProcess( NULL, const_cast(progname.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if(ret) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return; } throw Exception(ttstr(TVPExecutionFail).AsStdString()); #endif } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPWaitWritePermit //--------------------------------------------------------------------------- static bool TVPWaitWritePermit(const std::wstring& fn) { return false; #if 0 tjs_int timeout = 10; // 10/1 = 5 seconds while(true) { HANDLE h = CreateFile(fn.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(h != INVALID_HANDLE_VALUE) { CloseHandle(h); return true; } Sleep(500); timeout--; if(timeout == 0) return false; } #endif } //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // TVPShowUserConfig //--------------------------------------------------------------------------- static void TVPShowUserConfig(std::string orgexe) { TVPEnsureDataPathDirectory(); Application->SetTitle( ChangeFileExt(ExtractFileName(orgexe), "") ); TConfSettingsForm *form = new TConfSettingsForm(Application, true); form->InitializeConfig(orgexe); form->ShowModal(); delete form; } //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- // TVPExecuteUserConfig //--------------------------------------------------------------------------- bool TVPExecuteUserConfig() { return false; // check command line argument #if 0 tjs_int i; bool process = false; for(i=1; i<_argc; i++) { if(!strcmp(_argv[i], "-userconf")) // this does not refer TVPGetCommandLine process = true; } if(!process) return false; // execute user config mode //TVPShowUserConfig(ExePath()); TVPShowUserConfig(); // exit return true; #endif } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/win32/SysInitImpl.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // System Initialization and Uninitialization //--------------------------------------------------------------------------- #ifndef SysInitImplH #define SysInitImplH //--------------------------------------------------------------------------- extern void TVPDumpHWException(); extern void TVPInitializeBaseSystems(); extern ttstr TVPNativeProjectDir; extern ttstr TVPNativeDataPath; extern bool TVPProjectDirSelected; extern void TVPEnsureDataPathDirectory(); extern bool TVPExecuteUserConfig(); extern bool TVPTerminated; extern bool TVPTerminateOnWindowClose; extern bool TVPTerminateOnNoWindowStartup; extern int TVPTerminateCode; //--------------------------------------------------------------------------- #include "SysInitIntf.h" #endif ================================================ FILE: src/core/base/win32/SystemImpl.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // "System" class implementation //--------------------------------------------------------------------------- #include "tjsCommHead.h" // #include // #include #include "GraphicsLoaderImpl.h" #include "SystemImpl.h" #include "SystemIntf.h" #include "SysInitIntf.h" #include "StorageIntf.h" #include "StorageImpl.h" #include "TickCount.h" #include "ComplexRect.h" #include "WindowImpl.h" #include "SystemControl.h" #include "DInputMgn.h" #include "Application.h" #include "TVPScreen.h" //#include "CompatibleNativeFuncs.h" #include "DebugIntf.h" //#include "VersionFormUnit.h" #include "vkdefine.h" #include "ScriptMgnIntf.h" #include "tjsArray.h" #include "Platform.h" //--------------------------------------------------------------------------- static ttstr TVPAppTitle; static bool TVPAppTitleInit = false; //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // TVPShowSimpleMessageBox //--------------------------------------------------------------------------- static void TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption) { HWND hWnd = TVPGetModalWindowOwnerHandle(); if( hWnd == INVALID_HANDLE_VALUE ) { hWnd = NULL; } ::MessageBox( hWnd, text.AsStdString().c_str(), caption.AsStdString().c_str(), MB_OK|MB_ICONINFORMATION ); } //--------------------------------------------------------------------------- #endif bool TVPGetKeyMouseAsyncState(tjs_uint keycode, bool getcurrent); //--------------------------------------------------------------------------- // TVPGetAsyncKeyState //--------------------------------------------------------------------------- bool TVPGetAsyncKeyState(tjs_uint keycode, bool getcurrent) { // get keyboard state asynchronously. // return current key state if getcurrent is true. // otherwise, return whether the key is pushed during previous call of // TVPGetAsyncKeyState at the same keycode. if(keycode >= VK_PAD_FIRST && keycode <= VK_PAD_LAST) { // JoyPad related keys are treated in DInputMgn.cpp return TVPGetJoyPadAsyncState(keycode, getcurrent); } return TVPGetKeyMouseAsyncState(keycode, getcurrent); #if 0 if(keycode == VK_LBUTTON || keycode == VK_RBUTTON) { // check whether the mouse button is swapped if(GetSystemMetrics(SM_SWAPBUTTON)) { // mouse button had been swapped; swap key code if(keycode == VK_LBUTTON) keycode = VK_RBUTTON; else keycode = VK_LBUTTON; } } return 0!=( GetAsyncKeyState(keycode) & ( getcurrent?0x8000:0x0001) ); #endif } //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // TVPGetPlatformName //--------------------------------------------------------------------------- ttstr TVPGetPlatformName() { SYSTEM_INFO sysInfo; ::GetNativeSystemInfo( &sysInfo ); switch( sysInfo.wProcessorArchitecture ) { case PROCESSOR_ARCHITECTURE_AMD64: case PROCESSOR_ARCHITECTURE_IA64: return ttstr(TJS_W("Win64")); case PROCESSOR_ARCHITECTURE_INTEL: case PROCESSOR_ARCHITECTURE_UNKNOWN: default: return ttstr(TJS_W("Win32")); } } //--------------------------------------------------------------------------- typedef void (WINAPI *RtlGetVersionFunc)(OSVERSIONINFOEX* ); //--------------------------------------------------------------------------- // TVPGetOSName //--------------------------------------------------------------------------- ttstr TVPGetOSName() { OSVERSIONINFOEX ovi; ovi.dwOSVersionInfoSize = sizeof(ovi); bool isGetVersion = false; HMODULE hModule = ::LoadLibrary( L"ntdll.dll" ); if( hModule ) { RtlGetVersionFunc func; func = (RtlGetVersionFunc)::GetProcAddress( hModule, "RtlGetVersion" ); if( func ) { func( &ovi ); isGetVersion = true; } ::FreeLibrary( hModule ); hModule = NULL; } if( isGetVersion == false ) { GetVersionEx((OSVERSIONINFO*)&ovi); } tjs_char buf[256]; const tjs_char *osname = NULL; switch(ovi.dwPlatformId) { case VER_PLATFORM_WIN32s: osname = TJS_W("Win32s"); break; case VER_PLATFORM_WIN32_WINDOWS: switch((ovi.dwBuildNumber&0xffff )) { case 1998: osname = TJS_W("Windows 98"); break; case 95: osname = TJS_W("Windows 95"); break; default: osname = TJS_W("Win9x"); break; } break; case VER_PLATFORM_WIN32_NT: if( ovi.dwMajorVersion == 5 ) { switch(ovi.dwMinorVersion) { case 0: osname = TJS_W("Windows 2000"); break; case 1: osname = TJS_W("Windows XP"); break; case 2: osname = TJS_W("Windows Server 2003"); break; } } else if( ovi.dwMajorVersion == 6 ) { switch(ovi.dwMinorVersion) { case 0: if( ovi.wProductType == VER_NT_WORKSTATION ) osname = TJS_W("Windows Vista"); else osname = TJS_W("Windows Server 2008"); break; case 1: if( ovi.wProductType == VER_NT_WORKSTATION ) osname = TJS_W("Windows 7"); else osname = TJS_W("Windows Server 2008 R2"); break; case 2: if( ovi.wProductType == VER_NT_WORKSTATION ) osname = TJS_W("Windows 8"); else osname = TJS_W("Windows Server 2012"); break; case 3: if( ovi.wProductType == VER_NT_WORKSTATION ) osname = TJS_W("Windows 8.1"); else osname = TJS_W("Windows Server 2012 R2"); break; case 4: if( ovi.wProductType == VER_NT_WORKSTATION ) osname = TJS_W("Windows 10"); break; } } if( osname == NULL ) osname = TJS_W("Windows NT"); break; default: osname = TJS_W("Unknown"); break; } TJS_snprintf(buf, sizeof(buf)/sizeof(tjs_char), TJS_W("%ls %d.%d.%d "), osname, ovi.dwMajorVersion, ovi.dwMinorVersion, ovi.dwBuildNumber&0xfff); ttstr str(buf); str += ttstr(ovi.szCSDVersion); return str; } //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- // TVPGetOSBits //--------------------------------------------------------------------------- tjs_int TVPGetOSBits() { #if 0 SYSTEM_INFO sysInfo; ::GetNativeSystemInfo( &sysInfo ); switch( sysInfo.wProcessorArchitecture ) { case PROCESSOR_ARCHITECTURE_AMD64: case PROCESSOR_ARCHITECTURE_IA64: return 64; case PROCESSOR_ARCHITECTURE_INTEL: case PROCESSOR_ARCHITECTURE_UNKNOWN: default: return 32; } #endif return 32; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPShellExecute //--------------------------------------------------------------------------- bool TVPShellExecute(const ttstr &target, const ttstr ¶m) { // open or execute target file // ttstr file = TVPGetNativeName(TVPNormalizeStorageName(target)); #if 0 return TVPIsExistentStorageNoSearchNoNormalize(target); if (::ShellExecute(NULL, NULL, target.c_str(), param.IsEmpty() ? NULL : param.c_str(), L"", SW_SHOWNORMAL) <=(void *)32) { return false; } else #endif { return true; } } //--------------------------------------------------------------------------- static tTJSVariant RegisterData; ttstr TVPGetAppDataPath(); void TVPExecuteStorage(const ttstr &name, tTJSVariant *result, bool isexpression, const tjs_char * modestr); static void InitRegisterData() { static bool dataInited = false; if (!dataInited) { ttstr regfile = TVPGetAppDataPath() + TJS_W("RegisterData.tjs"); if (TVPIsExistentStorageNoSearch(regfile)) { TVPExecuteStorage(regfile, &RegisterData, true, TJS_W("")); } } } //--------------------------------------------------------------------------- // TVPReadRegValue //--------------------------------------------------------------------------- static void TVPReadRegValue(tTJSVariant &result, const ttstr & key) { // open specified registry key if(key.IsEmpty()) { result.Clear(); return; } // check whether the key contains root key name //HKEY root = HKEY_CURRENT_USER; const tjs_char *key_p = key.c_str(); InitRegisterData(); // search value name tTJSVariant CurrentNode = RegisterData; const tjs_char *start = key_p; while (*start && CurrentNode.Type() != tvtObject) { iTJSDispatch2 *pObj; switch (*key_p) { case '\\': case '/': ++key_p; case '\0': start = key_p; if (CurrentNode.Type() != tvtObject) { CurrentNode.Clear(); break; } pObj = CurrentNode.AsObject(); if (!pObj) { CurrentNode.Clear(); break; } if (!TJS_SUCCEEDED(pObj->PropGet(TJS_MEMBERMUSTEXIST, ttstr(start, key_p - start - 1).c_str(), 0, &CurrentNode, pObj))) { CurrentNode.Clear(); break; } start = key_p; continue; default: ++key_p; continue; } } if (*start) { CurrentNode.Clear(); return; } result = CurrentNode; #if 0 if(key.StartsWith(TJS_W("HKEY_CLASSES_ROOT"))) { key_p += 17; root = HKEY_CLASSES_ROOT; } else if(key.StartsWith(TJS_W("HKEY_CURRENT_CONFIG"))) { key_p += 19; root = HKEY_CURRENT_CONFIG; } else if(key.StartsWith(TJS_W("HKEY_CURRENT_USER"))) { key_p += 17; root = HKEY_CURRENT_USER; } else if(key.StartsWith(TJS_W("HKEY_LOCAL_MACHINE"))) { key_p += 18; root = HKEY_LOCAL_MACHINE; } else if(key.StartsWith(TJS_W("HKEY_USERS"))) { key_p += 10; root = HKEY_USERS; } else if(key.StartsWith(TJS_W("HKEY_PERFORMANCE_DATA"))) { key_p += 21; root = HKEY_PERFORMANCE_DATA; } else if(key.StartsWith(TJS_W("HKEY_DYN_DATA"))) { key_p += 13; root = HKEY_DYN_DATA; } if(*key_p == TJS_W('\\')) key_p ++; // search value name const tjs_char *start = key_p; key_p += TJS_strlen(key_p); key_p--; while(start <= key_p && *key_p != TJS_W('\\')) key_p--; ttstr valuename(key_p+1); if(key_p < start || *key_p != TJS_W('\\')) key_p++; ttstr keyname(start, (int)(key_p - start)); // open key HKEY handle; LONG res = RegOpenKeyEx(root, keyname.AsStdString().c_str(), 0, KEY_READ, &handle); if(res != ERROR_SUCCESS) { result.Clear(); return; } // try query value size and read key DWORD size; DWORD type; // query size res = RegQueryValueEx(handle, valuename.c_str(), 0, &type, NULL, &size); if(res != ERROR_SUCCESS) { RegCloseKey(handle); result.Clear(); return; } switch(type) { case REG_DWORD: // case REG_DWORD_LITTLE_ENDIAN: // is actually the same as REG_DWORD case REG_DWORD_BIG_ENDIAN: case REG_EXPAND_SZ: case REG_SZ: break; // these should be OK case REG_MULTI_SZ: // sorry not yet implemented case REG_BINARY: case REG_LINK: case REG_NONE: case REG_RESOURCE_LIST: default: // not capable types RegCloseKey(handle); result.Clear(); return; } while(true) { tjs_uint8 * data = new tjs_uint8[size]; try { DWORD size2 = size; res = RegQueryValueEx(handle, valuename.c_str(), 0, NULL, data, &size2); if(res == ERROR_MORE_DATA) { // more data required delete [] data; size += 1024; continue; } else if(res != ERROR_SUCCESS) { RegCloseKey(handle); result.Clear(); return; } // query succeeded // store data into result switch(type) { case REG_DWORD: // case REG_DWORD_LITTLE_ENDIAN: result = (tTVInteger)*(DWORD*)data; break; case REG_DWORD_BIG_ENDIAN: { DWORD val = *(DWORD*)data; val = (val >> 24) + ((val >> 8) & 0x0000ff00) + ((val << 8) & 0x00ff0000) + (val << 24); result = (tTVInteger)val; } break; case REG_EXPAND_SZ: case REG_SZ: // data is stored in unicode result = ttstr((const tjs_char*)data); break; } } catch(...) { RegCloseKey(handle); delete [] data; throw; } RegCloseKey(handle); delete [] data; break; } #endif } //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- // Static function for retrieving special folder path //--------------------------------------------------------------------------- static ttstr TVPGetSpecialFolderPath(int csidl) { WCHAR path[MAX_PATH+1]; if(!SHGetSpecialFolderPath(NULL, path, csidl, false)) return ttstr(); return ttstr(path); } //--------------------------------------------------------------------------- #endif //--------------------------------------------------------------------------- // TVPGetPersonalPath //--------------------------------------------------------------------------- ttstr TVPGetPersonalPath() { #if 0 // Retrieve personal directory; // This usually refers "My Documents". // If this is not exist, returns application data path, then exe path. // for windows vista, this refers application data path. ttstr path; path = TVPGetSpecialFolderPath(CSIDL_PERSONAL); if(path.IsEmpty()) path = TVPGetSpecialFolderPath(CSIDL_APPDATA); if(!path.IsEmpty()) { path = TVPNormalizeStorageName(path); if(path.GetLastChar() != TJS_W('/')) path += TJS_W('/'); return path; } #endif return TVPGetAppPath(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetAppDataPath //--------------------------------------------------------------------------- ttstr TVPGetAppDataPath() { #if 0 // Retrieve application data directory; // If this is not exist, returns application exe path. ttstr path = TVPGetSpecialFolderPath(CSIDL_APPDATA); if(!path.IsEmpty()) { path = TVPNormalizeStorageName(path); if(path.GetLastChar() != TJS_W('/')) path += TJS_W('/'); return path; } #endif return TVPGetAppPath(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetSavedGamesPath //--------------------------------------------------------------------------- ttstr TVPGetSavedGamesPath() { #if 0 ttstr path; PWSTR ppszPath = NULL; HRESULT hr = ::SHGetKnownFolderPath(FOLDERID_SavedGames, 0, NULL, &ppszPath); if( hr == S_OK ) { path = ppszPath; ::CoTaskMemFree( ppszPath ); } return path; #endif return TVPGetAppPath(); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPCreateAppLock //--------------------------------------------------------------------------- bool TVPCreateAppLock(const ttstr &lockname) { #if 0 // lock application using mutex CreateMutex(NULL, TRUE, lockname.c_str()); if(GetLastError()) { return false; // already running } #endif // No need to release the mutex object because the mutex is automatically // released when the calling thread exits. return true; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- enum tTVPTouchDevice { tdNone = 0, tdIntegratedTouch = 0x00000001, tdExternalTouch = 0x00000002, tdIntegratedPen = 0x00000004, tdExternalPen = 0x00000008, tdMultiInput = 0x00000040, tdDigitizerReady = 0x00000080, tdMouse = 0x00000100, tdMouseWheel = 0x00000200 }; /** * ^b`foCX(ƃ}EX)̐ڑԂ擾 **/ static int TVPGetSupportTouchDevice() { int result = 0; #if 0 if( procRegisterTouchWindow ) { int value = ::GetSystemMetrics( SM_DIGITIZER ); if( value & NID_INTEGRATED_TOUCH ) result |= tdIntegratedTouch; if( value & NID_EXTERNAL_TOUCH ) result |= tdExternalTouch; if( value & NID_INTEGRATED_PEN ) result |= tdIntegratedPen; if( value & NID_EXTERNAL_PEN ) result |= tdExternalPen; if( value & NID_MULTI_INPUT ) result |= tdMultiInput; if( value & NID_READY ) result |= tdDigitizerReady; } int value = ::GetSystemMetrics( SM_MOUSEPRESENT ); if( value ) { result |= tdMouse; value = ::GetSystemMetrics( SM_MOUSEWHEELPRESENT ); if( value ) result |= tdMouseWheel; } #endif result |= tdMouse; result |= tdMouseWheel; return result; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // System.onActivate and System.onDeactivate related //--------------------------------------------------------------------------- static void TVPOnApplicationActivate(bool activate_or_deactivate); //--------------------------------------------------------------------------- class tTVPOnApplicationActivateEvent : public tTVPBaseInputEvent { static tTVPUniqueTagForInputEvent Tag; bool ActivateOrDeactivate; // true for activate; otherwise deactivate public: tTVPOnApplicationActivateEvent(bool activate_or_deactivate) : tTVPBaseInputEvent(Application, Tag), ActivateOrDeactivate(activate_or_deactivate) {}; void Deliver() const { TVPOnApplicationActivate(ActivateOrDeactivate); } }; tTVPUniqueTagForInputEvent tTVPOnApplicationActivateEvent ::Tag; //--------------------------------------------------------------------------- void TVPPostApplicationActivateEvent() { TVPPostInputEvent(new tTVPOnApplicationActivateEvent(true), TVP_EPT_REMOVE_POST); } //--------------------------------------------------------------------------- void TVPPostApplicationDeactivateEvent() { TVPPostInputEvent(new tTVPOnApplicationActivateEvent(false), TVP_EPT_REMOVE_POST); } //--------------------------------------------------------------------------- static void TVPOnApplicationActivate(bool activate_or_deactivate) { // called by event system, to fire System.onActivate or // System.onDeactivate event if(!TVPSystemControlAlive) return; // check the state again (because the state may change during the event delivering). // but note that this implementation might fire activate events even in the application // is already activated (the same as deactivation). if(activate_or_deactivate != Application->GetActivating()) return; // fire the event TVPFireOnApplicationActivateEvent(activate_or_deactivate); } //--------------------------------------------------------------------------- #if 0 //--------------------------------------------------------------------------- static void TVPHeapDump() { tjs_char buff[128]; HANDLE heaps[100]; DWORD c = ::GetProcessHeaps (100, heaps); TJS_sprintf( buff, 128, TJS_W("The process has %d heaps."), c ); TVPAddLog( buff ); const HANDLE default_heap = ::GetProcessHeap(); const HANDLE crt_heap = (HANDLE)_get_heap_handle(); for( unsigned int i = 0; i < c; i++ ) { ULONG heap_info = 0; SIZE_T ret_size = 0; bool isdefault = false; bool isCRT = false; if( ::HeapQueryInformation( heaps[i], HeapCompatibilityInformation, &heap_info, sizeof(heap_info), &ret_size) ) { tjs_char* type = NULL; switch( heap_info ) { case 0: type = TJS_W("standard"); break; case 1: type = TJS_W("LAL"); break; case 2: type = TJS_W("LFH"); break; default: type = TJS_W("unknown"); break; } if( heaps[i] == default_heap ) { isdefault = true; } if( heaps [i] == crt_heap ) { isCRT = true; } PROCESS_HEAP_ENTRY entry; memset( &entry, 0, sizeof (entry) ); struct Info { int count; tjs_int64 total; tjs_int64 overhead; Info() : count(0), total(0), overhead(0) {} } use, uncommit, unused; while( ::HeapWalk( heaps[i], &entry) ) { if( entry.wFlags & PROCESS_HEAP_ENTRY_BUSY ) { use.count++; use.total += entry.cbData; use.overhead += entry.cbOverhead; } else if( entry.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE ) { uncommit.count++; uncommit.total += entry.cbData; uncommit.overhead += entry.cbOverhead; } else { unused.count++; unused.total += entry.cbData; unused.overhead += entry.cbOverhead; } } ttstr mes( TJS_W("#") ); mes += ttstr((tjs_int)(i+1)) + TJS_W(" type: ") + type; if( isdefault ) mes += TJS_W(" [default]"); if( isCRT ) mes += TJS_W(" [CRT]"); TVPAddLog( mes ); TJS_sprintf( buff, 128, L" Allocated: %d, size: %lld, overhead: %lld", use.count, use.total, use.overhead ); TVPAddLog( buff ); TJS_sprintf( buff, 128, L" Uncommitted: %d, size: %lld, overhead: %lld", uncommit.count, uncommit.total, uncommit.overhead ); TVPAddLog( buff ); TJS_sprintf( buff, 128, L" Unused: %d, size: %lld, overhead: %lld", unused.count, unused.total, unused.overhead ); TVPAddLog( buff ); } } } //--------------------------------------------------------------------------- #endif bool TVPAutoSaveBookMark = false; extern void TVPDoSaveSystemVariables() { try { // hack for save system variable iTJSDispatch2* global = TVPGetScriptDispatch(); if (!global) return; tTJSVariant var; if (global->PropGet(0, TJS_W("kag"), nullptr, &var, global) == TJS_S_OK && var.Type() == tvtObject) { iTJSDispatch2* kag = var.AsObjectNoAddRef(); if (kag->PropGet(0, TJS_W("saveSystemVariables"), nullptr, &var, kag) == TJS_S_OK) { iTJSDispatch2* fn = var.AsObjectNoAddRef(); if (fn->IsInstanceOf(0, 0, 0, TJS_W("Function"), fn)) { tTJSVariant *args = nullptr; fn->FuncCall(0, nullptr, nullptr, nullptr, 0, &args, kag); } } if(TVPAutoSaveBookMark && kag->PropGet(0, TJS_W("saveBookMark"), nullptr, &var, kag) == TJS_S_OK && var.Type() == tvtObject) { iTJSDispatch2* fn = var.AsObjectNoAddRef(); if (fn->IsInstanceOf(0, 0, 0, TJS_W("Function"), fn)) { tTJSVariant num((tjs_int32)0); tTJSVariant *args = # fn->FuncCall(0, nullptr, nullptr, nullptr, 1, &args, kag); } } } } catch (...) { ; } } //--------------------------------------------------------------------------- // TVPCreateNativeClass_System //--------------------------------------------------------------------------- tTJSNativeClass * TVPCreateNativeClass_System() { tTJSNC_System *cls = new tTJSNC_System(); // setup some platform-specific members //---------------------------------------------------------------------- //-- methods //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/inform) { // show simple message box if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr text = *param[0]; ttstr caption; if(numparams >= 2 && param[1]->Type() != tvtVoid) caption = *param[1]; else caption = TJS_W("Information"); if (numparams >= 3 && param[2]->Type() != tvtVoid) { if (param[2]->Type() == tvtObject) { // vector of button tTJSArrayNI* ni; param[2]->AsObjectNoAddRef()->NativeInstanceSupport(TJS_NIS_GETINSTANCE, TJSGetArrayClassID(), (iTJSNativeInstance**)&ni); std::vector vecButtons; vecButtons.reserve(ni->Items.size()); for (const ttstr &label : ni->Items) { vecButtons.emplace_back(label); } int ret = TVPShowSimpleMessageBox(text, caption, vecButtons); if (result) result->operator =(ret); } else { int nButtons = param[2]->AsInteger(); std::vector vecButtons; if (nButtons >= 1) vecButtons.emplace_back(TJS_W("OK")); if (nButtons >= 2) vecButtons.emplace_back(TJS_W("Cancel")); int ret = TVPShowSimpleMessageBox(text, caption, vecButtons); if (result) result->operator =(ret); } return TJS_S_OK; } TVPShowSimpleMessageBox(text, caption); if(result) result->Clear(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/inform) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getTickCount) { if(result) { TVPStartTickCount(); *result = (tjs_int64) TVPGetTickCount(); } return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/getTickCount) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getKeyState) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; tjs_uint code = (tjs_int)*param[0]; bool getcurrent = true; if(numparams >= 2) getcurrent = 0!=(tjs_int)*param[1]; bool res = TVPGetAsyncKeyState(code, getcurrent); if(result) *result = (tjs_int)res; return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/getKeyState) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/shellExecute) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr target = *param[0]; ttstr execparam; if(numparams >= 2) execparam = *param[1]; bool res = TVPShellExecute(target, execparam); if(result) *result = (tjs_int)res; return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/shellExecute) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/system) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; ttstr target = *param[0]; int ret = 0;// _wsystem(target.c_str()); TVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MAX); // this should clear all caches if(result) *result = (tjs_int)ret; return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/system) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/readRegValue) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; if(!result) return TJS_S_OK; ttstr key = *param[0]; TVPReadRegValue(*result, key); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/readRegValue) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/getArgument) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; if(!result) return TJS_S_OK; ttstr name = *param[0]; bool res = TVPGetCommandLine(name.c_str(), result); if(!res) result->Clear(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/getArgument) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/setArgument) { if(numparams < 2) return TJS_E_BADPARAMCOUNT; ttstr name = *param[0]; ttstr value = *param[1]; TVPSetCommandLine(name.c_str(), value); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/setArgument) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/createAppLock) { if(numparams < 1) return TJS_E_BADPARAMCOUNT; if(!result) return TJS_S_OK; ttstr lockname = *param[0]; bool res = TVPCreateAppLock(lockname); if(result) *result = (tjs_int)res; return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/createAppLock) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/dumpHeap) { // TVPHeapDump(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/dumpHeap) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/nullpo) { // force make a null-po #ifdef _MSC_VER *(int *)0 = 0; #else __builtin_trap(); #endif return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/nullpo) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_METHOD_DECL(/*func. name*/showVersion) { // TVPShowVersionForm(); return TJS_S_OK; } TJS_END_NATIVE_STATIC_METHOD_DECL_OUTER(/*object to register*/cls, /*func. name*/showVersion) //--------------------------------------------------------------------------- //---------------------------------------------------------------------- //-- properties //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(exePath) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetAppPath(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, exePath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(personalPath) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetPersonalPath(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, personalPath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(appDataPath) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetAppDataPath(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, appDataPath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(dataPath) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPDataPath; return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, dataPath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(exeName) { TJS_BEGIN_NATIVE_PROP_GETTER { static ttstr exename(TVPNormalizeStorageName(ExePath())); *result = exename; return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, exeName) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(savedGamesPath) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetSavedGamesPath(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, savedGamesPath) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(title) { TJS_BEGIN_NATIVE_PROP_GETTER { if(!TVPAppTitleInit) { TVPAppTitleInit = true; TVPAppTitle = Application->GetTitle(); } *result = TVPAppTitle; return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_BEGIN_NATIVE_PROP_SETTER { TVPAppTitle = *param; Application->SetTitle( TVPAppTitle.AsStdString() ); return TJS_S_OK; } TJS_END_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, title) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(screenWidth) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = tTVPScreen::GetWidth(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, screenWidth) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(screenHeight) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = tTVPScreen::GetHeight(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, screenHeight) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(desktopLeft) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = tTVPScreen::GetDesktopLeft(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, desktopLeft) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(desktopTop) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = tTVPScreen::GetDesktopTop(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, desktopTop) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(desktopWidth) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = tTVPScreen::GetDesktopWidth(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, desktopWidth) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(desktopHeight) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = tTVPScreen::GetDesktopHeight(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, desktopHeight) //---------------------------------------------------------------------- TJS_BEGIN_NATIVE_PROP_DECL(touchDevice) { TJS_BEGIN_NATIVE_PROP_GETTER { *result = TVPGetSupportTouchDevice(); return TJS_S_OK; } TJS_END_NATIVE_PROP_GETTER TJS_DENY_NATIVE_PROP_SETTER } TJS_END_NATIVE_STATIC_PROP_DECL_OUTER(cls, touchDevice) //---------------------------------------------------------------------- return cls; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/base/win32/SystemImpl.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // "System" class implementation //--------------------------------------------------------------------------- #ifndef SystemImplH #define SystemImplH //--------------------------------------------------------------------------- TJS_EXP_FUNC_DEF(bool, TVPGetAsyncKeyState, (tjs_uint keycode, bool getcurrent = true)); //--------------------------------------------------------------------------- extern void TVPPostApplicationActivateEvent(); extern void TVPPostApplicationDeactivateEvent(); extern bool TVPShellExecute(const ttstr &target, const ttstr ¶m); extern void TVPDoSaveSystemVariables(); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/base/win32/win32io.h ================================================ #pragma once #ifdef WIN32 // posix io api extern "C" { extern __int64 __cdecl lseek64(int _FileHandle, __int64 _Offset, int _Origin); extern void* valloc(int n); extern void vfree(void *p); } #endif #ifdef CC_TARGET_OS_IPHONE #define lseek64 lseek #endif ================================================ FILE: src/core/environ/Application.cpp ================================================ #include "tjsCommHead.h" #include #include #include #include #include "tjsError.h" #include "tjsDebug.h" #include "Application.h" #include "SysInitIntf.h" #include "SysInitImpl.h" #include "DebugIntf.h" #include "MsgIntf.h" #include "ScriptMgnIntf.h" #include "tjsError.h" #include "PluginImpl.h" #include "SystemIntf.h" #include "Exception.h" //#include "Resource.h" #include "SystemControl.h" //#include "MouseCursor.h" #include "SystemImpl.h" #include "WaveImpl.h" #include "GraphicsLoadThread.h" #include "Platform.h" #include "EventIntf.h" #include #include "ConfigManager/LocaleConfigManager.h" #include "StorageIntf.h" extern "C" { #include } #include "TVPColor.h" #include "FontImpl.h" //#include "resource.h" //#pragma comment(lib,"dbghelp.lib") /* kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;dsound.lib;version.lib;mpr.lib;shlwapi.lib;vfw32.lib;imm32.lib;zlib_d.lib;jpeg-6bx_d.lib;libpng_d.lib;onig_s_d.lib;freetype250MT_D.lib;tvpgl_ia32.lib;tvpsnd_ia32.lib;%(AdditionalDependencies) kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;dsound.lib;version.lib;mpr.lib;shlwapi.lib;vfw32.lib;imm32.lib;zlib.lib;jpeg-6bx.lib;libpng.lib;onig_s.lib;freetype250MT.lib;tvpgl_ia32.lib;tvpsnd_ia32.lib;%(AdditionalDependencies) */ tTVPApplication* Application = new tTVPApplication; std::thread::id TVPMainThreadID; static tTJSCriticalSection _NoMemCallBackCS; static void *_reservedMem = malloc(1024 * 1024 * 4); // 4M reserved mem static bool _project_startup = false; tTJS *TVPAppScriptEngine; // ## fix ld: error: undefined symbol: __real_malloc // #define HOOK_MALLOC static void _do_compact() { TVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MAX); } static void _no_memory_cb() { tTJSCSH lock(_NoMemCallBackCS); free(_reservedMem); if (TVPMainThreadID == std::this_thread::get_id()) { _do_compact(); } else { Application->PostUserMessage(_do_compact); } _reservedMem = realloc(0, 1024 * 1024 * 4); } static std::string _title, _msg, _retry, _cancel; static tTJSCriticalSection _cs; typedef void* F_alloc_t(void*, size_t); static void* __do_alloc_func(F_alloc_t *f, void *p, size_t c) { void *ptr = f(p, c); if (!ptr) { _no_memory_cb(); ptr = f(p, c); if (!ptr) { tTJSCSH lock(_cs); const char *btns[2] = { _retry.c_str(), _cancel.c_str() }; while (!ptr && TVPShowSimpleMessageBox(_msg.c_str(), _title.c_str(), 2, btns) == 0) { ptr = f(p, c); } //TVPExitApplication(-1); } } return ptr; } ttstr TVPGetErrorDialogTitle() { const ttstr &title = Application->GetTitle(); if (title.IsEmpty()) { return TVPGetPackageVersionString() + " Error"; } else { return ttstr(TVPGetPackageVersionString()) + " " + title; } } #ifdef HOOK_MALLOC extern "C" { void* tc_malloc(size_t size); void tc_free(void* ptr); void* tc_realloc(void* ptr, size_t size); void* tc_calloc(size_t nmemb, size_t size); void *__real_malloc(size_t); void __real_free(void*); void* __real_realloc(void*, size_t); void* __real_calloc(size_t nmemb, size_t size); #ifdef WIN32 void* tc_malloc(size_t size) { return nullptr; } void tc_free(void* ptr) {} void* tc_realloc(void* ptr, size_t size){ return nullptr; } void* tc_calloc(size_t nmemb, size_t size){ return nullptr; } void *__real_malloc(size_t) { return nullptr; } void __real_free(void*) { return; } void* __real_realloc(void*, size_t) { return nullptr; } void* __real_calloc(size_t nmemb, size_t size){ return nullptr; } #endif static void *__func_malloc(void *, size_t c) { #ifdef TC_MALLOC int *ptr; if (tc_malloc_startup) { ptr = (int *)tc_malloc(c + sizeof(int)); if (ptr) { *ptr++ = 1; } } else { ptr = (int *)__real_malloc(c + sizeof(int)); if (ptr) { *ptr++ = 0; } } return ptr; #else return __real_malloc(c); #endif } void *__wrap_malloc(size_t c) { #ifdef HOOK_MALLOC_FOR_OVERRUN try { return __real_malloc(c); } catch (...) { TVPExitApplication(-1); } #else return __do_alloc_func(__func_malloc, nullptr, c); #endif } static void *__func_realloc(void *p, size_t c) { #ifdef TC_MALLOC if (!p) return __func_malloc(p, c); int *ptr = (int *)p; if (ptr[-1]) { ptr = (int *)tc_realloc(ptr - 1, c + sizeof(int)); } else { ptr = (int *)__real_realloc(ptr - 1, c + sizeof(int)); } return ptr; #else return __real_realloc(p, c); #endif } void *__wrap_realloc(void *p, size_t c) { #ifdef HOOK_MALLOC_FOR_OVERRUN try { return __real_realloc(p, c); } catch (...) { TVPExitApplication(-1); } #else return __do_alloc_func(__func_realloc, p, c); #endif } static void *__func_calloc(void *p, size_t c) { #ifdef TC_MALLOC int *ptr; if (tc_malloc_startup) { ptr = (int *)tc_calloc(c + sizeof(int), 1); if (ptr) { *ptr++ = 1; } } else { ptr = (int *)__real_calloc(c + sizeof(int), 1); if (ptr) { *ptr++ = 0; } } if (ptr) memset(ptr, 0, c); return ptr; #else return __real_calloc(c, 1); #endif } void *__wrap_calloc(size_t nmemb, size_t size) { #ifdef HOOK_MALLOC_FOR_OVERRUN try { return __real_calloc(nmemb, size); } catch (...) { TVPExitApplication(-1); } #else size *= nmemb; void* p = __do_alloc_func(__func_malloc, nullptr, size); if (p) memset(p, 0, size); return p; #endif } void __wrap_free(void *p) { #ifdef HOOK_MALLOC_FOR_OVERRUN try { return __real_free(p); } catch (...) { TVPExitApplication(-1); } #elif defined(TC_MALLOC) int *ptr = (int *)p; if (ptr[-1] == 0) __real_free(ptr - 1); else tc_free(ptr - 1); #else __real_free(p); #endif } } #endif #if 0 #ifdef TJS_64BIT_OS extern void TVPHandleSEHException( int ErrorCode, EXCEPTION_RECORD *P, unsigned long long osEsp, PCONTEXT ctx); #else extern void TVPHandleSEHException( int ErrorCode, EXCEPTION_RECORD *P, unsigned long osEsp, PCONTEXT ctx); #endif // �A�v���P�[�V�����̊J�n���ɌĂ� inline void CheckMemoryLeaksStart() { #ifdef _DEBUG _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF); #endif // _DEBUG } inline void DumpMemoryLeaks() { #ifdef _DEBUG int is_leak = _CrtDumpMemoryLeaks(); assert( !is_leak ); #endif // _DEBUG } #endif ttstr ExePath() { return TVPNativeProjectDir; } bool TVPCheckAbout(); bool TVPCheckPrintDataPath(); void TVPOnError(); void TVPLockSoundMixer(); void TVPUnlockSoundMixer(); static bool _warnLowMem = true; void TVPCheckMemory() { #if defined(_DEBUG) if (_warnLowMem) { tjs_int freeMem = TVPGetSystemFreeMemory(); if (freeMem < 24) { char buf[256]; sprintf(buf, "Insufficient memory (%dMB available)\nYou can diable this notice in global preference.", freeMem); const char *btn = "OK"; TVPShowSimpleMessageBox(buf, "No Memory Warning", 1, &btn); _warnLowMem = false; } } #endif } int TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption) { std::vector normal; normal.emplace_back(LocaleConfigManager::GetInstance()->GetText("msgbox_ok")); return TVPShowSimpleMessageBox(text, caption, normal); } int TVPShowSimpleMessageBoxYesNo(const ttstr & text, const ttstr & caption) { std::vector normal; LocaleConfigManager *mgr = LocaleConfigManager::GetInstance(); normal.emplace_back(mgr->GetText("msgbox_yes")); normal.emplace_back(mgr->GetText("msgbox_no")); return TVPShowSimpleMessageBox(text, caption, normal); } ttstr TVPGetMessageByLocale(const std::string &key) { return LocaleConfigManager::GetInstance()->GetText(key); } int _argc; char ** _argv; #if 0 extern void TVPInitCompatibleNativeFunctions(); extern void TVPLoadMessage(); AcceleratorKeyTable::AcceleratorKeyTable() { // �f�t�H���g��ǂݍ��� hAccel_ = ::LoadAccelerators( (HINSTANCE)GetModuleHandle(0), MAKEINTRESOURCE(IDC_TVPWIN32)); } AcceleratorKeyTable::~AcceleratorKeyTable() { std::map::iterator i = keys_.begin(); for( ; i != keys_.end(); i++ ) { delete (i->second); } } void AcceleratorKeyTable::AddKey( HWND hWnd, WORD id, WORD key, BYTE virt ) { std::map::iterator i = keys_.find(hWnd); if( i != keys_.end() ) { i->second->AddKey(id,key,virt); } else { AcceleratorKey* acc = new AcceleratorKey(); acc->AddKey( id, key, virt ); keys_.insert( std::map::value_type( hWnd, acc ) ); } } void AcceleratorKeyTable::DelKey( HWND hWnd, WORD id ) { std::map::iterator i = keys_.find(hWnd); if( i != keys_.end() ) { i->second->DelKey(id); } } void AcceleratorKeyTable::DelTable( HWND hWnd ) { std::map::iterator i = keys_.find(hWnd); if( i != keys_.end() ) { delete (i->second); keys_.erase(i); } } AcceleratorKey::AcceleratorKey() : hAccel_(NULL), keys_(NULL), key_count_(0) { } AcceleratorKey::~AcceleratorKey() { if( hAccel_ != NULL ) ::DestroyAcceleratorTable( hAccel_ ); delete[] keys_; } void AcceleratorKey::AddKey( WORD id, WORD key, BYTE virt ) { // �܂��͑��݂��邩�`�F�b�N���� bool found = false; int index = 0; for( int i = 0; i < key_count_; i++ ) { if( keys_[i].cmd == id ) { index = i; found = true; break; } } if( found ) { // ���ɓo�^����Ă���R�}���h�Ȃ̂ŃL�[���̍X�V���s�� if( keys_[index].key == key && keys_[index].fVirt == virt ) { // �ύX����Ă��Ȃ� return; } keys_[index].key = key; keys_[index].fVirt = virt; HACCEL hAccel = ::CreateAcceleratorTable( keys_, key_count_ ); if( hAccel_ != NULL ) ::DestroyAcceleratorTable( hAccel_ ); hAccel_ = hAccel; } else { ACCEL* table = new ACCEL[key_count_+1]; for( int i = 0; i < key_count_; i++ ) { table[i] = keys_[i]; } table[key_count_].cmd = id; table[key_count_].key = key; table[key_count_].fVirt = virt; key_count_++; HACCEL hAccel = ::CreateAcceleratorTable( table, key_count_ ); if( hAccel_ != NULL ) ::DestroyAcceleratorTable( hAccel_ ); hAccel_ = hAccel; delete[] keys_; keys_ = table; } } void AcceleratorKey::DelKey( WORD id ) { // �܂��͑��݂��邩�`�F�b�N���� bool found = false; for( int i = 0; i < key_count_; i++ ) { if( keys_[i].cmd == id ) { found = true; break; } } if( found == false ) return; // ���݂����ꍇ��蒼�� ACCEL* table = new ACCEL[key_count_-1]; int dest = 0; for( int i = 0; i < key_count_; i++ ) { if( keys_[i].cmd != id ) { table[dest] = keys_[i]; dest++; } } key_count_--; HACCEL hAccel = ::CreateAcceleratorTable( table, key_count_ ); if( hAccel_ != NULL ) ::DestroyAcceleratorTable( hAccel_ ); hAccel_ = hAccel; delete[] keys_; keys_ = table; } int APIENTRY WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow ) { try { CheckMemoryLeaksStart(); // �E�H�b�`�� _crtBreakAlloc �ɃZ�b�g���� // XP ����Ŏg����API�𓮓I�ɓǂݍ���Ō݊�������� TVPInitCompatibleNativeFunctions(); // ���b�Z�[�W����������\�[�X����Ǎ��� TVPLoadMessage(); _argc = __argc; _argv = __argv; MouseCursor::Initialize(); Application = new tTVPApplication(); Application->StartApplication( __argc, __argv ); // delete application and exit forcely // this prevents ugly exception message on exit // �A�v���P�[�V�������폜�������I��������B // ����͏I�����̏X����O���b�Z�[�W��}�~���� delete Application; #ifndef _DEBUG // ::ExitProcess(TVPTerminateCode); // �����ŏI��������ƃ��������[�N�\�����s���Ȃ� #endif } catch (...) { return 2; } return TVPTerminateCode; } #endif tTVPApplication::tTVPApplication() : is_attach_console_(false), tarminate_(false), application_activating_(true) , image_load_thread_(NULL), has_map_report_process_(false) { } tTVPApplication::~tTVPApplication() { // while( windows_list_.size() ) { // std::vector::iterator i = windows_list_.begin(); // delete (*i); // // TTVPWindowForm �̃f�X�g���N�^���Ń��X�g����폜�����͂� // } // windows_list_.clear(); delete image_load_thread_; } #if 0 struct SEHException { unsigned int Code; _EXCEPTION_POINTERS* ExceptionPointers; SEHException( unsigned int code, _EXCEPTION_POINTERS* ep ) : Code(code), ExceptionPointers(ep) {} }; int TVPWriteHWEDumpFile( EXCEPTION_POINTERS* pExceptionPointers ) { BOOL bMiniDumpSuccessful; WCHAR szPath[MAX_PATH]; WCHAR szFileName[MAX_PATH]; const wchar_t* szAppName = TVPKirikiri; const wchar_t* szVersion = TVPGetVersionString().c_str(); TVPEnsureDataPathDirectory(); TJS_strcpy(szPath, TVPNativeDataPath.c_str()); SYSTEMTIME stLocalTime; ::GetLocalTime( &stLocalTime ); StringCchPrintf( szFileName, MAX_PATH, L"%s%s%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp", szPath, szAppName, szVersion, stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, GetCurrentProcessId(), GetCurrentThreadId()); HANDLE hDumpFile = ::CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0); MINIDUMP_EXCEPTION_INFORMATION ExpParam; ExpParam.ThreadId = ::GetCurrentThreadId(); ExpParam.ExceptionPointers = pExceptionPointers; ExpParam.ClientPointers = TRUE; bMiniDumpSuccessful = MiniDumpWriteDump( ::GetCurrentProcess(), ::GetCurrentProcessId(), hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL, NULL); return EXCEPTION_EXECUTE_HANDLER; } static bool TVPIsHandledHWException = false; void se_translator_function(unsigned int code, struct _EXCEPTION_POINTERS* ep) { if( !TVPIsHandledHWException ) { //ShowStackTrace( ep->ContextRecord ); TVPWriteHWEDumpFile( ep ); #ifdef TJS_64BIT_OS TVPHandleSEHException( code, ep->ExceptionRecord, ep->ContextRecord->Rsp, ep->ContextRecord ); #else TVPHandleSEHException( code, ep->ExceptionRecord, ep->ContextRecord->Esp, ep->ContextRecord ); #endif TVPIsHandledHWException = true; } throw SEHException(code,ep); } const wchar_t* SECodeToMessage( unsigned int code ) { switch(code){ case EXCEPTION_ACCESS_VIOLATION: return TVPExceptionAccessViolation; case EXCEPTION_BREAKPOINT: return TVPExceptionBreakpoint; case EXCEPTION_DATATYPE_MISALIGNMENT: return TVPExceptionDatatypeMisalignment; case EXCEPTION_SINGLE_STEP: return TVPExceptionSingleStep; case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return TVPExceptionArrayBoundsExceeded; case EXCEPTION_FLT_DENORMAL_OPERAND: return TVPExceptionFltDenormalOperand; case EXCEPTION_FLT_DIVIDE_BY_ZERO: return TVPExceptionFltDivideByZero; case EXCEPTION_FLT_INEXACT_RESULT: return TVPExceptionFltInexactResult; case EXCEPTION_FLT_INVALID_OPERATION: return TVPExceptionFltInvalidOperation; case EXCEPTION_FLT_OVERFLOW: return TVPExceptionFltOverflow; case EXCEPTION_FLT_STACK_CHECK: return TVPExceptionFltStackCheck; case EXCEPTION_FLT_UNDERFLOW: return TVPExceptionFltUnderflow; case EXCEPTION_INT_DIVIDE_BY_ZERO: return TVPExceptionIntDivideByZero; case EXCEPTION_INT_OVERFLOW: return TVPExceptionIntOverflow; case EXCEPTION_PRIV_INSTRUCTION: return TVPExceptionPrivInstruction; case EXCEPTION_NONCONTINUABLE_EXCEPTION: return TVPExceptionNoncontinuableException; case EXCEPTION_GUARD_PAGE: return TVPExceptionGuardPage; case EXCEPTION_ILLEGAL_INSTRUCTION: return TVPExceptionIllegalInstruction; case EXCEPTION_IN_PAGE_ERROR: return TVPExceptionInPageError; case EXCEPTION_INVALID_DISPOSITION: return TVPExceptionInvalidDisposition; case EXCEPTION_INVALID_HANDLE: return TVPExceptionInvalidHandle; case EXCEPTION_STACK_OVERFLOW: return TVPExceptionStackOverflow; case STATUS_UNWIND_CONSOLIDATE: return TVPExceptionUnwindCconsolidate; } return L"Unknown"; } #endif extern void TVPLoadPluigins(void); bool tTVPApplication::StartApplication(ttstr path) { // _set_se_translator(se_translator_function); ArgC = 0; ArgV = nullptr; #if 0 for( int i = 0; i < argc; i++ ) { if(!strcmp(argv[i], "-@processohmlog")) { has_map_report_process_ = true; } } #endif TVPTerminateCode = 0; LocaleConfigManager *mgr = LocaleConfigManager::GetInstance(); _retry = mgr->GetText("retry"); _cancel = mgr->GetText("cancel"); _msg = mgr->GetText("err_no_memory"); _title = mgr->GetText("err_occured"); TVPNativeProjectDir = path; CheckConsole(); // try starting the program! try { // if(TVPCheckProcessLog()) return true; // sub-process for processing object hash map log TVPProjectDir = TVPNormalizeStorageName(path); TVPInitScriptEngine(); TVPInitFontNames(); // banner TVPAddImportantLog( TVPFormatMessage(TVPProgramStartedOn, TVPGetOSName(), TVPGetPlatformName()) ); // TVPInitializeBaseSystems TVPInitializeBaseSystems(); Initialize(); if(TVPCheckPrintDataPath()) return true; if(TVPExecuteUserConfig()) return true; image_load_thread_ = new tTVPAsyncImageLoader(); TVPLoadPluigins(); // load plugin module *.tpm TVPSystemInit(); if(TVPCheckAbout()) return true; // version information dialog box; SetTitle(TVPKirikiri.operator const tjs_char *()); TVPSystemControl = new tTVPSystemControl(); // Check digitizer CheckDigitizer(); // start image load thread image_load_thread_->Resume(); /*if(TVPProjectDirSelected)*/ TVPInitializeStartupScript(); _project_startup = true; // Run(); #if 0 try { // image_load_thread_->ExitRequest(); delete image_load_thread_; image_load_thread_ = NULL; } catch(...) { // ignore errors } try { TVPSystemUninit(); } catch(...) { // ignore errors } #endif } catch( const EAbort & ) { // nothing to do #if !(defined(_MSC_VER) && defined(_DEBUG)) } catch (const Exception &exception) { TVPOnError(); if(!TVPSystemUninitCalled) ShowException(exception.what()); } catch( const TJS::eTJSScriptError &e ) { TVPOnError(); if (!TVPSystemUninitCalled) { ttstr msg; if (!title_.IsEmpty()) { msg += title_; msg += "\n"; } msg += e.GetMessage(); const tjs_char *pszBlockName = e.GetBlockName(); if (pszBlockName && *pszBlockName) { msg += TJS_W("\n@line("); tjs_char tmp[34]; msg += TJS_int_to_str(e.GetSourceLine(), tmp); msg += TJS_W(") "); msg += pszBlockName; } msg += TJS_W("\n"); msg += e.GetTrace(); ShowException(msg); } } catch( const TJS::eTJS &e) { TVPOnError(); if(!TVPSystemUninitCalled) ShowException( e.GetMessage() ); } catch( const std::exception &e ) { ShowException( e.what() ); } catch( const char* e ) { ShowException( e ); } catch( const tjs_char* e ) { ShowException( e ); #if 0 } catch( const SEHException& e ) { PEXCEPTION_RECORD rec = e.ExceptionPointers->ExceptionRecord; std::wstring text(SECodeToMessage(e.Code)); ttstr result = TJSGetStackTraceString( 10 ); PrintConsole( result.c_str(), result.length(), true ); TVPDumpHWException(); ShowException( text.c_str() ); #endif } catch(...) { ShowException( (const tjs_char*)TVPUnknownError ); #endif } return false; } /** * �R���\�[������̋N�����m�F���A�R���\�[������̋N���̏ꍇ�́A�W���o�͂����蓖�Ă� */ void tTVPApplication::CheckConsole() { #ifdef TVP_LOG_TO_COMMANDLINE_CONSOLE if( has_map_report_process_ ) return; // �����o���p�q�v���Z�X���ċN������Ă������̓R���\�[���ڑ����Ȃ� HANDLE hin = ::GetStdHandle(STD_INPUT_HANDLE); HANDLE hout = ::GetStdHandle(STD_OUTPUT_HANDLE); HANDLE herr = ::GetStdHandle(STD_ERROR_HANDLE); DWORD curProcId = ::GetCurrentProcessId(); DWORD processList[256]; DWORD count = ::GetConsoleProcessList( processList, 256 ); bool thisProcHasConsole = false; for( DWORD i = 0; i < count; i++ ) { if( processList[i] == curProcId ) { thisProcHasConsole = true; break; } } bool attachedConsole = true; if( thisProcHasConsole == false ) { attachedConsole = ::AttachConsole(ATTACH_PARENT_PROCESS) != 0; } if( (hin==0||hout==0||herr==0) && attachedConsole ) { wchar_t console[256]; ::GetConsoleTitle( console, 256 ); console_title_ = std::wstring( console ); // ���̃n���h�����Ċ��蓖�� if (hin) ::SetStdHandle(STD_INPUT_HANDLE, hin); if (hout) ::SetStdHandle(STD_OUTPUT_HANDLE, hout); if (herr) ::SetStdHandle(STD_ERROR_HANDLE, herr); } is_attach_console_ = attachedConsole; #endif } void tTVPApplication::CloseConsole() { #if 0 wchar_t buf[100]; DWORD len = TJS_snprintf(buf, 100, TVPExitCode, TVPTerminateCode); PrintConsole(buf, len); if( is_attach_console_ ) { ::SetConsoleTitle( console_title_.c_str() ); ::FreeConsole(); is_attach_console_ = false; } #endif } void TVPConsoleLog(const ttstr &mes, bool important); void tTVPApplication::PrintConsole(const ttstr &mes, bool important) { TVPConsoleLog(mes, important); } #if 0 HWND tTVPApplication::GetHandle() { if( windows_list_.size() > 0 ) { return windows_list_[0]->GetHandle(); } else { return INVALID_HANDLE_VALUE; } } void tTVPApplication::Minimize() { size_t size = windows_list_.size(); for( size_t i = 0; i < size; i++ ) { if( windows_list_[i]->GetVisible() ) { ::ShowWindow( windows_list_[i]->GetHandle(), SW_MINIMIZE ); } } } void tTVPApplication::Restore() { size_t size = windows_list_.size(); for( size_t i = 0; i < size; i++ ) { if( windows_list_[i]->GetVisible() ) { ::ShowWindow( windows_list_[i]->GetHandle(), SW_RESTORE ); } } } void tTVPApplication::BringToFront() { size_t size = windows_list_.size(); for( size_t i = 0; i < size; i++ ) { windows_list_[i]->BringToFront(); } } #endif void tTVPApplication::ShowException(const ttstr& e) { TVPShowSimpleMessageBox(e, TVPGetErrorDialogTitle()); TVPSystemUninit(); TVPExitApplication(0); } void tTVPApplication::Run() { try { if (TVPTerminated) { TVPSystemUninit(); TVPExitApplication(TVPTerminateCode); } // TVPBreathe(); ProcessMessages(); if (TVPSystemControl) TVPSystemControl->SystemWatchTimerTimer(); // TVPDeliverWindowUpdateEvents(); // from SystemWatchTimerTimer } catch (const EAbort &) { // nothing to do #if !(defined(_MSC_VER) && defined(_DEBUG)) } catch (const Exception &exception) { TVPOnError(); if(!TVPSystemUninitCalled) ShowException(exception.what()); } catch( const TJS::eTJSScriptError &e ) { TVPOnError(); if (!TVPSystemUninitCalled) { ttstr msg; if (!title_.IsEmpty()) { msg += title_; msg += "\n"; } msg += e.GetMessage(); const tjs_char *pszBlockName = e.GetBlockName(); if (pszBlockName && *pszBlockName) { msg += TJS_W("\n@line("); tjs_char tmp[34]; msg += TJS_int_to_str(e.GetSourceLine(), tmp); msg += TJS_W(") "); msg += pszBlockName; } msg += TJS_W("\n"); msg += e.GetTrace(); ShowException(msg); } } catch( const TJS::eTJS &e) { TVPOnError(); if(!TVPSystemUninitCalled) ShowException( e.GetMessage() ); } catch( const std::exception &e ) { ShowException( e.what() ); } catch( const char* e ) { ShowException( e ); } catch( const tjs_char* e ) { ShowException( e ); } catch (...) { ShowException((const tjs_char*)TVPUnknownError); #endif } } void tTVPApplication::ProcessMessages() { std::vector > lstUserMsg; { std::lock_guard cs(m_msgQueueLock); m_lstUserMsg.swap(lstUserMsg); } for (std::tuple& it : lstUserMsg) { std::get<2>(it)(); } TVPTimer::ProgressAllTimer(); } #if 0 bool tTVPApplication::ProcessMessage( MSG &msg ) { bool result = false; if( ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE) ) { BOOL msgExists = ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE); if( msgExists == 0 ) { return result; } result = true; if( msg.message != WM_QUIT ) { HACCEL hAccelTable = accel_key_.GetHandle(msg.hwnd); if( !TranslateAccelerator(msg.hwnd, hAccelTable, &msg) ) { TranslateMessage(&msg); DispatchMessage(&msg); } } else { TVPTerminateCode = (int)msg.wParam; tarminate_ = true; } } return result; } void tTVPApplication::ProcessMessages() { MSG msg = {0}; while(ProcessMessage(msg)); } void tTVPApplication::HandleMessage() { MSG msg = {0}; if( !ProcessMessage(msg) ) { HandleIdle(msg); } } void tTVPApplication::HandleIdle(MSG &) { bool done = true; if( TVPSystemControl ) { done = TVPSystemControl->ApplicationIdle(); } if( done ) ::WaitMessage(); } #endif void tTVPApplication::SetTitle(const ttstr& caption) { title_ = caption; #if 0 if( windows_list_.size() > 0 ) { windows_list_[0]->SetCaption( caption ); } if( is_attach_console_ ) { ::SetConsoleTitle( caption.c_str() ); } #endif } void tTVPApplication::Terminate() { //::PostQuitMessage(0); tarminate_ = true; TVPTerminated = true; } #if 0 HWND tTVPApplication::GetMainWindowHandle() const { if( windows_list_.size() > 0 ) { return windows_list_[0]->GetHandle(); } return INVALID_HANDLE_VALUE; } void tTVPApplication::RemoveWindow( TTVPWindowForm* win ) { std::vector::iterator it = std::remove( windows_list_.begin(), windows_list_.end(), win ); if( it != windows_list_.end() ) { windows_list_.erase( it, windows_list_.end() ); } } void tTVPApplication::PostMessageToMainWindow(UINT message, WPARAM wParam, LPARAM lParam) { if( windows_list_.size() > 0 ) { ::PostMessage( windows_list_[0]->GetHandle(), message, wParam, lParam ); } } void tTVPApplication::GetDisableWindowList( std::vector& win ) { size_t count = windows_list_.size(); for( size_t i = 0; i < count; i++ ) { if( windows_list_[i]->GetEnable() == false ) { win.push_back( windows_list_[i] ); } } } void tTVPApplication::GetEnableWindowList( std::vector& win, class TTVPWindowForm* activeWindow ) { size_t count = windows_list_.size(); for( size_t i = 0; i < count; i++ ) { if( activeWindow != windows_list_[i] && windows_list_[i]->GetEnable() ) { win.push_back( windows_list_[i] ); } } } void tTVPApplication::DisableWindows() { size_t count = windows_list_.size(); for( size_t i = 0; i < count; i++ ) { windows_list_[i]->SetEnable( false ); } } void tTVPApplication::EnableWindows( const std::vector& win ) { size_t count = win.size(); for( size_t i = 0; i < count; i++ ) { win[i]->SetEnable( true ); } /* size_t count = windows_list_.size(); for( size_t i = 0; i < count; i++ ) { TTVPWindowForm* win = windows_list_[i]; std::vector::const_iterator f = std::find( ignores.begin(), ignores.end(), win ); if( f == ignores.end() ) { windows_list_[i]->SetEnable( true ); } } */ } void tTVPApplication::FreeDirectInputDeviceForWindows() { size_t count = windows_list_.size(); for( size_t i = 0; i < count; i++ ) { windows_list_[i]->FreeDirectInputDevice(); } } void tTVPApplication::RegisterAcceleratorKey(HWND hWnd, char virt, short key, short cmd) { accel_key_.AddKey( hWnd, cmd, key, virt ); } void tTVPApplication::UnregisterAcceleratorKey(HWND hWnd, short cmd) { accel_key_.DelKey( hWnd, cmd ); } void tTVPApplication::DeleteAcceleratorKeyTable( HWND hWnd ) { accel_key_.DelTable( hWnd ); } #endif void tTVPApplication::CheckDigitizer() { // Windows 7 �ȍ~�ł̂ݗL�� #if 0 OSVERSIONINFOEX ovi; ovi.dwOSVersionInfoSize = sizeof(ovi); ::GetVersionEx((OSVERSIONINFO*)&ovi); if( ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion >= 6 && ovi.dwMinorVersion >= 1 ) { int value = ::GetSystemMetrics(SM_DIGITIZER); if( value == 0 ) return; TVPAddLog( (const tjs_char*)TVPEnableDigitizer ); if( value & NID_INTEGRATED_TOUCH ) { TVPAddLog( (const tjs_char*)TVPTouchIntegratedTouch ); } if( value & NID_EXTERNAL_TOUCH ) { TVPAddLog( (const tjs_char*)TVPTouchExternalTouch ); } if( value & NID_INTEGRATED_PEN ) { TVPAddLog( (const tjs_char*)TVPTouchIntegratedPen ); } if( value & NID_EXTERNAL_PEN ) { TVPAddLog( (const tjs_char*)TVPTouchExternalPen ); } if( value & NID_MULTI_INPUT ) { TVPAddLog( (const tjs_char*)TVPTouchMultiInput ); } if( value & NID_READY ) { TVPAddLog( (const tjs_char*)TVPTouchReady ); } } #endif } void tTVPApplication::PostUserMessage(const std::function &func, void* host, int msg) { std::lock_guard cs(m_msgQueueLock); m_lstUserMsg.emplace_back(host, msg, func); } void tTVPApplication::FilterUserMessage(const std::function > &)> &func) { std::lock_guard cs(m_msgQueueLock); func(m_lstUserMsg); } void tTVPApplication::OnActivate() { application_activating_ = true; if (!_project_startup) return; // TVPRestoreFullScreenWindowAtActivation(); TVPResetVolumeToAllSoundBuffer(); TVPUnlockSoundMixer(); // trigger System.onActivate event TVPPostApplicationActivateEvent(); for (auto & it : m_activeEvents) { it.second(it.first, eTVPActiveEvent::onActive); } } void tTVPApplication::OnDeactivate( ) { application_activating_ = false; if (!_project_startup) return; // TVPMinimizeFullScreenWindowAtInactivation(); // fire compact event TVPDeliverCompactEvent(TVP_COMPACT_LEVEL_DEACTIVATE); // set sound volume TVPResetVolumeToAllSoundBuffer(); TVPLockSoundMixer(); // trigger System.onDeactivate event TVPPostApplicationDeactivateEvent(); for (auto & it : m_activeEvents) { it.second(it.first, eTVPActiveEvent::onDeactive); } } void tTVPApplication::OnExit() { TVPUninitScriptEngine(); if (TVPSystemControl) delete TVPSystemControl; TVPSystemControl = NULL; CloseConsole(); } void tTVPApplication::OnLowMemory() { if (!_project_startup) return; TVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MAX); } bool tTVPApplication::GetNotMinimizing() const { return !application_activating_; #if 0 HWND hWnd = GetMainWindowHandle(); if( hWnd != INVALID_HANDLE_VALUE && hWnd != NULL ) { return ::IsIconic( hWnd ) == 0; } return true; // ���C�����Ȃ����͍ŏ�������Ă���Ƃ݂Ȃ� #endif } #if 0 void tTVPApplication::OnActiveAnyWindow() { if( modal_window_stack_.empty() != true ) { tTVPWindow* win = modal_window_stack_.top(); if( win->GetVisible() && win->GetEnable() ) { win->BringToFront(); } } } void tTVPApplication::ModalFinished() { modal_window_stack_.pop(); if( modal_window_stack_.empty() != true ) { tTVPWindow* win = modal_window_stack_.top(); if( win->GetVisible() && win->GetEnable() ) { win->BringToFront(); } } } #endif void tTVPApplication::LoadImageRequest( class iTJSDispatch2 *owner, class tTJSNI_Bitmap* bmp, const ttstr &name ) { if( image_load_thread_ ) { image_load_thread_->LoadRequest( owner, bmp, name ); } } void tTVPApplication::RegisterActiveEvent(void *host, const std::function& func/*empty = unregister*/) { if (func) m_activeEvents.emplace(host, func); else m_activeEvents.erase(host); } #if 0 std::vector* LoadLinesFromFile( const std::wstring& path ) { FILE *fp = NULL; _wfopen_s( &fp, path.c_str(), L"r"); if( fp == NULL ) { return NULL; } char buff[1024]; std::vector* ret = new std::vector(); while( fgets(buff, 1024, fp) != NULL ) { ret->push_back( std::string(buff) ); } fclose(fp); return ret; } void TVPRegisterAcceleratorKey(HWND hWnd, char virt, short key, short cmd) { if( Application ) Application->RegisterAcceleratorKey( hWnd, virt, key, cmd ); } void TVPUnregisterAcceleratorKey(HWND hWnd, short cmd) { if( Application ) Application->UnregisterAcceleratorKey( hWnd, cmd ); } void TVPDeleteAcceleratorKeyTable( HWND hWnd ) { if( Application ) Application->DeleteAcceleratorKeyTable( hWnd ); } #endif void TVPInitWindowOptions() { ; } std::string ExtractFileDir(const std::string & FileName) { return av_dirname((char*)FileName.c_str()); } unsigned long ColorToRGB(unsigned int col) { // 0xBBGGRR switch (col) { case clScrollBar: return 0xc8c8c8; case clBackground: return 0; case clActiveCaption: return 0xd1b499; case clInactiveCaption: return 0xdbcdbf; case clMenu: return 0xf0f0f0; case clWindow: return 0xffffff; case clWindowFrame: return 0x646464; case clMenuText: return 0; case clWindowText: return 0; case clCaptionText: return 0; case clActiveBorder: return 0xb4b4b4; case clInactiveBorder: return 0xfcf7f4; case clAppWorkSpace: return 0xababab; case clHighlight: return 0xff9933; case clHighlightText: return 0xffffff; case clBtnFace: return 0xf0f0f0; case clBtnShadow: return 0xa0a0a0; case clGrayText: return 0x6d6d6d; case clBtnText: return 0; case clInactiveCaptionText: return 0x544e43; case clBtnHighlight: return 0xffffff; case cl3DDkShadow: return 0x696969; case cl3DLight: return 0xe3e3e3; case clInfoText: return 0; case clInfoBk: return 0xe1ffff; case clUnknown: return 0; case clHotLight: return 0xcc6600; case clGradientActiveCaption: return 0xead1b9; case clGradientInactiveCaption: return 0xf2e4d7; case clMenuLight: return 0xff9933; case clMenuBar: return 0xf0f0f0; default: return col & 0xFFFFFF; } } ================================================ FILE: src/core/environ/Application.h ================================================ #ifndef __T_APPLICATION_H__ #define __T_APPLICATION_H__ #include "tjsVariant.h" #include "tjsString.h" #include #include #include #include #include ttstr ExePath(); // ʂ̂悢@ɕύXǂ extern int _argc; extern char ** _argv; enum { mrOk, mrAbort, mrCancel, }; enum { mtWarning = /*MB_ICONWARNING*/0x00000030L, mtError = /*MB_ICONERROR*/0x00000010L, mtInformation = /*MB_ICONINFORMATION*/0x00000040L, mtConfirmation = /*MB_ICONQUESTION*/0x00000020L, mtStop = /*MB_ICONSTOP*/0x00000010L, mtCustom = 0 }; enum { mbOK = /*MB_OK*/0x00000000L, }; enum class eTVPActiveEvent { onActive, onDeactive, }; #if 0 class AcceleratorKey { HACCEL hAccel_; ACCEL* keys_; int key_count_; public: AcceleratorKey(); ~AcceleratorKey(); void AddKey( WORD id, WORD key, BYTE virt ); void DelKey( WORD id ); HACCEL GetHandle() { return hAccel_; } }; class AcceleratorKeyTable { std::map keys_; HACCEL hAccel_; public: AcceleratorKeyTable(); ~AcceleratorKeyTable(); void AddKey( HWND hWnd, WORD id, WORD key, BYTE virt ); void DelKey( HWND hWnd, WORD id ); void DelTable( HWND hWnd ); HACCEL GetHandle(HWND hWnd) { std::map::iterator i = keys_.find(hWnd); if( i != keys_.end() ) { return i->second->GetHandle(); } return hAccel_; } }; #endif class tTVPApplication { // std::vector windows_list_; ttstr title_; bool is_attach_console_; ttstr console_title_; // AcceleratorKeyTable accel_key_; bool tarminate_; bool application_activating_; bool has_map_report_process_; class tTVPAsyncImageLoader* image_load_thread_; #if 0 std::stack modal_window_stack_; #endif private: void CheckConsole(); void CloseConsole(); void CheckDigitizer(); void ShowException( const ttstr& e ); void Initialize() {} public: tTVPApplication(); ~tTVPApplication(); bool StartApplication(ttstr path); void Run(); void ProcessMessages(); static void PrintConsole(const ttstr &mes, bool important = false); bool IsAttachConsole() { return is_attach_console_; } bool IsTarminate() const { return tarminate_; } // HWND GetHandle(); bool IsIconic() { #if 0 HWND hWnd = GetHandle(); if( hWnd != INVALID_HANDLE_VALUE ) { return 0 != ::IsIconic(hWnd); } #endif return true; // EBhEȂ } #if 0 void Minimize(); void Restore(); void BringToFront(); void AddWindow( class TTVPWindowForm* win ) { windows_list_.push_back( win ); } void RemoveWindow( class TTVPWindowForm* win ); unsigned int GetWindowCount() const { return (unsigned int)windows_list_.size(); } void FreeDirectInputDeviceForWindows(); bool ProcessMessage( MSG &msg ); void ProcessMessages(); void HandleMessage(); void HandleIdle(MSG &msg); #endif const ttstr &GetTitle() const { return title_; } void SetTitle( const ttstr& caption ); #if 0 static inline int MessageDlg( const ttstr& string, const ttstr& caption, int type, int button ) { return ::MessageBox( NULL, string.c_str(), caption.c_str(), type|button ); } #endif void Terminate(); void SetHintHidePause( int v ) {} void SetShowHint( bool b ) {} void SetShowMainForm( bool b ) {} // HWND GetMainWindowHandle() const; int ArgC; char ** ArgV; typedef std::function tMsg; // void PostMessageToMainWindow(UINT message, WPARAM wParam, LPARAM lParam); void PostUserMessage(const std::function &func, void* param1 = nullptr, int param2 = 0); void FilterUserMessage(const std::function > &)> &func); #if 0 void ModalStarted( class tTVPWindow* form ) { modal_window_stack_.push(form); } void ModalFinished(); void OnActiveAnyWindow(); void DisableWindows(); void EnableWindows( const std::vector& win ); void GetDisableWindowList( std::vector& win ); void GetEnableWindowList( std::vector& win, class TTVPWindowForm* activeWindow ); void RegisterAcceleratorKey(HWND hWnd, char virt, short key, short cmd); void UnregisterAcceleratorKey(HWND hWnd, short cmd); void DeleteAcceleratorKeyTable( HWND hWnd ); #endif void OnActivate( ); void OnDeactivate( ); void OnExit(); void OnLowMemory(); bool GetActivating() const { return application_activating_; } bool GetNotMinimizing() const; /** * 摜̔񓯊Ǎݗv */ void LoadImageRequest( class iTJSDispatch2 *owner, class tTJSNI_Bitmap* bmp, const ttstr &name ); tTVPAsyncImageLoader* GetAsyncImageLoader() { return image_load_thread_; } void RegisterActiveEvent(void *host, const std::function& func/*empty = unregister*/); private: std::mutex m_msgQueueLock; std::vector > m_lstUserMsg; std::map > m_activeEvents; }; std::vector* LoadLinesFromFile( const ttstr& path ); //inline HINSTANCE GetHInstance() { return ((HINSTANCE)GetModuleHandle(0)); } extern class tTVPApplication* Application; #endif // __T_APPLICATION_H__ ================================================ FILE: src/core/environ/ConfigManager/GlobalConfigManager.cpp ================================================ #include "GlobalConfigManager.h" #include "tinyxml2/tinyxml2.h" #include "platform/CCFileUtils.h" #include "Platform.h" #include "UtilStreams.h" #include "LocaleConfigManager.h" bool TVPWriteDataToFile(const ttstr &filepath, const void *data, unsigned int len); class XMLMemPrinter : public tinyxml2::XMLPrinter { tTVPMemoryStream _stream; char _buffer[4096]; public: virtual void Print(const char* format, ...) { va_list param; va_start(param, format); int n = vsnprintf(_buffer, 4096, format, param); va_end(param); _stream.Write(_buffer, n); } void SaveFile(const std::string &path) { if (!TVPWriteDataToFile(path, _stream.GetInternalBuffer(), _stream.GetSize())) { TVPShowSimpleMessageBox( LocaleConfigManager::GetInstance()->GetText("cannot_create_preference"), LocaleConfigManager::GetInstance()->GetText("readonly_storage")); } } }; GlobalConfigManager::GlobalConfigManager() { Initialize(); } GlobalConfigManager* GlobalConfigManager::GetInstance() { static GlobalConfigManager instance; return &instance; } void iSysConfigManager::Initialize() { AllConfig.clear(); ConfigUpdated = false; tinyxml2::XMLDocument doc; FILE *fp = nullptr; #ifdef _MSC_VER fp = _wfopen(ttstr(GetFilePath()).c_str(), TJS_W("rb")); #else fp = fopen(GetFilePath().c_str(), "rb"); #endif if (fp && !doc.LoadFile(fp)) { tinyxml2::XMLElement *rootElement = doc.RootElement(); if (rootElement) { for (tinyxml2::XMLElement *item = rootElement->FirstChildElement("Item"); item; item = item->NextSiblingElement("Item")) { const char *key = item->Attribute("key"); const char *val = item->Attribute("value"); if (key && val) { AllConfig[key] = val; } } for (tinyxml2::XMLElement *item = rootElement->FirstChildElement("Custom"); item; item = item->NextSiblingElement("Custom")) { const char *key = item->Attribute("key"); const char *val = item->Attribute("value"); if (key && val) { CustomArguments.emplace_back(key, val); } } for (tinyxml2::XMLElement *item = rootElement->FirstChildElement("KeyMap"); item; item = item->NextSiblingElement("KeyMap")) { int key, val; if (tinyxml2::XML_SUCCESS == item->QueryIntAttribute("key", &key) && tinyxml2::XML_SUCCESS == item->QueryIntAttribute("value", &val) && key && val) { KeyMap.emplace(key, val); } } } } if (fp) fclose(fp); } void iSysConfigManager::SaveToFile() { if (!ConfigUpdated) return; std::string filepath = GetFilePath(); if (filepath.empty()) return; tinyxml2::XMLDocument doc; doc.LinkEndChild(doc.NewDeclaration()); tinyxml2::XMLElement *rootElement = doc.NewElement("GlobalPreference"); for (auto it = AllConfig.begin(); it != AllConfig.end(); ++it) { tinyxml2::XMLElement *item = doc.NewElement("Item"); item->SetAttribute("key", it->first.c_str()); item->SetAttribute("value", it->second.c_str()); rootElement->LinkEndChild(item); } for (auto it = CustomArguments.begin(); it != CustomArguments.end(); ++it) { tinyxml2::XMLElement *item = doc.NewElement("Custom"); item->SetAttribute("key", it->first.c_str()); item->SetAttribute("value", it->second.c_str()); rootElement->LinkEndChild(item); } for (auto &it : KeyMap) { if (it.first && it.second) { tinyxml2::XMLElement *item = doc.NewElement("KeyMap"); item->SetAttribute("key", it.first); item->SetAttribute("value", it.second); rootElement->LinkEndChild(item); } } doc.LinkEndChild(rootElement); XMLMemPrinter stream; doc.Print(&stream); stream.SaveFile(GetFilePath()); ConfigUpdated = false; } bool iSysConfigManager::IsValueExist(const std::string &name) { auto it = AllConfig.find(name); return it != AllConfig.end(); } std::string GlobalConfigManager::GetFilePath() { return TVPGetInternalPreferencePath() + "GlobalPreference.xml"; } template<> bool iSysConfigManager::GetValue(const std::string &name, const bool& defVal) { return !!GetValue(name, defVal); } template<> int iSysConfigManager::GetValue(const std::string &name, const int& defVal) { auto it = AllConfig.find(name); if (it == AllConfig.end()) { SetValueInt(name, defVal); return defVal; } return atoi(it->second.c_str()); } template<> float iSysConfigManager::GetValue(const std::string &name, const float& defVal) { auto it = AllConfig.find(name); if (it == AllConfig.end()) { SetValueFloat(name, defVal); return defVal; } return atof(it->second.c_str()); } template<> std::string iSysConfigManager::GetValue(const std::string &name, const std::string& defVal) { auto it = AllConfig.find(name); if (it == AllConfig.end()) { SetValue(name, defVal); return defVal; } return it->second; } void iSysConfigManager::SetValueInt(const std::string &name, int val) { char buf[16]; sprintf(buf, "%d", val); AllConfig[name] = buf; ConfigUpdated = true; } void iSysConfigManager::SetValueFloat(const std::string &name, float val) { char buf[24]; sprintf(buf, "%g", val); AllConfig[name] = buf; ConfigUpdated = true; } void iSysConfigManager::SetValue(const std::string &name, const std::string & val) { AllConfig[name] = val; ConfigUpdated = true; } void iSysConfigManager::SetKeyMap(int k/* 0 means remove */, int v) { if (v == 0) { KeyMap.erase(k); } else { KeyMap[k] = v; } } std::vector iSysConfigManager::GetCustomArgumentsForPush() { std::vector ret; for (auto arg : CustomArguments) { std::string line("-"); line += arg.first; line += "="; line += arg.second; ret.emplace_back(line); } return ret; } ================================================ FILE: src/core/environ/ConfigManager/GlobalConfigManager.h ================================================ #pragma once #include #include #include #include class iSysConfigManager { protected: std::unordered_map AllConfig; std::vector > CustomArguments; std::map KeyMap; bool ConfigUpdated; virtual std::string GetFilePath() = 0; void Initialize(); public: void SaveToFile(); bool IsValueExist(const std::string &name); template T GetValue(const std::string &name, const T& defVal); void SetValueInt(const std::string &name, int val); void SetValueFloat(const std::string &name, float val); void SetValue(const std::string &name, const std::string & val); std::vector > &GetCustomArgumentsForModify() { ConfigUpdated = true; return CustomArguments; } const std::map& GetKeyMap() { return KeyMap; } void SetKeyMap(int k, int v/* 0 means remove */); const std::vector > &GetCustomArguments() const { return CustomArguments; } std::vector GetCustomArgumentsForPush(); }; template<> bool iSysConfigManager::GetValue(const std::string &name, const bool& defVal); template<> int iSysConfigManager::GetValue(const std::string &name, const int& defVal); template<> float iSysConfigManager::GetValue(const std::string &name, const float& defVal); template<> std::string iSysConfigManager::GetValue(const std::string &name, const std::string& defVal); class GlobalConfigManager : public iSysConfigManager { virtual std::string GetFilePath() override; GlobalConfigManager(); public: static GlobalConfigManager* GetInstance(); }; ================================================ FILE: src/core/environ/ConfigManager/IndividualConfigManager.cpp ================================================ #include "IndividualConfigManager.h" #include "platform/CCFileUtils.h" #include "LocaleConfigManager.h" #include "Platform.h" #define FILENAME "Kirikiroid2Preference.xml" IndividualConfigManager* IndividualConfigManager::GetInstance() { static IndividualConfigManager instance; return &instance; } std::string IndividualConfigManager::GetFilePath() { return CurrentPath; } void IndividualConfigManager::Clear() { AllConfig.clear(); CustomArguments.clear(); ConfigUpdated = false; CurrentPath.clear(); } bool IndividualConfigManager::CheckExistAt(const std::string &folder) { std::string fullpath = folder + "/" FILENAME; return cocos2d::FileUtils::getInstance()->isFileExist(fullpath); } bool IndividualConfigManager::CreatePreferenceAt(const std::string &folder) { std::string fullpath = folder + "/" FILENAME; // FILE *fp = // #ifdef _MSC_VER // _wfopen(ttstr(fullpath).c_str(), TJS_W("w")); // #else // fopen(fullpath.c_str(), "w"); // #endif Clear(); // if (!fp) { // TVPShowSimpleMessageBox( // LocaleConfigManager::GetInstance()->GetText("cannot_create_preference"), // LocaleConfigManager::GetInstance()->GetText("readonly_storage")); // return false; // } CurrentPath = fullpath; return true; } bool IndividualConfigManager::UsePreferenceAt(const std::string &folder) { std::string fullpath = folder + "/" FILENAME; if (CurrentPath == fullpath) return true; Clear(); if (!cocos2d::FileUtils::getInstance()->isFileExist(fullpath)) return false; CurrentPath = fullpath; Initialize(); return true; } template<> bool IndividualConfigManager::GetValue(const std::string &name, const bool &defVal /*= false*/) { return inherit::GetValue(name, GlobalConfigManager::GetInstance()->GetValue(name, defVal)); } template<> int IndividualConfigManager::GetValue(const std::string &name, const int &defVal /*= 0*/) { return inherit::GetValue(name, GlobalConfigManager::GetInstance()->GetValue(name, defVal)); } template<> float IndividualConfigManager::GetValue(const std::string &name, const float &defVal /*= 0*/) { return inherit::GetValue(name, GlobalConfigManager::GetInstance()->GetValue(name, defVal)); } template<> std::string IndividualConfigManager::GetValue(const std::string &name, const std::string &defVal /*= ""*/) { return inherit::GetValue(name, GlobalConfigManager::GetInstance()->GetValue(name, defVal)); } std::vector IndividualConfigManager::GetCustomArgumentsForPush() { if (CustomArguments.empty()) { return GlobalConfigManager::GetInstance()->GetCustomArgumentsForPush(); } return inherit::GetCustomArgumentsForPush(); } ================================================ FILE: src/core/environ/ConfigManager/IndividualConfigManager.h ================================================ #pragma once #include #include #include #include "GlobalConfigManager.h" class IndividualConfigManager : public iSysConfigManager { typedef iSysConfigManager inherit; virtual std::string GetFilePath() override; void Clear(); std::string CurrentPath; public: static IndividualConfigManager* GetInstance(); static bool CheckExistAt(const std::string &folder); bool CreatePreferenceAt(const std::string &folder); bool UsePreferenceAt(const std::string &folder); template T GetValue(const std::string &name, const T& defVal); std::vector GetCustomArgumentsForPush(); }; template<> bool IndividualConfigManager::GetValue(const std::string &name, const bool& defVal); template<> int IndividualConfigManager::GetValue(const std::string &name, const int& defVal); template<> float IndividualConfigManager::GetValue(const std::string &name, const float& defVal); template<> std::string IndividualConfigManager::GetValue(const std::string &name, const std::string& defVal); ================================================ FILE: src/core/environ/ConfigManager/LocaleConfigManager.cpp ================================================ #include "LocaleConfigManager.h" #include "platform/CCFileUtils.h" #include "GlobalConfigManager.h" #include "tinyxml2/tinyxml2.h" #include "ui/UIText.h" #include "ui/UIButton.h" LocaleConfigManager::LocaleConfigManager() { } std::string LocaleConfigManager::GetFilePath() { std::string pathprefix = "locale/"; // constant file in app package std::string fullpath = pathprefix + currentLangCode + ".xml"; // exp. "local/en_us.xml" if (!cocos2d::FileUtils::getInstance()->isFileExist(fullpath)) { currentLangCode = "en_us"; // restore to default language config(must exist) return GetFilePath(); } return cocos2d::FileUtils::getInstance()->fullPathForFilename(fullpath); } LocaleConfigManager* LocaleConfigManager::GetInstance() { static LocaleConfigManager instance; return &instance; } const std::string &LocaleConfigManager::GetText(const std::string &tid) { auto it = AllConfig.find(tid); if (it == AllConfig.end()) { AllConfig[tid] = tid; return AllConfig[tid]; } return it->second; } void LocaleConfigManager::Initialize(const std::string &sysLang) { // override by global configured lang currentLangCode = GlobalConfigManager::GetInstance()->GetValue("user_language", ""); if (currentLangCode.empty()) currentLangCode = sysLang; AllConfig.clear(); tinyxml2::XMLDocument doc; std::string xmlData = cocos2d::FileUtils::getInstance()->getStringFromFile(GetFilePath()); bool _writeBOM = false; const char* p = xmlData.c_str(); p = tinyxml2::XMLUtil::ReadBOM(p, &_writeBOM); doc.ParseDeep((char*)p, nullptr); tinyxml2::XMLElement *rootElement = doc.RootElement(); if (rootElement) { for (tinyxml2::XMLElement *item = rootElement->FirstChildElement(); item; item = item->NextSiblingElement()) { const char *key = item->Attribute("id"); const char *val = item->Attribute("text"); if (key && val) { AllConfig[key] = val; } } } } bool LocaleConfigManager::initText(cocos2d::ui::Text *ctrl) { if (!ctrl) return false; return initText(ctrl, ctrl->getString()); } bool LocaleConfigManager::initText(cocos2d::ui::Button *ctrl) { if (!ctrl) return false; return initText(ctrl, ctrl->getTitleText()); } bool LocaleConfigManager::initText(cocos2d::ui::Text *ctrl, const std::string &tid) { if (!ctrl) return false; std::string txt = GetText(tid); if (txt.empty()) { ctrl->setString(tid); ctrl->setColor(cocos2d::Color3B::RED); return false; } ctrl->setString(txt); return true; } bool LocaleConfigManager::initText(cocos2d::ui::Button *ctrl, const std::string &tid) { if (!ctrl) return false; std::string txt = GetText(tid); if (txt.empty()) { ctrl->setTitleText(tid); ctrl->setTitleColor(cocos2d::Color3B::RED); return false; } ctrl->setTitleText(txt); return true; } ================================================ FILE: src/core/environ/ConfigManager/LocaleConfigManager.h ================================================ // multi language config mainly for ui #pragma once #include #include #include namespace cocos2d { namespace ui { class Text; class Button; } } class LocaleConfigManager { std::unordered_map AllConfig; // tid->text in utf8 bool ConfigUpdated; LocaleConfigManager(); std::string GetFilePath(); public: static LocaleConfigManager* GetInstance(); void Initialize(const std::string &sysLang); const std::string &GetText(const std::string &tid); // in utf8 bool initText(cocos2d::ui::Text *ctrl); bool initText(cocos2d::ui::Button *ctrl); bool initText(cocos2d::ui::Text *ctrl, const std::string &tid); bool initText(cocos2d::ui::Button *ctrl, const std::string &tid); private: std::string currentLangCode; }; ================================================ FILE: src/core/environ/DetectCPU.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000-2007 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // CPU idetification / features detection routine //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include "cpu_types.h" #include "DebugIntf.h" #include "SysInitIntf.h" #include "ThreadIntf.h" #include "Exception.h" /* Note: CPU clock measuring routine is in EmergencyExit.cpp, reusing hot-key watching thread. */ //--------------------------------------------------------------------------- extern "C" { tjs_uint32 TVPCPUType = 0; // CPU type tjs_uint32 TVPCPUFeatures = 0; } static bool TVPCPUChecked = false; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetCPUTypeForOne //--------------------------------------------------------------------------- static void TVPGetCPUTypeForOne() { try { TVPCPUFeatures = 0; //TVPCheckCPU(); // in detect_cpu.nas } catch(.../*EXCEPTION_EXECUTE_HANDLER*/) { // exception had been ocured throw Exception("CPU check failure."); } // check OSFXSR // if(TVPCPUFeatures & TVP_CPU_HAS_SSE) // { // __try // { // __emit__(0x0f, 0x57, 0xc0); // xorps xmm0, xmm0 (SSE) // } // __except(EXCEPTION_EXECUTE_HANDLER) // { // // exception had been ocured // // execution of 'xorps' is failed (XMM registers not available) // TVPCPUFeatures &=~ TVP_CPU_HAS_SSE; // TVPCPUFeatures &=~ TVP_CPU_HAS_SSE2; // } // } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- static ttstr TVPDumpCPUFeatures(tjs_uint32 features) { ttstr ret; // #define TVP_DUMP_CPU(x, n) { ret += TJS_W(" ") TJS_W(n); \ // if(features & x) ret += TJS_W(":yes"); else ret += TJS_W(":no"); } // // TVP_DUMP_CPU(TVP_CPU_HAS_FPU, "FPU"); // TVP_DUMP_CPU(TVP_CPU_HAS_MMX, "MMX"); // TVP_DUMP_CPU(TVP_CPU_HAS_3DN, "3DN"); // TVP_DUMP_CPU(TVP_CPU_HAS_SSE, "SSE"); // TVP_DUMP_CPU(TVP_CPU_HAS_CMOV, "CMOVcc"); // TVP_DUMP_CPU(TVP_CPU_HAS_E3DN, "E3DN"); // TVP_DUMP_CPU(TVP_CPU_HAS_EMMX, "EMMX"); // TVP_DUMP_CPU(TVP_CPU_HAS_SSE2, "SSE2"); // TVP_DUMP_CPU(TVP_CPU_HAS_TSC, "TSC"); return ret; } //--------------------------------------------------------------------------- static ttstr TVPDumpCPUInfo(tjs_int cpu_num) { // dump detected cpu type ttstr features(TJS_W("(info) CPU #") + ttstr(cpu_num) + TJS_W(" : ")); features += TVPDumpCPUFeatures(TVPCPUFeatures); tjs_uint32 vendor = TVPCPUFeatures & TVP_CPU_VENDOR_MASK; // #undef TVP_DUMP_CPU // #define TVP_DUMP_CPU(x, n) { \ // if(vendor == x) features += TJS_W(" ") TJS_W(n); } // // TVP_DUMP_CPU(TVP_CPU_IS_INTEL, "Intel"); // TVP_DUMP_CPU(TVP_CPU_IS_AMD, "AMD"); // TVP_DUMP_CPU(TVP_CPU_IS_IDT, "IDT"); // TVP_DUMP_CPU(TVP_CPU_IS_CYRIX, "Cyrix"); // TVP_DUMP_CPU(TVP_CPU_IS_NEXGEN, "NexGen"); // TVP_DUMP_CPU(TVP_CPU_IS_RISE, "Rise"); // TVP_DUMP_CPU(TVP_CPU_IS_UMC, "UMC"); // TVP_DUMP_CPU(TVP_CPU_IS_TRANSMETA, "Transmeta"); // // TVP_DUMP_CPU(TVP_CPU_IS_UNKNOWN, "Unknown"); // // #undef TVP_DUMP_CPU // features += TJS_W("(") + ttstr((const tjs_nchar *)TVPCPUVendor) + TJS_W(")"); // if(TVPCPUName[0]!=0) // features += TJS_W(" [") + ttstr((const tjs_nchar *)TVPCPUName) + TJS_W("]"); // features += TJS_W(" CPUID(1)/EAX=") + TJSInt32ToHex(TVPCPUID1_EAX); // features += TJS_W(" CPUID(1)/EBX=") + TJSInt32ToHex(TVPCPUID1_EBX); TVPAddImportantLog(features); // if(((TVPCPUID1_EAX >> 8) & 0x0f) <= 4) // throw Exception("CPU check failure: CPU family 4 or lesser is not supported\r\n"+ // features.AsAnsiString()); return features; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPDetectCPU //--------------------------------------------------------------------------- static void TVPDisableCPU(tjs_uint32 featurebit, const tjs_char *name) { #if 0 tTJSVariant val; ttstr str; if(TVPGetCommandLine(name, &val)) { str = val; if(str == TJS_W("no")) TVPCPUType &=~ featurebit; else if(str == TJS_W("force")) TVPCPUType |= featurebit; } #endif } #if defined(WIN32) || defined(__ANDROID__) #include #endif //--------------------------------------------------------------------------- void TVPDetectCPU() { if(TVPCPUChecked) return; TVPCPUChecked = true; //if(SDL_HasSSE2()) TVPCPUFeatures |= TVP_CPU_HAS_SSE2 | TVP_CPU_HAS_EMMX; //if(SDL_HasSSE()) TVPCPUFeatures |= TVP_CPU_HAS_SSE; //if(SDL_HasMMX()) TVPCPUFeatures |= TVP_CPU_HAS_MMX; //if(SDL_HasSSE2()) TVPCPUFeatures |= TVP_CPU_HAS_SSE2; #if defined(__ANDROID__) || defined(WIN32) //if (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM) { TVPCPUFeatures |= TVP_CPU_FAMILY_ARM; // must be arm #if defined(__arm64__) || defined(__aarch64__) || defined(__LP64__) TVPCPUFeatures |= TVP_CPU_HAS_NEON; // aka. asimd #else if((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0) { TVPCPUFeatures |= TVP_CPU_HAS_NEON; } #endif //} #endif #ifdef __APPLE__ // must be iOS TVPCPUFeatures |= TVP_CPU_FAMILY_ARM | TVP_CPU_HAS_NEON; #endif tjs_uint32 features = 0; features = (TVPCPUFeatures & TVP_CPU_FEATURE_MASK); TVPCPUType &= ~ TVP_CPU_FEATURE_MASK; TVPCPUType |= features; // // get process affinity mask // DWORD pam = 1; // HANDLE hp = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId()); // if(hp) // { // DWORD sam = 1; // GetProcessAffinityMask(hp, &pam, &sam); // CloseHandle(hp); // } // // // for each CPU... // ttstr cpuinfo; // bool first = true; // for(tjs_int cpu = 0; cpu < 32; cpu++) // { // if(pam & (1<WaitEnd(); // bool succeeded = thread->GetSucceeded(); // delete thread; // if(!succeeded) throw Exception("CPU check failure"); // cpuinfo += TVPDumpCPUInfo(cpu) + TJS_W("\r\n"); // // // mask features // if(first) // { // features = (TVPCPUFeatures & TVP_CPU_FEATURE_MASK); // TVPCPUType = TVPCPUFeatures; // first = false; // } // else // { // features &= (TVPCPUFeatures & TVP_CPU_FEATURE_MASK); // } // } // } // Disable or enable cpu features by option // TVPDisableCPU(TVP_CPU_HAS_MMX, TJS_W("-cpummx")); // TVPDisableCPU(TVP_CPU_HAS_3DN, TJS_W("-cpu3dn")); // TVPDisableCPU(TVP_CPU_HAS_SSE, TJS_W("-cpusse")); // TVPDisableCPU(TVP_CPU_HAS_CMOV, TJS_W("-cpucmov")); // TVPDisableCPU(TVP_CPU_HAS_E3DN, TJS_W("-cpue3dn")); // TVPDisableCPU(TVP_CPU_HAS_EMMX, TJS_W("-cpuemmx")); // TVPDisableCPU(TVP_CPU_HAS_SSE2, TJS_W("-cpusse2")); TVPDisableCPU(TVP_CPU_HAS_NEON, TJS_W("-cpuneon")); // if(TVPCPUType == 0) // throw Exception("CPU check failure: Not supported CPU\r\n" + // cpuinfo.AsAnsiString()); // // TVPAddImportantLog(TJS_W("(info) finally detected CPU features : ") + // TVPDumpCPUFeatures(TVPCPUType)); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // jpeg and png loader support functions //--------------------------------------------------------------------------- unsigned long MMXReady = 0; extern "C" { void CheckMMX(void) { TVPDetectCPU(); MMXReady = TVPCPUType & TVP_CPU_HAS_MMX; } } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // TVPGetCPUType //--------------------------------------------------------------------------- tjs_uint32 TVPGetCPUType() { TVPDetectCPU(); return TVPCPUType; } //--------------------------------------------------------------------------- ================================================ FILE: src/core/environ/DetectCPU.h ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000-2007 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // CPU idetification / features detection routine //--------------------------------------------------------------------------- #ifndef DetectCPUH #define DetectCPUH //--------------------------------------------------------------------------- extern "C" { extern tjs_uint32 TVPCPUType; } extern void TVPDetectCPU(); TJS_EXP_FUNC_DEF(tjs_uint32, TVPGetCPUType, ()); //--------------------------------------------------------------------------- #endif ================================================ FILE: src/core/environ/DumpSend.cpp ================================================ #include "network/HttpRequest.h" #include "network/HttpClient.h" #include "base/CCDirector.h" #include "base/CCScheduler.h" #include "base/base64.h" #include "Platform.h" #include "SysInitIntf.h" #include "ConfigManager/LocaleConfigManager.h" #include "StorageImpl.h" #include "minizip/ioapi.h" #include "minizip/zip.h" #include #include #include static void ClearDumps(const std::string &dumpdir, std::vector &allDumps) { for (const std::string &path : allDumps) { remove((dumpdir + "/" + path).c_str()); } //allDumps.clear(); } static std::map _inmemFiles; struct zlib_inmem_func64 : public zlib_filefunc64_def { static voidpf ZCALLBACK fopen64_file_func(voidpf opaque, const void* filename, int mode) { tTVPMemoryStream *str = new tTVPMemoryStream; _inmemFiles[(const char*)filename] = str; return str; } static uLong ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uLong size) { tTVPMemoryStream* str = (tTVPMemoryStream*)stream; return str->Read(buf, size); } static uLong ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void* buf, uLong size) { tTVPMemoryStream* str = (tTVPMemoryStream*)stream; return str->Write(buf, size); } static ZPOS64_T ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream) { tTVPMemoryStream* str = (tTVPMemoryStream*)stream; return str->GetPosition(); } static long ZCALLBACK fseek64_file_func(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) { int fseek_origin = TJS_BS_SEEK_SET; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR: fseek_origin = TJS_BS_SEEK_CUR; break; case ZLIB_FILEFUNC_SEEK_END: fseek_origin = TJS_BS_SEEK_END; break; case ZLIB_FILEFUNC_SEEK_SET: fseek_origin = TJS_BS_SEEK_SET; break; default: return -1; } tTVPMemoryStream* str = (tTVPMemoryStream*)stream; str->Seek(offset, fseek_origin); return 0; } static int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream) { return 0; } static int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream) { return 0; } zlib_inmem_func64() { zopen64_file = fopen64_file_func; zread_file = fread_file_func; zwrite_file = fwrite_file_func; ztell64_file = ftell64_file_func; zseek64_file = fseek64_file_func; zclose_file = fclose_file_func; zerror_file = ferror_file_func; opaque = NULL; } }; static zlib_filefunc64_def* GetZlibIOFunc() { static zlib_inmem_func64 func; return &func; } static std::string url_encode(const std::string &value) { std::ostringstream escaped; escaped.fill('0'); escaped << std::hex; for (std::string::value_type c : value) { // Keep alphanumeric and other accepted characters intact if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { escaped << c; continue; } // Any other characters are percent-encoded escaped << '%' << std::setw(2) << int((unsigned char)c); } return escaped.str(); } #define FLAG_UTF8 (1<<11) static void SendDumps(std::string dumpdir, std::vector allDumps, std::string packageName, std::string versionStr) { std::mutex _mutex; std::condition_variable _cond; for (const std::string &filename : allDumps) { std::string fullpath = dumpdir + "/" + filename; do { struct tTVP_stat stat_buf; if (!TVP_stat(fullpath.c_str(), stat_buf)) { break; } FILE *fp = fopen(fullpath.c_str(), "rb"); if (!fp) { break; } std::vector buf; buf.resize(stat_buf.st_size); fseek(fp, 0, SEEK_SET); fread(&buf[0], 1, stat_buf.st_size, fp); fclose(fp); zip_fileinfo zi; memset(&zi, 0, sizeof zi); time_t _t = stat_buf.st_mtime; struct tm *time = localtime(&_t); zi.tmz_date.tm_year = time->tm_year; zi.tmz_date.tm_mon = time->tm_mon; zi.tmz_date.tm_mday = time->tm_mday; zi.tmz_date.tm_hour = time->tm_hour; zi.tmz_date.tm_min = time->tm_min; zi.tmz_date.tm_sec = time->tm_sec; // CRCӋ unsigned long crcFile = 0; crcFile = crc32(crcFile, (const Bytef *)&buf[0], buf.size()); // ե׷ // UTF8Ǹ{ zipFile zf = zipOpen2_64((const void*)filename.c_str(), 0, NULL, GetZlibIOFunc()); if (zf == NULL) { break; } if (zipOpenNewFileInZip4(zf, filename.c_str(), &zi, NULL, 0, NULL, 0, NULL /* comment*/, Z_DEFLATED, 9, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, crcFile, 0, FLAG_UTF8) != ZIP_OK) { zipClose(zf, NULL); break; } zipWriteInFileInZip(zf, (const Bytef *)&buf[0], buf.size()); zipCloseFileInZip(zf); zipClose(zf, NULL); cocos2d::network::HttpRequest* pRequest = new cocos2d::network::HttpRequest(); std::string strUrl = #ifdef _DEBUG "http://127.0.0.1:7777/upload_dump.php" #else "http://avgfun.net/upload_dump.php" #endif ; pRequest->setUrl(strUrl.c_str()); pRequest->setRequestType(cocos2d::network::HttpRequest::Type::POST); std::ostringstream postData; postData << "appid=" << url_encode(packageName); postData << "&version=" << url_encode(versionStr); postData << "&time=" << _t; tTVPMemoryStream *bs = _inmemFiles.begin()->second; char *base64str; cocos2d::base64Encode((const unsigned char *)bs->GetInternalBuffer(), bs->GetSize(), &base64str); postData << "&data=" << url_encode(base64str); free(base64str); std::string postStr = postData.str(); pRequest->setRequestData(postStr.c_str(), postStr.length()); pRequest->setResponseCallback([&](cocos2d::network::HttpClient* client, cocos2d::network::HttpResponse* response){ _cond.notify_one(); }); pRequest->setTag("POST"); std::unique_lock lk(_mutex); cocos2d::network::HttpClient::getInstance()->send(pRequest); _cond.wait(lk); pRequest->release(); } while (false); remove(fullpath.c_str()); for (auto it : _inmemFiles) { delete it.second; } _inmemFiles.clear(); } //allDumps.clear(); } void TVPCheckAndSendDumps(const std::string &dumpdir, const std::string &packageName, const std::string &versionStr) { std::vector allDumps; TVPListDir(dumpdir, [&](const std::string &name, int mask) { if (mask & (S_IFREG | S_IFDIR)) { if (name.size() <= 4) return; if (name.substr(name.size() - 4) != ".dmp") return; allDumps.emplace_back(name); } }); if (!allDumps.empty()) { std::string title = LocaleConfigManager::GetInstance()->GetText("crash_report"); std::string msgfmt = LocaleConfigManager::GetInstance()->GetText("crash_report_msg"); char buf[256]; sprintf(buf, msgfmt.c_str(), allDumps.size()); if (TVPShowSimpleMessageBoxYesNo(buf, title) == 0) { static std::thread dumpthread; dumpthread = std::thread(std::bind(SendDumps, dumpdir, allDumps, packageName, versionStr)); } else { ClearDumps(dumpdir, allDumps); } } } ================================================ FILE: src/core/environ/Platform.h ================================================ #pragma once #include "tjsCommHead.h" #include #include struct TVPMemoryInfo { // all in kB unsigned long MemTotal; unsigned long MemFree; unsigned long SwapTotal; unsigned long SwapFree; unsigned long VirtualTotal; unsigned long VirtualUsed; }; void TVPGetMemoryInfo(TVPMemoryInfo &m); tjs_int TVPGetSystemFreeMemory(); // in MB tjs_int TVPGetSelfUsedMemory(); // in MB extern "C" int TVPShowSimpleMessageBox(const char * text, const char * caption, unsigned int nButton, const char **btnText); // C-style int TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption, const std::vector &vecButtons); int TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption); int TVPShowSimpleMessageBoxYesNo(const ttstr & text, const ttstr & caption); int TVPShowSimpleInputBox(ttstr &text, const ttstr &caption, const ttstr &prompt, const std::vector &vecButtons); std::vector TVPGetDriverPath(); std::vector TVPGetAppStoragePath(); bool TVPCheckStartupPath(const std::string &path); std::string TVPGetPackageVersionString(); void TVPExitApplication(int code); void TVPCheckMemory(); const std::string &TVPGetInternalPreferencePath(); bool TVPDeleteFile(const std::string &filename); bool TVPRenameFile(const std::string &from, const std::string &to); bool TVPCopyFile(const std::string &from, const std::string &to); void TVPShowIME(int x, int y, int w, int h); void TVPHideIME(); void TVPRelinquishCPU(); void TVPPrintLog(const char *str); void TVPFetchSDCardPermission(); // for android only struct tTVP_stat { uint16_t st_mode; uint64_t st_size; uint64_t st_atime; uint64_t st_mtime; uint64_t st_ctime; }; bool TVP_stat(const tjs_char *name, tTVP_stat &s); bool TVP_stat(const char *name, tTVP_stat &s); void TVP_utime(const char *name, time_t modtime); void TVPSendToOtherApp(const std::string &filename); std::string TVPGetCurrentLanguage(); ================================================ FILE: src/core/environ/XP3ArchiveRepack.cpp ================================================ #include "XP3ArchiveRepack.h" #include #include "p7zip/CPP/7zip/Archive/7z/7zOut.h" #include "p7zip/CPP/7zip/Common/StreamObjects.h" extern "C" { #include "p7zip/C/7zCrc.h" } #include "TextStream.h" #include "StorageImpl.h" #include "XP3Archive.h" #include #include #include #include #include #include "win32io.h" #include "GraphicsLoaderIntf.h" #include "ogl/etcpak.h" #include #include "LayerIntf.h" #include "MsgIntf.h" #include "ncbind/ncbind.hpp" #include "visual/tvpgl_asm_init.h" #include "DetectCPU.h" #include using namespace TJS; using namespace NArchive::N7z; #define COMPRESS_THRESHOLD 4 * 1024 * 1024 #define S_INTERRUPT ((HRESULT)0x114705) void TVPSetXP3FilterScript(ttstr content); void TVPSavePVRv3(void* formatdata, tTJSBinaryStream* dst, const iTVPBaseBitmap* image, const ttstr & mode, iTJSDispatch2* meta); class tTVPXP3ArchiveEx : public tTVPXP3Archive { public: tTVPXP3ArchiveEx(const ttstr & name, tTJSBinaryStream *st) : tTVPXP3Archive(name, 0) { Init(st, -1, false); } uint64_t TotalSize = 0; }; class OutStreamFor7z : public IOutStream { long fp; unsigned int RefCount = 1; public: OutStreamFor7z(const std::string &path) { fp = open(path.c_str(), O_RDWR | O_CREAT, 0666); } ~OutStreamFor7z() { close(fp); } ULONG AddRef() { return ++RefCount; } ULONG Release() { if (RefCount == 1) { delete this; return 0; } return --RefCount; } HRESULT QueryInterface(REFIID iid, void **ppOut) { if (!memcmp(&iid, &IID_IOutStream, sizeof(IID_IOutStream))) { *ppOut = (IOutStream*)this; return S_OK; } *ppOut = nullptr; return E_NOTIMPL; } HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize) { *processedSize = write(fp, data, size); return S_OK; } HRESULT Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) override { int64_t pos = lseek64(fp, offset, seekOrigin); if (newPosition) *newPosition = pos; return S_OK; } HRESULT SetSize(UInt64 newSize) { return S_OK; } }; class OutStreamMemory : public IOutStream, public tTVPMemoryStream { unsigned int RefCount = 1; public: ULONG AddRef() { return ++RefCount; } ULONG Release() { if (RefCount == 1) { delete this; return 0; } return --RefCount; } HRESULT QueryInterface(REFIID iid, void **ppOut) { if (!memcmp(&iid, &IID_IOutStream, sizeof(IID_IOutStream))) { *ppOut = (IOutStream*)this; return S_OK; } *ppOut = nullptr; return E_NOTIMPL; } HRESULT Write(const void *data, UInt32 size, UInt32 *processedSize) override { *processedSize = tTVPMemoryStream::Write(data, size); return S_OK; } HRESULT Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) override { *newPosition = tTVPMemoryStream::Seek(offset, seekOrigin); return S_OK; } HRESULT SetSize(UInt64 newSize) { tTVPMemoryStream::SetSize(newSize); return S_OK; } }; class SequentialInStreamFor7z : public ISequentialInStream { tTJSBinaryStream *fp; unsigned int RefCount = 1; public: SequentialInStreamFor7z(tTJSBinaryStream *s) { fp = s; } ~SequentialInStreamFor7z() { fp = nullptr; } ULONG AddRef() { return ++RefCount; } ULONG Release() { if (RefCount == 1) { delete this; return 0; } return --RefCount; } HRESULT QueryInterface(REFIID iid, void **ppOut) { if (!memcmp(&iid, &IID_IInStream, sizeof(IID_IInStream))) { *ppOut = (ISequentialInStream*)this; return S_OK; } *ppOut = nullptr; return E_NOTIMPL; } HRESULT Read(void *data, UInt32 size, UInt32 *processedSize) { *processedSize = fp->Read(data, size); return S_OK; } }; class XP3ArchiveRepackAsyncImpl : ICompressProgressInfo { public: XP3ArchiveRepackAsyncImpl(); ~XP3ArchiveRepackAsyncImpl(); void Clear(); void Start(); void Stop() { bStopRequired = true; } void DoConv(); uint64_t AddTask(const std::string &src); void SetXP3Filter(const std::string &xp3filter); void SetCallback( const std::function &onNewFile, const std::function &onNewArchive, const std::function &onProgress, const std::function &onError, const std::function &onEnded) { OnNewFile = onNewFile; OnNewArchive = onNewArchive; OnProgress = onProgress; OnError = onError; OnEnded = onEnded; } void SetOption(const std::string &name, bool v); public: bool OptionUsingETC2 = false; bool OptionMergeMaskImg = true; private: HRESULT AddTo7zArchive(tTJSBinaryStream* s, const ttstr &_naem); // ICompressProgressInfo virtual HRESULT SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) override; // IUnknown virtual HRESULT QueryInterface(REFIID riid, void **ppvObject) override { return E_NOTIMPL; } virtual ULONG AddRef(void) override { return 0; } virtual ULONG Release(void) override { return 0; } std::vector > ConvFileList; std::thread* Thread = nullptr; CCreatedCoder CoderCompress, CoderCopy; static const int nCodecMethod = 0x30101, // LZMA nCodecMethodCopy = 0; CArchiveDatabaseOut newDatabase; OutStreamFor7z *strout; CByteBuffer props; bool bStopRequired = false; uint64_t nTotalSize = 0, nArcSize = 0; std::function OnNewFile; std::function OnNewArchive; std::function OnProgress; std::function OnError; std::function OnEnded; }; XP3ArchiveRepackAsync::XP3ArchiveRepackAsync() : _impl(new XP3ArchiveRepackAsyncImpl()) { TVPDetectCPU(); TVPGL_ASM_Init(); } XP3ArchiveRepackAsync::~XP3ArchiveRepackAsync() { delete _impl; } uint64_t XP3ArchiveRepackAsync::AddTask(const std::string &src) { return _impl->AddTask(src); } void XP3ArchiveRepackAsync::Start() { _impl->Start(); } void XP3ArchiveRepackAsync::Stop() { _impl->Stop(); } void XP3ArchiveRepackAsync::SetXP3Filter(const std::string &xp3filter) { _impl->SetXP3Filter(xp3filter); } void XP3ArchiveRepackAsync::SetCallback( const std::function &onNewFile, const std::function &onNewArchive, const std::function &onProgress, const std::function &onError, const std::function &onEnded) { _impl->SetCallback(onNewFile, onNewArchive, onProgress, onError, onEnded); } void XP3ArchiveRepackAsync::SetOption(const std::string &name, bool v) { _impl->SetOption(name, v); } XP3ArchiveRepackAsyncImpl::XP3ArchiveRepackAsyncImpl() { if (!g_CrcTable[1]) CrcGenerateTable(); CreateCoder(nCodecMethod, true, CoderCompress); CreateCoder(nCodecMethodCopy, true, CoderCopy); CMyComPtr writeCoderProperties; CMyComPtr setCoderProperties; CoderCompress.Coder->QueryInterface(IID_ICompressWriteCoderProperties, (void **)&writeCoderProperties); CoderCompress.Coder->QueryInterface(IID_ICompressSetCoderProperties, (void **)&setCoderProperties); if (setCoderProperties) { const int nProp = 1; PROPVARIANT propvars[nProp]; PROPID props[nProp] = { NCoderPropID::kDictionarySize, }; propvars[0].vt = VT_UI4; propvars[0].ulVal = 4 * 1024 * 1024; setCoderProperties->SetCoderProperties(props, propvars, nProp); } if (writeCoderProperties) { CDynBufSeqOutStream *outStreamSpec = new CDynBufSeqOutStream; CMyComPtr dynOutStream(outStreamSpec); outStreamSpec->Init(); writeCoderProperties->WriteCoderProperties(dynOutStream); outStreamSpec->CopyToBuffer(props); } } XP3ArchiveRepackAsyncImpl::~XP3ArchiveRepackAsyncImpl() { std::thread* t = Thread; if (t && t->joinable()) { t->join(); delete t; } Clear(); } uint64_t XP3ArchiveRepackAsyncImpl::AddTask(const std::string &src/*, const std::string &dst*/) { ttstr path(src); tTVPLocalFileStream *str = new tTVPLocalFileStream(path, path, TJS_BS_READ); tTVPXP3ArchiveEx *xp3arc = new tTVPXP3ArchiveEx(path, str); for (const tTVPXP3Archive::tArchiveItem &item : xp3arc->ItemVector) { xp3arc->TotalSize += item.OrgSize; } ConvFileList.emplace_back(xp3arc, src); return xp3arc->TotalSize; } void XP3ArchiveRepackAsyncImpl::SetXP3Filter(const std::string &xp3filter) { ttstr xp3filterScript; iTJSTextReadStream * stream = TVPCreateTextStreamForRead(xp3filter, ""); stream->Read(xp3filterScript, 0); delete stream; TVPSetXP3FilterScript(xp3filterScript); } void XP3ArchiveRepackAsyncImpl::SetOption(const std::string &name, bool v) { if (name == "merge_mask_img") { OptionMergeMaskImg = v; } else if (name == "conv_etc2") { OptionUsingETC2 = v; } } void XP3ArchiveRepackAsyncImpl::Clear() { for (auto & it : ConvFileList) { if (it.first) delete it.first; } ConvFileList.clear(); TVPSetXP3FilterScript(TJS_W("")); } void XP3ArchiveRepackAsyncImpl::Start() { if (!Thread) { Thread = new std::thread(std::bind(&XP3ArchiveRepackAsyncImpl::DoConv, this)); } } static bool CheckIsImage(tTJSBinaryStream *s) { // convert image > 8k tjs_uint8 header[16]; tjs_uint readed = s->Read(header, 16); s->SetPosition(0); if (readed != 16) return false; if (!memcmp(header, "BM", 2)) { return true; } else if (!memcmp(header, "\x89PNG", 4)) { return true; } else if (!memcmp(header, "\xFF\xD8\xFF", 3)) { // JPEG return true; } else if (!memcmp(header, "TLG", 3)) { return true; } else if (!memcmp(header, "\x49\x49\xbc\x01", 4)) { // JXR return true; } else if (!memcmp(header, "BPG", 3)) { return true; } else if (!memcmp(header, "RIFF", 4)) { if (!memcmp(header + 8, "WEBPVP8", 7)) { return true; } } return false; } HRESULT XP3ArchiveRepackAsyncImpl::AddTo7zArchive(tTJSBinaryStream* s, const ttstr &_name) { CFileItem file; CFileItem2 file2; SequentialInStreamFor7z str(s); tjs_uint64 origSize = s->GetSize(); file.Size = origSize; file2.Init(); UString name(_name.c_str()); UInt64 inSizeForReduce = origSize; UInt64 newSize = origSize; bool compressable = origSize > 64 && origSize < 4 * 1024 * 1024; if (compressable) { // compressable quick check tjs_uint8 header[16]; s->Read(header, 16); if (!memcmp(header, "\x89PNG", 4)) { compressable = false; } else if (!memcmp(header, "OggS\x00", 5)) { compressable = false; } else if (!memcmp(header, "\xFF\xD8\xFF", 3)) { // JPEG compressable = false; } else if (!memcmp(header, "TLG", 3)) { compressable = false; } else if (!memcmp(header, "0&\xB2\x75\x8E\x66\xCF\x11", 8)) { // wmv/wma compressable = false; } else if (!memcmp(header, "AJPM", 4)) { // AMV compressable = false; } else if (!memcmp(header, "\x49\x49\xbc\x01", 4)) { // JXR compressable = false; } else if (!memcmp(header, "BPG", 3)) { compressable = false; } else if (!memcmp(header, "RIFF", 4)) { if (!memcmp(header + 8, "WEBPVP8", 7)) { compressable = false; } } s->SetPosition(0); } HRESULT ret; if (compressable) { UInt64 expectedSize = origSize * 4 / 5; OutStreamMemory tmp; if ((ret = CoderCompress.Coder->Code(&str, &tmp, &inSizeForReduce, &newSize, this)) != S_OK) return ret; if (tmp.GetSize() < expectedSize) { UInt32 writed; if ((ret = strout->Write(tmp.GetInternalBuffer(), tmp.GetSize(), &writed)) != S_OK) { return ret; } if (writed != tmp.GetSize()) return E_FAIL; newDatabase.PackSizes.Add(tmp.GetSize()); newDatabase.CoderUnpackSizes.Add(origSize); newDatabase.NumUnpackStreamsVector.Add(1); CFolder &folder = newDatabase.Folders.AddNew(); folder.Bonds.SetSize(0); folder.Coders.SetSize(1); CCoderInfo &cod = folder.Coders[0]; cod.MethodID = nCodecMethod; cod.NumStreams = 1; cod.Props = props; folder.PackStreams.SetSize(1); folder.PackStreams[0] = 0; // only 1 stream newDatabase.AddFile(file, file2, name); return S_OK; } s->SetPosition(0); } // direct copy newSize = origSize; if ((ret = CoderCopy.Coder->Code(&str, strout, &inSizeForReduce, &newSize, this)) != S_OK) { return ret; } newDatabase.PackSizes.Add(s->GetSize()); newDatabase.CoderUnpackSizes.Add(origSize); newDatabase.NumUnpackStreamsVector.Add(1); CFolder &folder = newDatabase.Folders.AddNew(); folder.Bonds.SetSize(0); folder.Coders.SetSize(1); CCoderInfo &cod = folder.Coders[0]; cod.MethodID = nCodecMethodCopy; cod.NumStreams = 1; folder.PackStreams.SetSize(1); folder.PackStreams[0] = 0; // only 1 stream newDatabase.AddFile(file, file2, name); return S_OK; } HRESULT XP3ArchiveRepackAsyncImpl::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) { if (OnProgress) { OnProgress(nTotalSize + *inSize, nArcSize + *inSize, *inSize); } return bStopRequired ? S_INTERRUPT : S_OK; } void XP3ArchiveRepackAsyncImpl::DoConv() { nTotalSize = 0; for (unsigned int arcidx = 0; arcidx < ConvFileList.size(); ++arcidx) { auto &it = ConvFileList[arcidx]; if (bStopRequired) break; if (OnNewArchive) OnNewArchive(arcidx, it.first->TotalSize, it.second); tTVPXP3ArchiveEx *xp3arc = it.first; tjs_uint totalFile = xp3arc->GetCount(); std::string tmpname = it.second + ".7z"; strout = new OutStreamFor7z(tmpname); COutArchive archive; if (archive.Create(strout, false) != S_OK) { if (OnError) OnError(-1, "Fail to create output archive."); break; } archive.SkipPrefixArchiveHeader(); newDatabase.Clear(); nArcSize = 0; // filter image files , img_mask = -1 means no mask available or normal file std::map imglist; std::vector filelist; // normal files { std::unordered_multimap allFileName; std::vector allfilelist; std::set masklist; for (tjs_uint idx = 0; idx < xp3arc->ItemVector.size(); ++idx) { const tTVPXP3Archive::tArchiveItem &item = xp3arc->ItemVector[idx]; if (!item.OrgSize) { // add empty files first CFileItem file; CFileItem2 file2; file2.Init(); UString name(item.Name.c_str()); file.Size = item.OrgSize; file.HasStream = false; newDatabase.AddFile(file, file2, name); continue; } if (item.Name.length() > 256 && item.Name.StartsWith(TJS_W("$$$"))) continue; ttstr name = TVPChopStorageExt(item.Name); allFileName.emplace(name, &item); allfilelist.emplace_back(idx); } if(OptionMergeMaskImg) for (tjs_uint idx : allfilelist) { const tTVPXP3Archive::tArchiveItem &item = xp3arc->ItemVector[idx]; ttstr name = TVPChopStorageExt(item.Name); tjs_int pos = name.length() - 2; if (pos > 0 && name.SubString(pos, 2) == TJS_W("_m")) { ttstr prefix = name.SubString(0, pos); int count = 0; auto itpair = allFileName.equal_range(prefix); for (auto it = itpair.first; it != itpair.second; ++it) { ++count; } if (count == 1) { // assume that one mask associate to one image const tTVPXP3Archive::tArchiveItem* imgItem = itpair.first->second; allFileName.erase(itpair.first); allFileName.erase(name); imglist.emplace(imgItem - &xp3arc->ItemVector.front(), idx); masklist.emplace(idx); continue; } } } for (tjs_uint idx : allfilelist) { if (imglist.find(idx) != imglist.end() || masklist.find(idx) != masklist.end()) continue; filelist.push_back(idx); } } // merge image with mask // actual TVPLoadGraphicRouter static tTVPGraphicHandlerType *handler = TVPGetGraphicLoadHandler(TJS_W(".png")); for (const auto &it : imglist) { if (bStopRequired) break; const tTVPXP3Archive::tArchiveItem &imgItem = xp3arc->ItemVector[it.first]; const tTVPXP3Archive::tArchiveItem &maskItem = xp3arc->ItemVector[it.second]; std::auto_ptr strImg(xp3arc->CreateStreamByIndex(&imgItem - &xp3arc->ItemVector.front())); std::auto_ptr strMask(xp3arc->CreateStreamByIndex(&maskItem - &xp3arc->ItemVector.front())); bool isImage = CheckIsImage(strImg.get()) && CheckIsImage(strMask.get()); if (isImage) { // skip 8-bit image iTJSDispatch2 *dic = nullptr; handler->Header(strImg.get(), &dic); strImg->SetPosition(0); if (dic) { tTJSVariant val; dic->PropGet(0, TJS_W("bpp"), 0, &val, dic); dic->Release(); int bpp = val.AsInteger(); isImage = bpp == 24 || bpp == 32; } else { isImage = false; // unknown error, skip } } if (!isImage) { filelist.push_back(it.first); filelist.push_back(it.second); continue; } struct BmpInfoWithMask { tTVPBitmap* bmp = nullptr; tTVPBitmap* bmpForMask = nullptr; std::unordered_map metainfo; ~BmpInfoWithMask() { if (bmp) delete bmp; if (bmpForMask) delete bmpForMask; } } data; if (OnNewFile) OnNewFile(it.first, imgItem.OrgSize, imgItem.Name.AsStdString()); // main part handler->Load(handler->FormatData, &data, [](void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt)->int{ BmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata; if (!data->bmp) { data->bmp = new tTVPBitmap(w, h, 32); } return data->bmp->GetPitch(); }, [](void *callbackdata, tjs_int y)->void* { BmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata; if (y >= 0) { return data->bmp->GetScanLine(y); } return nullptr; }, [](void *callbackdata, const ttstr & name, const ttstr & value) { BmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata; data->metainfo.emplace(name, value); }, strImg.get(), TVP_clNone, glmNormal); // mask part handler->Load(handler->FormatData, &data, [](void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt)->int { BmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata; if (data->bmp->GetWidth() != w || data->bmp->GetHeight() != h) TVPThrowExceptionMessage(TVPMaskSizeMismatch); if (!data->bmpForMask) { data->bmpForMask = new tTVPBitmap(w, h, 8); } return data->bmpForMask->GetPitch(); }, [](void *callbackdata, tjs_int y)->void* { BmpInfoWithMask * data = (BmpInfoWithMask *)callbackdata; if (y >= 0) { return data->bmpForMask->GetScanLine(y); } return nullptr; }, [](void *callbackdata, const ttstr & name, const ttstr & value) { // no metainfo for mask }, strMask.get(), TVP_clNone, glmGrayscale); for (tjs_uint y = 0; y < data.bmp->GetHeight(); ++y) { TVPBindMaskToMain((tjs_uint32*)data.bmp->GetScanLine(y), (tjs_uint8*)data.bmpForMask->GetScanLine(y), data.bmp->GetWidth()); } delete data.bmpForMask; data.bmpForMask = nullptr; ncbDictionaryAccessor meta; for (const auto &it : data.metainfo) { meta.SetValue(it.first.c_str(), it.second); } tTVPMemoryStream memstr; tTVPBaseBitmap *bmp = new tTVPBaseBitmap(data.bmp->GetWidth(), data.bmp->GetHeight()); bmp->AssignBitmap(data.bmp); if (OptionUsingETC2) { TVPSavePVRv3(nullptr, &memstr, bmp, TJS_W("ETC2_RGBA"), meta.GetDispatch()); } else { // convert to tlg5 for better performance TVPSaveAsTLG(nullptr, &memstr, bmp, TJS_W("tlg5"), meta.GetDispatch()); } delete bmp; memstr.SetPosition(0); HRESULT ret = AddTo7zArchive(&memstr, imgItem.Name); if (OnProgress) { uint64_t size = imgItem.OrgSize + maskItem.OrgSize; nArcSize += size; nTotalSize += size; OnProgress(nTotalSize, nArcSize, size); } if (ret != S_OK) { if (ret != S_INTERRUPT && OnError) { OnError(ret, "Write to file fail."); } bStopRequired = true; break; } } for (tjs_uint idx : filelist) { const tTVPXP3Archive::tArchiveItem& item = xp3arc->ItemVector[idx]; if (bStopRequired) break; std::auto_ptr s(xp3arc->CreateStreamByIndex(idx)); if (OnNewFile) OnNewFile(&item - &xp3arc->ItemVector.front(), item.OrgSize, item.Name.AsStdString()); if (OptionUsingETC2 && item.OrgSize > 8192) { // convert image > 8k bool isImage = CheckIsImage(s.get()); int width = 0, height = 0; struct BmpInfo { tTVPBitmap* bmp = nullptr; std::unordered_map metainfo; tTVPGraphicPixelFormat fmt = gpfLuminance; ~BmpInfo() { if (bmp) delete bmp; } } data; if (isImage) { // main part handler->Load(handler->FormatData, &data, [](void *callbackdata, tjs_uint w, tjs_uint h, tTVPGraphicPixelFormat fmt)->int { BmpInfo * data = (BmpInfo *)callbackdata; if (!data->bmp) { data->bmp = new tTVPBitmap(w, h, 32); data->fmt = fmt; } return data->bmp->GetPitch(); }, [](void *callbackdata, tjs_int y)->void* { BmpInfo * data = (BmpInfo *)callbackdata; if (y >= 0) { return data->bmp->GetScanLine(y); } return nullptr; }, [](void *callbackdata, const ttstr & name, const ttstr & value) { BmpInfo * data = (BmpInfo *)callbackdata; data->metainfo.emplace(name, value); }, s.get(), TVP_clNone, glmNormal); // skip 8-bit image if (data.fmt != gpfRGB || data.fmt != gpfRGBA) { isImage = false; } } if (isImage) { tTVPBaseBitmap *bmp = new tTVPBaseBitmap(data.bmp->GetWidth(), data.bmp->GetHeight()); bmp->AssignBitmap(data.bmp); s.reset(new tTVPMemoryStream); ncbDictionaryAccessor meta; for (const auto &it : data.metainfo) { meta.SetValue(it.first.c_str(), it.second); } TVPSavePVRv3(nullptr, s.get(), bmp, data.fmt == gpfRGB ? TJS_W("ETC2_RGB") : TJS_W("ETC2_RGBA"), meta.GetDispatch()); delete bmp; s->SetPosition(0); } } HRESULT ret = AddTo7zArchive(s.get(), item.Name); nArcSize += item.OrgSize; nTotalSize += item.OrgSize; if (ret != S_OK) { if (ret != S_INTERRUPT && OnError) { OnError(ret, "Write to file fail."); } bStopRequired = true; break; } } if (bStopRequired) break; CCompressionMethodMode mode; CHeaderOptions hdropt; hdropt.CompressMainHeader = true; archive.WriteDatabase(newDatabase, &mode, hdropt); archive.Close(); strout = nullptr; delete xp3arc; it.first = nullptr; remove(it.second.c_str()); rename(tmpname.c_str(), it.second.c_str()); } Clear(); if (OnEnded) OnEnded(); } ================================================ FILE: src/core/environ/XP3ArchiveRepack.h ================================================ #pragma once #include #include #include class XP3ArchiveRepackAsyncImpl; class XP3ArchiveRepackAsync { public: XP3ArchiveRepackAsync(); ~XP3ArchiveRepackAsync(); uint64_t AddTask(const std::string &src); void Start(); void Stop(); void SetXP3Filter(const std::string &xp3filter); void SetCallback( const std::function &onNewFile, const std::function &onNewArchive, const std::function &onProgress, const std::function &onError, const std::function &onEnded); void SetOption(const std::string &name, bool v); private: XP3ArchiveRepackAsyncImpl *_impl; }; ================================================ FILE: src/core/environ/android/AndroidUtils.cpp ================================================ #include "AndroidUtils.h" #include "minizip/unzip.h" #include "zlib.h" #include #include #include #include "tjs.h" #include "MsgIntf.h" #include "md5.h" #include "DebugIntf.h" #include #include #include "platform/android/jni/JniHelper.h" #include #include #include "SysInitIntf.h" #include "platform/CCFileUtils.h" #include "ConfigManager/LocaleConfigManager.h" #include "Platform.h" #include "platform/CCCommon.h" #include #include #include "base/CCDirector.h" #include "base/CCScheduler.h" #include #include #include #include "TickCount.h" #include "StorageImpl.h" #include "ConfigManager/IndividualConfigManager.h" #include "EventIntf.h" #include "RenderManager.h" #include #include "deprecated/CCString.h" USING_NS_CC; #define KR2ActJavaPath "org/tvp/kirikiri2/KR2Activity" //#define KR2EntryJavaPath "org/tvp/kirikiri2/Kirikiroid2" extern unsigned int __page_size = getpagesize(); void TVPPrintLog(const char *str) { __android_log_print(ANDROID_LOG_INFO, "kr2 debug info", "%s", str); } static tjs_uint32 _lastMemoryInfoQuery = 0; static tjs_int _availMemory, _usedMemory; static void _updateMemoryInfo() { if (TVPGetRoughTickCount32() - _lastMemoryInfoQuery > 3000) { // freq in 3s JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, "updateMemoryInfo", "()V")) { methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); } if (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, "getAvailMemory", "()J")) { _availMemory = methodInfo.env->CallStaticLongMethod(methodInfo.classID, methodInfo.methodID) / (1024 * 1024); methodInfo.env->DeleteLocalRef(methodInfo.classID); } if (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, "getUsedMemory", "()J")) { // in kB _usedMemory = methodInfo.env->CallStaticLongMethod(methodInfo.classID, methodInfo.methodID) / 1024; methodInfo.env->DeleteLocalRef(methodInfo.classID); } _lastMemoryInfoQuery = TVPGetRoughTickCount32(); } } tjs_int TVPGetSystemFreeMemory() { _updateMemoryInfo(); return _availMemory; } tjs_int TVPGetSelfUsedMemory() { _updateMemoryInfo(); return _usedMemory; } void TVPForceSwapBuffer() { eglSwapBuffers(eglGetCurrentDisplay(), eglGetCurrentSurface(EGL_DRAW)); } std::string TVPGetDeviceID() { std::string ret; // use pure jni to avoid java code // jclass classID = pEnv->FindClass(KR2EntryJavaPath); // std::string strtmp("()L"); strtmp += KR2EntryJavaPath; strtmp += ";"; // jmethodID methodGetInstance = pEnv->GetStaticMethodID(classID, "GetInstance", strtmp.c_str()); // jobject sInstance = pEnv->CallStaticObjectMethod(classID, methodGetInstance); // jmethodID getSystemService = pEnv->GetMethodID(classID, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); // jstring jstrPhone = pEnv->NewStringUTF("phone"); // jobject telephonyManager = pEnv->CallObjectMethod(sInstance, getSystemService, jstrPhone); // pEnv->DeleteLocalRef(jstrPhone); // // jclass clsTelephonyManager = pEnv->FindClass("android/telephony/TelephonyManager"); // jmethodID getDeviceId = pEnv->GetMethodID(clsTelephonyManager, "getDeviceId", "()Ljava/lang/String;"); // jstring jstrDevID = (jstring)pEnv->CallObjectMethod(telephonyManager, getDeviceId); // if (jstrDevID) { // const char *p = pEnv->GetStringUTFChars(jstrDevID, 0); // if (p && *p) { // ret = "DevID="; // ret += p; // pEnv->ReleaseStringUTFChars(jstrDevID, p); // } else { // if (p) { // pEnv->ReleaseStringUTFChars(jstrDevID, p); // } // jmethodID getContentResolver = pEnv->GetMethodID(classID, "getContentResolver", "()Landroid/content/ContentResolver;"); // jobject contentResolver = pEnv->CallObjectMethod(sInstance, getContentResolver); // // jclass clsSecure = pEnv->FindClass("android/provider/Settings/Secure"); // if (clsSecure) { // jmethodID Secure_getString = pEnv->GetMethodID(clsSecure, "getString", "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;"); // jstring jastrAndroid_ID = pEnv->NewStringUTF("android_id"); // jstring jstrAndroidID = (jstring)pEnv->CallStaticObjectMethod(clsSecure, Secure_getString, contentResolver, jastrAndroid_ID); // if (jstrAndroidID) { // const char *p = pEnv->GetStringUTFChars(jstrAndroidID, 0); // if (p && strlen(p) > 8 && strcmp(p, "9774d56d682e549c")) { // ret = "AndroidID="; // ret += p; // } // } // pEnv->ReleaseStringUTFChars(jstrAndroidID, p); // pEnv->DeleteLocalRef(jastrAndroid_ID); // } // } // } // if (ret.empty()) { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, "getDeviceId", "()Ljava/lang/String;")) { jstring result = (jstring)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID); ret = JniHelper::jstring2string(result); methodInfo.env->DeleteLocalRef(result); methodInfo.env->DeleteLocalRef(methodInfo.classID); char *t = (char*)ret.c_str(); while (*t) { if (*t == ':') { *t = '='; break; } t++; } } } return ret; } static jobject GetKR2ActInstance() { JniMethodInfo methodInfo; std::string strtmp("()L"); strtmp += KR2ActJavaPath; strtmp += ";"; if (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, "GetInstance", strtmp.c_str())) { jobject ret = methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); return ret; } return 0; } static std::string GetApkStoragePath() { JniMethodInfo methodInfo; jobject sInstance = GetKR2ActInstance(); if (!JniHelper::getMethodInfo(methodInfo, "android/content/Context", "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;")) { methodInfo.env->DeleteLocalRef(sInstance); return ""; } jobject ApplicationInfo = methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID); jclass clsApplicationInfo = methodInfo.env->FindClass("android/content/pm/ApplicationInfo"); jfieldID id_sourceDir = methodInfo.env->GetFieldID(clsApplicationInfo, "sourceDir", "Ljava/lang/String;"); methodInfo.env->DeleteLocalRef(sInstance); return JniHelper::jstring2string((jstring)methodInfo.env->GetObjectField(ApplicationInfo, id_sourceDir)); } static std::string GetPackageName() { JniMethodInfo methodInfo; jobject sInstance = GetKR2ActInstance(); if (!JniHelper::getMethodInfo(methodInfo, "android/content/ContextWrapper", "getPackageName", "()Ljava/lang/String;")) { methodInfo.env->DeleteLocalRef(sInstance); return ""; } return JniHelper::jstring2string((jstring)methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID)); } // from unzip.cpp #define FLAG_UTF8 (1<<11) extern zlib_filefunc64_def TVPZlibFileFunc; class ZipFile { unzFile uf; bool utf8; public: ZipFile() : uf(0) { } ~ZipFile() { if (uf) { unzClose(uf); uf = NULL; } } bool Open(const char *filename) { if ((uf = unzOpen(filename)) == NULL) { ttstr msg = filename; msg += TJS_W(" can't open."); TVPThrowExceptionMessage(msg.c_str()); return false; } // UTF8�ʥե����������ɤ������ж�������Υե�����ǛQ��� unzGoToFirstFile(uf); unz_file_info file_info; if (unzGetCurrentFileInfo(uf, &file_info, NULL, 0, NULL, 0, NULL, 0) == UNZ_OK) { utf8 = (file_info.flag & FLAG_UTF8) != 0; return true; } return false; } bool GetData(std::vector &buff, const char *filename) { bool ret = false; if (unzLocateFile(uf, filename, 1) == UNZ_OK) { int result = unzOpenCurrentFile(uf); if (result == UNZ_OK) { unz_file_info info; unzGetCurrentFileInfo(uf, &info, NULL, 0, NULL, 0, NULL, 0); buff.resize(info.uncompressed_size); unsigned int size = unzReadCurrentFile(uf, &buff[0], info.uncompressed_size); if (size == info.uncompressed_size) ret = true; unzCloseCurrentFile(uf); } } return ret; } tjs_int64 GetMD5InZip(const char *filename) { std::vector buff; if(!GetData(buff, filename)) return 0; md5_state_t state; md5_init(&state); md5_append(&state, (const md5_byte_t*)&buff[0], buff.size()); union { tjs_int64 _s64[2]; tjs_uint8 _u8[16]; } digest; md5_finish(&state, digest._u8); return digest._s64[0] ^ digest._s64[1]; } private: unzFile zipFile; }; std::string TVPGetDeviceLanguage() { // use pure jni to avoid java code JniMethodInfo methodInfo; if (!JniHelper::getStaticMethodInfo(methodInfo, "java/util/Locale", "getDefault", "()Ljava/util/Locale;")) return ""; jobject LocaleObj = methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID); if (!JniHelper::getMethodInfo(methodInfo, "java/util/Locale", "getLanguage", "()Ljava/lang/String;")) return ""; jstring languageID = (jstring)methodInfo.env->CallObjectMethod(LocaleObj, methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); return JniHelper::jstring2string(languageID); } std::string TVPGetPackageVersionString() { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, KR2ActJavaPath, "GetVersion", "()Ljava/lang/String;")) { return JniHelper::jstring2string((jstring)methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID)); } return ""; } static std::vector &split(const std::string &s, char delim, std::vector &elems) { std::stringstream ss(s); std::string item; while (std::getline(ss, item, delim)) { elems.emplace_back(item); } return elems; } static std::string File_getAbsolutePath(jobject FileObj) { if (!FileObj) return ""; JniMethodInfo methodInfo; if (!JniHelper::getMethodInfo(methodInfo, "java/io/File", "exists", "()Z")) return ""; if (!methodInfo.env->CallBooleanMethod(FileObj, methodInfo.methodID)) return ""; if (!JniHelper::getMethodInfo(methodInfo, "java/io/File", "getAbsolutePath", "()Ljava/lang/String;")) return ""; jstring path = (jstring)methodInfo.env->CallObjectMethod(FileObj, methodInfo.methodID); std::string ret = cocos2d::JniHelper::jstring2string(path); return ret; } static std::string GetInternalStoragePath() { jobject sInstance = GetKR2ActInstance(); JniMethodInfo methodInfo; if (!JniHelper::getMethodInfo(methodInfo, "android/content/ContextWrapper", "getFilesDir", "()Ljava/io/File;")) { return ""; } jobject FileObj = methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID); return File_getAbsolutePath(FileObj); } std::string Android_GetDumpStoragePath() { return GetInternalStoragePath() + "/dump"; } static int InsertFilepathInto(JNIEnv *env, std::vector& vec, jobjectArray FileObjs) { int count = env->GetArrayLength(FileObjs); for (int i = 0; i < count; ++i) { jobject FileObj = env->GetObjectArrayElement(FileObjs, i); std::string path = File_getAbsolutePath(FileObj); if (!path.empty()) vec.emplace_back(path); } return count; } static int GetExternalStoragePath(std::vector &ret) { int count = 0; JniMethodInfo methodInfo; jobject sInstance = GetKR2ActInstance(); // if (JniHelper::getMethodInfo(methodInfo, "android/content/Context", "getExternalMediaDirs", "()[Ljava/io/File;")) { // jobjectArray FileObjs = (jobjectArray)methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID); // if(FileObjs) count += InsertFilepathInto(methodInfo.env, ret, FileObjs); // } if (JniHelper::getMethodInfo(methodInfo, "android/content/Context", "getExternalFilesDirs", "(Ljava/lang/String;)[Ljava/io/File;")) { jobjectArray FileObjs = (jobjectArray)methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID, nullptr); if (FileObjs) count += InsertFilepathInto(methodInfo.env, ret, FileObjs); } else if (JniHelper::getMethodInfo(methodInfo, "android/content/Context", "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;")) { jobject FileObj = methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID, nullptr); if (FileObj) { ret.emplace_back(File_getAbsolutePath(FileObj)); ++count; } } return count; } std::vector TVPGetAppStoragePath() { std::vector ret; ret.emplace_back(GetInternalStoragePath()); GetExternalStoragePath(ret); return ret; } std::vector TVPGetDriverPath() { std::vector ret; jobject sInstance = GetKR2ActInstance(); JniMethodInfo methodInfo; if (JniHelper::getMethodInfo(methodInfo, KR2ActJavaPath, "getStoragePath", "()[Ljava/lang/String;")) { jobjectArray PathObjs = (jobjectArray)methodInfo.env->CallObjectMethod(sInstance, methodInfo.methodID); if (PathObjs) { int count = methodInfo.env->GetArrayLength(PathObjs); for (int i = 0; i < count; ++i) { jstring path = (jstring)methodInfo.env->GetObjectArrayElement(PathObjs, i); if (path) ret.emplace_back(cocos2d::JniHelper::jstring2string(path)); } } } if (!ret.empty()) return ret; char buffer[256] = { 0 }; // enum all mounted storages FILE *fp = fopen("/proc/mounts", "r"); std::set mounted; while (fgets(buffer, sizeof(buffer), fp)) { std::vector tabs; split(buffer, ' ', tabs); if (tabs.size() < 3) continue; if (mounted.find(tabs[0]) != mounted.end()) continue; const std::string &path = tabs[1]; if (tabs[3].find("rw,") != std::string::npos && (tabs[2] == "vfat" || path.find("/mnt") != std::string::npos)) { if (path.find("/mnt/secure") != std::string::npos || path.find("/mnt/asec") != std::string::npos || path.find("/mnt/mapper") != std::string::npos || path.find("/mnt/obb") != std::string::npos || tabs[0] == "tmpfs" || tabs[2] == "tmpfs") { continue; } mounted.insert(tabs[0]); ret.emplace_back(path); } } return ret; } // extern "C" int TVPCheckValidate() // { // JNIEnv *pEnv = 0; // bool ret = true; // // if (! getEnv(&pEnv)) // { // return false; // } // { // jclass classID = pEnv->FindClass(KR2EntryJavaPath); // std::string strtmp("()L"); strtmp += KR2EntryJavaPath; strtmp += ";"; // jmethodID methodGetInstance = pEnv->GetStaticMethodID(classID, "GetInstance", strtmp.c_str()); // jobject sInstance = pEnv->CallStaticObjectMethod(classID, methodGetInstance); // // jclass clsPreferenceManager = pEnv->FindClass("android.preference.PreferenceManager"); // jmethodID getDefaultSharedPreferences = pEnv->GetMethodID(clsPreferenceManager, "getDefaultSharedPreferences", "(Landroid/content/Context;)Landroid.preference.PreferenceManager;"); // jobject PreferenceManager = pEnv->CallStaticObjectMethod(clsPreferenceManager, getDefaultSharedPreferences, sInstance); // jmethodID getString = pEnv->GetMethodID(clsPreferenceManager, "getString", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); // jstring jstrConstAPPID = pEnv->NewStringUTF("APP_ID"); // jstring jstrNull = pEnv->NewStringUTF(""); // jstring jstrAPPID = (jstring)pEnv->CallObjectMethod(PreferenceManager, getString, jstrConstAPPID, jstrNull); // pEnv->DeleteLocalRef(jstrConstAPPID); // pEnv->DeleteLocalRef(jstrNull); // const char *p = pEnv->GetStringUTFChars(jstrAPPID, 0); // if(0x929e08af != adler32(0, (const Bytef*)p, strlen(p))) ret = false; // pEnv->ReleaseStringUTFChars(jstrAPPID, p); // } // // return ret; // } namespace kr2android { std::condition_variable MessageBoxCond; std::mutex MessageBoxLock; int MsgBoxRet = -2; std::string MessageBoxRetText; } using namespace kr2android; int TVPShowSimpleMessageBox(const char *pszText, const char *pszTitle, unsigned int nButton, const char **btnText) { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "ShowMessageBox", "(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V")) { jstring jstrTitle = methodInfo.env->NewStringUTF(pszTitle); jstring jstrText = methodInfo.env->NewStringUTF(pszText); jclass strcls = methodInfo.env->FindClass("java/lang/String"); jobjectArray btns = methodInfo.env->NewObjectArray(nButton, strcls, nullptr); for (unsigned int i = 0; i < nButton; ++i) { jstring jstrBtn = methodInfo.env->NewStringUTF(btnText[i]); methodInfo.env->SetObjectArrayElement(btns, i, jstrBtn); methodInfo.env->DeleteLocalRef(jstrBtn); } methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, jstrTitle, jstrText, btns); methodInfo.env->DeleteLocalRef(jstrTitle); methodInfo.env->DeleteLocalRef(jstrText); methodInfo.env->DeleteLocalRef(btns); methodInfo.env->DeleteLocalRef(methodInfo.classID); std::unique_lock lk(MessageBoxLock); while (MsgBoxRet == -2) { MessageBoxCond.wait_for(lk, std::chrono::milliseconds(200)); if (MsgBoxRet == -2) { TVPForceSwapBuffer(); // update opengl events } } return MsgBoxRet; } return -1; } int TVPShowSimpleMessageBox(const ttstr & text, const ttstr & caption, const std::vector &vecButtons) { tTJSNarrowStringHolder pszText(text.c_str()); tTJSNarrowStringHolder pszTitle(caption.c_str()); std::vector btnText; btnText.reserve(vecButtons.size()); std::vector btnTextHold; btnTextHold.reserve(vecButtons.size()); for (const ttstr &btn : vecButtons) { btnTextHold.emplace_back(btn.AsStdString()); btnText.emplace_back(btnTextHold.back().c_str()); } return TVPShowSimpleMessageBox(pszText, pszTitle, btnText.size(), &btnText[0]); } int TVPShowSimpleInputBox(ttstr &text, const ttstr &caption, const ttstr &prompt, const std::vector &vecButtons) { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "ShowInputBox", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V")) { jstring jstrTitle = methodInfo.env->NewStringUTF(caption.AsStdString().c_str()); jstring jstrText = methodInfo.env->NewStringUTF(text.AsStdString().c_str()); jstring jstrPrompt = methodInfo.env->NewStringUTF(prompt.AsStdString().c_str()); jclass strcls = methodInfo.env->FindClass("java/lang/String"); jobjectArray btns = methodInfo.env->NewObjectArray(vecButtons.size(), strcls, nullptr); for (unsigned int i = 0; i < vecButtons.size(); ++i) { jstring jstrBtn = methodInfo.env->NewStringUTF(vecButtons[i].AsStdString().c_str()); methodInfo.env->SetObjectArrayElement(btns, i, jstrBtn); methodInfo.env->DeleteLocalRef(jstrBtn); } MsgBoxRet = -2; methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, jstrTitle, jstrPrompt, jstrText, btns); methodInfo.env->DeleteLocalRef(jstrTitle); methodInfo.env->DeleteLocalRef(jstrText); methodInfo.env->DeleteLocalRef(jstrPrompt); methodInfo.env->DeleteLocalRef(btns); methodInfo.env->DeleteLocalRef(methodInfo.classID); std::unique_lock lk(MessageBoxLock); while (MsgBoxRet == -2) { MessageBoxCond.wait_for(lk, std::chrono::milliseconds(200)); if (MsgBoxRet == -2) { TVPForceSwapBuffer(); // update opengl events } } text = MessageBoxRetText; return MsgBoxRet; } return -1; } extern std::string Android_ShowInputDialog(const char* pszTitle, const char *pszInitText); extern std::string Android_ShowFileBrowser(const char* pszTitle, const char *pszInitDir, bool showEditor); extern ttstr TVPGetAppPath(); extern ttstr TVPGetLocallyAccessibleName(const ttstr &name); std::vector Android_GetExternalStoragePath() { static std::vector ret; if (ret.empty()) { std::vector pathlist; GetExternalStoragePath(pathlist); for (const std::string &path : pathlist) { std::string strPath = "file://."; strPath += path; ret.emplace_back(strPath); } } return ret; } ttstr Android_GetInternalStoragePath() { static ttstr strPath; if (strPath.IsEmpty()) { strPath = "file://."; strPath += GetInternalStoragePath(); } return strPath; } ttstr Android_GetApkStoragePath() { static ttstr strPath; if (strPath.IsEmpty()) { strPath = "file://."; strPath += GetApkStoragePath(); } return strPath; } #if 0 struct _eventQueueNode { std::function func; _eventQueueNode *prev; _eventQueueNode *next; }; static std::atomic<_eventQueueNode*> _lastQueuedEvents(nullptr); static void _processEvents(float) { _eventQueueNode* q = _lastQueuedEvents.exchange(nullptr); if (q) { q->next = nullptr; while (q->prev) { q->prev->next = q; q = q->prev; } } while (q) { q->func(); _eventQueueNode *nq = q->next; delete q; q = nq; } } void Android_PushEvents(const std::function &func) { _eventQueueNode *node = new _eventQueueNode; node->func = func; node->next = nullptr; node->prev = nullptr; while (!_lastQueuedEvents.compare_exchange_weak(node->prev, node)) {} } #endif void TVPCheckAndSendDumps(const std::string &dumpdir, const std::string &packageName, const std::string &versionStr); bool TVPCheckStartupArg() { // check dump TVPCheckAndSendDumps(Android_GetDumpStoragePath(), GetPackageName(), TVPGetPackageVersionString()); #if 0 // register event dispatcher cocos2d::Director *director = cocos2d::Director::getInstance(); class HackForScheduler : public cocos2d::Scheduler { public: void regProcessEvents() { schedulePerFrame(_processEvents, &_lastQueuedEvents, -1, false); } }; static_cast(director->getScheduler())->regProcessEvents(); #endif return false; } void Android_PushEvents(const std::function &func) { cocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread(func); } void TVPControlAdDialog(int adType, int arg1, int arg2) { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "MessageController", "(III)V")) { methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, adType, arg1, arg2); methodInfo.env->DeleteLocalRef(methodInfo.classID); } } static int _GetAndroidSDKVersion() { JNIEnv *pEnv = JniHelper::getEnv(); jclass classID = pEnv->FindClass("android/os/Build$VERSION"); jfieldID idSDK_INT = pEnv->GetStaticFieldID(classID, "SDK_INT", "I"); return pEnv->GetStaticIntField(classID, idSDK_INT); } static int GetAndroidSDKVersion() { static int result = _GetAndroidSDKVersion(); return result; } static bool IsLollipop() { return GetAndroidSDKVersion() >= 21; } static bool IsOreo() { return GetAndroidSDKVersion() >= 26; } void TVPFetchSDCardPermission() { if (!IsLollipop()) return; std::vector paths; GetExternalStoragePath(paths); JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "requireLEXA", "(Ljava/lang/String;)V")) { jstring jstrPath = methodInfo.env->NewStringUTF(paths.back().c_str()); methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, jstrPath); methodInfo.env->DeleteLocalRef(jstrPath); return; } return; } bool TVPCheckStartupPath(const std::string &path) { // check writing permission first int pos = path.find_last_of('/'); if (pos == path.npos) return false; std::string parent = path.substr(0, pos); std::string testPath = parent + cocos2d::StringUtils::format("/_check_save_%d.tmp", time(nullptr)); JniMethodInfo methodInfo; bool success = false; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "isWritableNormal", "(Ljava/lang/String;)Z")) { jstring jstrPath = methodInfo.env->NewStringUTF(testPath.c_str()); success = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstrPath); methodInfo.env->DeleteLocalRef(jstrPath); TVPDeleteFile(testPath.c_str()); #if 0 if (success) { parent += "/savedata"; if (!TVPCheckExistentLocalFolder(parent)) { TVPCreateFolders(parent); } jstrPath = methodInfo.env->NewStringUTF(parent.c_str()); success = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstrPath); methodInfo.env->DeleteLocalRef(jstrPath); } #endif } if (!success) { std::vector paths; // paths.emplace_back(GetInternalStoragePath()); GetExternalStoragePath(paths); std::string pathlist; for (const std::string &path : paths) { pathlist += "\n"; pathlist += path; } std::string msg = LocaleConfigManager::GetInstance()->GetText("use_internal_path") + pathlist; #if 0 if (pathlist.size() > 0) { size_t pos = msg.find("%1"); if (pos != msg.npos) { msg = msg.replace(msg.begin() + pos, msg.begin() + pos + 2, pathlist.back()); } } #endif std::vector btns; btns.emplace_back("OK"); TVPShowSimpleMessageBox(msg, LocaleConfigManager::GetInstance()->GetText("readonly_storage"), btns); return false; #if 0 btns.push_back(LocaleConfigManager::GetInstance()->GetText("continue_run")); bool isLOLLIPOP = IsLollipop(); if (isLOLLIPOP) btns.push_back(LocaleConfigManager::GetInstance()->GetText("get_sdcard_permission")); else btns.push_back(LocaleConfigManager::GetInstance()->GetText("cancel")); int result = TVPShowSimpleMessageBox(msg, LocaleConfigManager::GetInstance()->GetText("readonly_storage"), btns); if (isLOLLIPOP && result == 1) { TVPFetchSDCardPermission(); } if (result != 0) return false; #endif } return true; } bool TVPCreateFolders(const ttstr &folder) { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "CreateFolders", "(Ljava/lang/String;)Z")) { jstring jstr = methodInfo.env->NewStringUTF(folder.AsStdString().c_str()); bool ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstr); methodInfo.env->DeleteLocalRef(jstr); methodInfo.env->DeleteLocalRef(methodInfo.classID); return ret; } return false; } static bool TVPWriteDataToFileJava(const std::string &filename, const void* data, unsigned int size) { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "WriteFile", "(Ljava/lang/String;[B)Z")) { cocos2d::FileUtils *fileutil = cocos2d::FileUtils::getInstance(); bool ret = false; int retry = 3; do { jstring jstr = methodInfo.env->NewStringUTF(filename.c_str()); jbyteArray arr = methodInfo.env->NewByteArray(size); methodInfo.env->SetByteArrayRegion(arr, 0, size, (jbyte*)data); ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstr, arr); methodInfo.env->DeleteLocalRef(arr); methodInfo.env->DeleteLocalRef(jstr); methodInfo.env->DeleteLocalRef(methodInfo.classID); } while (!fileutil->isFileExist(filename) && --retry); return ret; } return false; } bool TVPWriteDataToFile(const ttstr &filepath, const void *data, unsigned int size) { std::string filename = filepath.AsStdString(); cocos2d::FileUtils *fileutil = cocos2d::FileUtils::getInstance(); while (fileutil->isFileExist(filename)) { // for number filename suffix issue time_t t = time(nullptr); std::vector buffer; buffer.resize(filename.size() + 32); sprintf(&buffer.front(), "%s.%d.bak", filename.c_str(), (int)t); std::string tempname = &buffer.front(); if (rename(filename.c_str(), tempname.c_str()) == 0) { // file api is OK FILE *fp = fopen(filename.c_str(), "wb"); if (fp) { bool ret = fwrite(data, 1, size, fp) == size; fclose(fp); remove(tempname.c_str()); return ret; } } bool ret = TVPWriteDataToFileJava(filename, data, size); if (fileutil->isFileExist(tempname.c_str())) { TVPDeleteFile(tempname); } return ret; } FILE *fp = fopen(filename.c_str(), "wb"); if (fp) { // file api is OK int writed = fwrite(data, 1, size, fp); fclose(fp); return writed == size; } return TVPWriteDataToFileJava(filename, data, size); } std::string TVPGetCurrentLanguage() { JniMethodInfo t; std::string ret(""); if (JniHelper::getStaticMethodInfo(t, "org/tvp/kirikiri2/KR2Activity", "getLocaleName", "()Ljava/lang/String;")) { jstring str = (jstring)t.env->CallStaticObjectMethod(t.classID, t.methodID); t.env->DeleteLocalRef(t.classID); ret = JniHelper::jstring2string(str); t.env->DeleteLocalRef(str); } return ret; } void TVPExitApplication(int code) { TVPDeliverCompactEvent(TVP_COMPACT_LEVEL_MAX); if (!TVPIsSoftwareRenderManager()) iTVPTexture2D::RecycleProcess(); JniMethodInfo t; if (JniHelper::getStaticMethodInfo(t, "org/tvp/kirikiri2/KR2Activity", "exit", "()V")) { t.env->CallStaticVoidMethod(t.classID, t.methodID); t.env->DeleteLocalRef(t.classID); } exit(code); } void TVPHideIME() { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "hideTextInput", "()V")) { methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID); } } void TVPShowIME(int x, int y, int w, int h) { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "showTextInput", "(IIII)V")) { methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, x, y, w, h); } } void TVPProcessInputEvents() {} bool TVPDeleteFile(const std::string &filename) { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "DeleteFile", "(Ljava/lang/String;)Z")) { jstring jstr = methodInfo.env->NewStringUTF(filename.c_str()); bool ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstr); methodInfo.env->DeleteLocalRef(jstr); methodInfo.env->DeleteLocalRef(methodInfo.classID); return ret; } return false; } bool TVPRenameFile(const std::string &from, const std::string &to) { JniMethodInfo methodInfo; if (JniHelper::getStaticMethodInfo(methodInfo, "org/tvp/kirikiri2/KR2Activity", "RenameFile", "(Ljava/lang/String;Ljava/lang/String;)Z")) { jstring jstr = methodInfo.env->NewStringUTF(from.c_str()); jstring jstr2 = methodInfo.env->NewStringUTF(to.c_str()); bool ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID, jstr, jstr2); methodInfo.env->DeleteLocalRef(jstr); methodInfo.env->DeleteLocalRef(jstr2); methodInfo.env->DeleteLocalRef(methodInfo.classID); return ret; } return false; } tjs_uint32 TVPGetRoughTickCount32() { tjs_uint32 uptime = 0; struct timespec on; if (clock_gettime(CLOCK_MONOTONIC, &on) == 0) uptime = on.tv_sec * 1000 + on.tv_nsec / 1000000; return uptime; } bool TVP_stat(const tjs_char *name, tTVP_stat &s) { tTJSNarrowStringHolder holder(name); return TVP_stat(holder, s); } #undef st_atime #undef st_ctime #undef st_mtime //int stat64(const char* __path, struct stat64* __buf) __INTRODUCED_IN(21); // force link it ! bool TVP_stat(const char *name, tTVP_stat &s) { struct stat t; // static_assert(sizeof(t.st_size) == 4, ""); static_assert(sizeof(t.st_size) == 8, ""); bool ret = !stat(name, &t); s.st_mode = t.st_mode; s.st_size = t.st_size; s.st_atime = t.st_atim.tv_sec; s.st_mtime = t.st_mtim.tv_sec; s.st_ctime = t.st_ctim.tv_sec; return ret; } void TVPSendToOtherApp(const std::string &filename) { } ================================================ FILE: src/core/environ/android/AndroidUtils.h ================================================ #pragma once #include #include std::string TVPGetDeviceID(); ================================================ FILE: src/core/environ/cocos2d/AppDelegate.cpp ================================================ #include "AppDelegate.h" #include "MainScene.h" #include "ui/MainFileSelectorForm.h" #include "ui/extension/UIExtension.h" #include "cocostudio/FlatBuffersSerialize.h" #include "ConfigManager/LocaleConfigManager.h" #include "ConfigManager/GlobalConfigManager.h" #include "Application.h" #include "Platform.h" #include "ui/MessageBox.h" #include "ui/GlobalPreferenceForm.h" #include "CustomFileUtils.h" USING_NS_CC; cocos2d::FileUtils *TVPCreateCustomFileUtils(); extern "C" void SDL_SetMainReady(void); extern std::thread::id TVPMainThreadID; static Size designResolutionSize(960, 640); bool TVPCheckStartupArg(); cocos2d::FileUtils *TVPCreateCustomFileUtils(); void TVPAppDelegate::applicationWillEnterForeground() { ::Application->OnActivate(); Director::getInstance()->startAnimation(); } void TVPAppDelegate::applicationDidEnterBackground() { ::Application->OnDeactivate(); Director::getInstance()->stopAnimation(); } bool TVPAppDelegate::applicationDidFinishLaunching() { SDL_SetMainReady(); TVPMainThreadID = std::this_thread::get_id(); cocos2d::log("applicationDidFinishLaunching"); // initialize director FileUtils::setDelegate(TVPCreateCustomFileUtils()); auto director = Director::getInstance(); auto glview = director->getOpenGLView(); if (!glview) { glview = GLViewImpl::create("kirikiri2 frame"); director->setOpenGLView(glview); #if CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM glview->setFrameSize(960, 640); #endif } // Set the design resolution Size screenSize = glview->getFrameSize(); if (screenSize.width < screenSize.height) { std::swap(screenSize.width, screenSize.height); } Size designSize = designResolutionSize; designSize.height = designSize.width * screenSize.height / screenSize.width; glview->setDesignResolutionSize(designSize.width, designSize.height, ResolutionPolicy::SHOW_ALL); Size frameSize = glview->getFrameSize(); std::vector searchPath; // In this demo, we select resource according to the frame's height. // If the resource size is different from design resolution size, you need to set contentScaleFactor. // We use the ratio of resource's height to the height of design resolution, // this can make sure that the resource's height could fit for the height of design resolution. searchPath.emplace_back("res"); TVPSkinManager::getInstance()->InitSkin(); // set searching path FileUtils::getInstance()->setSearchPaths(searchPath); // turn on display FPS director->setDisplayStats(false); // set FPS. the default value is 1.0/60 if you don't call this director->setAnimationInterval(1.0f / 60); TVPInitUIExtension(); // initialize something LocaleConfigManager::GetInstance()->Initialize(TVPGetCurrentLanguage()); // create a scene. it's an autorelease object TVPMainScene *scene = TVPMainScene::CreateInstance(); // run director->runWithScene(scene); //director->getConsole()->listenOnTCP(16006); scene->scheduleOnce([](float dt){ TVPMainScene::GetInstance()->unschedule("launch"); TVPGlobalPreferenceForm::Initialize(); if (!TVPCheckStartupArg()) { TVPMainScene::GetInstance()->pushUIForm(TVPMainFileSelectorForm::create()); } }, 0, "launch"); return true; } void TVPAppDelegate::initGLContextAttrs() { GLContextAttrs glContextAttrs = { 8, 8, 8, 8, 24, 8 }; GLView::setGLContextAttrs(glContextAttrs); } void TVPAppDelegate::applicationScreenSizeChanged(int newWidth, int newHeight) { // auto director = Director::getInstance(); // director->getOpenGLView()->setFrameSize(newWidth, newHeight); } void TVPOpenPatchLibUrl() { cocos2d::Application::getInstance()->openURL("https://zeas2.github.io/Kirikiroid2_patch/patch"); } ================================================ FILE: src/core/environ/cocos2d/AppDelegate.h ================================================ #pragma once #include "cocos2d.h" class TVPAppDelegate : public cocos2d::Application { virtual void initGLContextAttrs(); /** @brief Implement Director and Scene init code here. @return true Initialize success, app continue. @return false Initialize failed, app terminate. */ virtual bool applicationDidFinishLaunching(); /** @brief The function be called when the application enter background @param the pointer of the application */ virtual void applicationDidEnterBackground(); /** @brief The function be called when the application enter foreground @param the pointer of the application */ virtual void applicationWillEnterForeground(); virtual void applicationScreenSizeChanged(int newWidth, int newHeight); }; ================================================ FILE: src/core/environ/cocos2d/CCKeyCodeConv.cpp ================================================ #include "CCKeyCodeConv.h" #include "cocos/base/CCController.h" #include "vkdefine.h" int TVPConvertMouseBtnToVKCode(tTVPMouseButton _mouseBtn) { int btncode; switch (_mouseBtn) { case mbLeft: btncode = VK_LBUTTON; break; case mbMiddle: btncode = VK_MBUTTON; break; case mbRight: btncode = VK_RBUTTON; break; default: btncode = 0; break; } return btncode; } int TVPConvertKeyCodeToVKCode(cocos2d::EventKeyboard::KeyCode keyCode) { #define CASE(x) case cocos2d::EventKeyboard::KeyCode::KEY_##x: return VK_##x switch (keyCode) { CASE(0); CASE(1); CASE(2); CASE(3); CASE(4); CASE(5); CASE(6); CASE(7); CASE(8); CASE(9); CASE(A); CASE(B); CASE(C); CASE(D); CASE(E); CASE(F); CASE(G); CASE(H); CASE(I); CASE(J); CASE(K); CASE(L); CASE(M); CASE(N); CASE(O); CASE(P); CASE(Q); CASE(R); CASE(S); CASE(T); CASE(U); CASE(V); CASE(W); CASE(X); CASE(Y); CASE(Z); CASE(F1); CASE(F2); CASE(F3); CASE(F4); CASE(F5); CASE(F6); CASE(F7); CASE(F8); CASE(F9); CASE(F10); CASE(F11); CASE(F12); CASE(PAUSE); CASE(PRINT); CASE(ESCAPE); case cocos2d::EventKeyboard::KeyCode::KEY_BACK_TAB: CASE(TAB); CASE(RETURN); case cocos2d::EventKeyboard::KeyCode::KEY_SCROLL_LOCK: return VK_SCROLL; case cocos2d::EventKeyboard::KeyCode::KEY_SYSREQ: return VK_SNAPSHOT; case cocos2d::EventKeyboard::KeyCode::KEY_BREAK: return VK_CANCEL; case cocos2d::EventKeyboard::KeyCode::KEY_BACKSPACE: return VK_BACK; case cocos2d::EventKeyboard::KeyCode::KEY_CAPS_LOCK: return VK_CAPITAL; case cocos2d::EventKeyboard::KeyCode::KEY_LEFT_SHIFT: return VK_SHIFT; // LR the same case cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_SHIFT: return VK_SHIFT; case cocos2d::EventKeyboard::KeyCode::KEY_LEFT_CTRL: return VK_CONTROL; // LR the same case cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_CTRL: return VK_CONTROL; case cocos2d::EventKeyboard::KeyCode::KEY_LEFT_ALT: return VK_MENU; case cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_ALT: return VK_MENU; case cocos2d::EventKeyboard::KeyCode::KEY_MENU: return VK_APPS; case cocos2d::EventKeyboard::KeyCode::KEY_HYPER: return VK_LWIN; CASE(INSERT); CASE(HOME); CASE(DELETE); CASE(END); case cocos2d::EventKeyboard::KeyCode::KEY_KP_PG_UP: case cocos2d::EventKeyboard::KeyCode::KEY_PG_UP: return VK_PRIOR; case cocos2d::EventKeyboard::KeyCode::KEY_KP_PG_DOWN: case cocos2d::EventKeyboard::KeyCode::KEY_PG_DOWN: return VK_NEXT; case cocos2d::EventKeyboard::KeyCode::KEY_KP_LEFT: case cocos2d::EventKeyboard::KeyCode::KEY_LEFT_ARROW: return VK_LEFT; case cocos2d::EventKeyboard::KeyCode::KEY_KP_RIGHT: case cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_ARROW: return VK_RIGHT; case cocos2d::EventKeyboard::KeyCode::KEY_KP_UP: case cocos2d::EventKeyboard::KeyCode::KEY_UP_ARROW: return VK_UP; case cocos2d::EventKeyboard::KeyCode::KEY_KP_DOWN: case cocos2d::EventKeyboard::KeyCode::KEY_DOWN_ARROW: return VK_DOWN; case cocos2d::EventKeyboard::KeyCode::KEY_NUM_LOCK: return VK_NUMLOCK; case cocos2d::EventKeyboard::KeyCode::KEY_KP_PLUS: return VK_ADD; case cocos2d::EventKeyboard::KeyCode::KEY_KP_MINUS: return VK_SUBTRACT; case cocos2d::EventKeyboard::KeyCode::KEY_KP_MULTIPLY: return VK_MULTIPLY; case cocos2d::EventKeyboard::KeyCode::KEY_KP_DIVIDE: return VK_DIVIDE; case cocos2d::EventKeyboard::KeyCode::KEY_KP_ENTER: return VK_RETURN; case cocos2d::EventKeyboard::KeyCode::KEY_KP_HOME: return VK_HOME; case cocos2d::EventKeyboard::KeyCode::KEY_KP_FIVE: return VK_NUMPAD5; case cocos2d::EventKeyboard::KeyCode::KEY_KP_END: return VK_END; case cocos2d::EventKeyboard::KeyCode::KEY_KP_INSERT: return VK_INSERT; case cocos2d::EventKeyboard::KeyCode::KEY_KP_DELETE: return VK_DELETE; CASE(SPACE); case cocos2d::EventKeyboard::KeyCode::KEY_EXCLAM: return VK_SPACE; case cocos2d::EventKeyboard::KeyCode::KEY_QUOTE: return VK_OEM_7; case cocos2d::EventKeyboard::KeyCode::KEY_COMMA: return VK_OEM_COMMA; case cocos2d::EventKeyboard::KeyCode::KEY_MINUS: return VK_OEM_MINUS; case cocos2d::EventKeyboard::KeyCode::KEY_PERIOD: return VK_OEM_PERIOD; case cocos2d::EventKeyboard::KeyCode::KEY_EQUAL: return VK_OEM_PLUS; case cocos2d::EventKeyboard::KeyCode::KEY_SLASH: return VK_OEM_2; case cocos2d::EventKeyboard::KeyCode::KEY_SEMICOLON: return VK_OEM_1; case cocos2d::EventKeyboard::KeyCode::KEY_BACK_SLASH: return VK_OEM_5; case cocos2d::EventKeyboard::KeyCode::KEY_LEFT_BRACE: return VK_OEM_4; case cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_BRACE: return VK_OEM_6; case cocos2d::EventKeyboard::KeyCode::KEY_PLAY: return VK_PLAY; case cocos2d::EventKeyboard::KeyCode::KEY_NUMBER: case cocos2d::EventKeyboard::KeyCode::KEY_DOLLAR: case cocos2d::EventKeyboard::KeyCode::KEY_PERCENT: case cocos2d::EventKeyboard::KeyCode::KEY_CIRCUMFLEX: case cocos2d::EventKeyboard::KeyCode::KEY_AMPERSAND: case cocos2d::EventKeyboard::KeyCode::KEY_APOSTROPHE: case cocos2d::EventKeyboard::KeyCode::KEY_LEFT_PARENTHESIS: case cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_PARENTHESIS: case cocos2d::EventKeyboard::KeyCode::KEY_ASTERISK: case cocos2d::EventKeyboard::KeyCode::KEY_COLON: case cocos2d::EventKeyboard::KeyCode::KEY_LESS_THAN: case cocos2d::EventKeyboard::KeyCode::KEY_PLUS: case cocos2d::EventKeyboard::KeyCode::KEY_GREATER_THAN: case cocos2d::EventKeyboard::KeyCode::KEY_QUESTION: case cocos2d::EventKeyboard::KeyCode::KEY_AT: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_A: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_B: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_C: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_D: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_E: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_F: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_G: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_H: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_I: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_J: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_K: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_L: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_M: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_N: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_O: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_P: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_Q: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_R: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_S: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_T: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_U: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_V: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_W: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_X: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_Y: case cocos2d::EventKeyboard::KeyCode::KEY_CAPITAL_Z: case cocos2d::EventKeyboard::KeyCode::KEY_LEFT_BRACKET: case cocos2d::EventKeyboard::KeyCode::KEY_RIGHT_BRACKET: case cocos2d::EventKeyboard::KeyCode::KEY_UNDERSCORE: case cocos2d::EventKeyboard::KeyCode::KEY_GRAVE: case cocos2d::EventKeyboard::KeyCode::KEY_BAR: case cocos2d::EventKeyboard::KeyCode::KEY_TILDE: case cocos2d::EventKeyboard::KeyCode::KEY_EURO: case cocos2d::EventKeyboard::KeyCode::KEY_POUND: case cocos2d::EventKeyboard::KeyCode::KEY_YEN: case cocos2d::EventKeyboard::KeyCode::KEY_MIDDLE_DOT: case cocos2d::EventKeyboard::KeyCode::KEY_SEARCH: case cocos2d::EventKeyboard::KeyCode::KEY_DPAD_LEFT: case cocos2d::EventKeyboard::KeyCode::KEY_DPAD_RIGHT: case cocos2d::EventKeyboard::KeyCode::KEY_DPAD_UP: case cocos2d::EventKeyboard::KeyCode::KEY_DPAD_DOWN: case cocos2d::EventKeyboard::KeyCode::KEY_DPAD_CENTER: case cocos2d::EventKeyboard::KeyCode::KEY_ENTER: default: return 0; } #undef CASE } int TVPConvertPadKeyCodeToVKCode(int keyCode) { switch (keyCode) { case cocos2d::Controller::BUTTON_A: return VK_PAD1; case cocos2d::Controller::BUTTON_B: return VK_PAD2; case cocos2d::Controller::BUTTON_C: return VK_PAD3; case cocos2d::Controller::BUTTON_X: return VK_PAD4; case cocos2d::Controller::BUTTON_Y: return VK_PAD5; case cocos2d::Controller::BUTTON_Z: return VK_PAD6; case cocos2d::Controller::BUTTON_LEFT_SHOULDER: return VK_PAD7; case cocos2d::Controller::BUTTON_RIGHT_SHOULDER: return VK_PAD8; case cocos2d::Controller::BUTTON_LEFT_THUMBSTICK: return VK_PAD9; case cocos2d::Controller::BUTTON_RIGHT_THUMBSTICK: return VK_PAD10; case cocos2d::Controller::BUTTON_START: return VK_PAD9; case cocos2d::Controller::BUTTON_SELECT: return VK_PAD10; case cocos2d::Controller::AXIS_LEFT_TRIGGER: return VK_PAD5; case cocos2d::Controller::AXIS_RIGHT_TRIGGER: return VK_PAD6; case cocos2d::Controller::BUTTON_PAUSE: return VK_PAD7; case cocos2d::Controller::BUTTON_DPAD_UP: return VK_PADUP; case cocos2d::Controller::BUTTON_DPAD_DOWN: return VK_PADDOWN; case cocos2d::Controller::BUTTON_DPAD_LEFT: return VK_PADLEFT; case cocos2d::Controller::BUTTON_DPAD_RIGHT: return VK_PADRIGHT; case cocos2d::Controller::BUTTON_DPAD_CENTER: default: return 0; } } const std::unordered_map & TVPGetVKCodeNameMap() { static std::unordered_map ret({ #define CASE(x) { #x, VK_##x } CASE(0), CASE(1), CASE(2), CASE(3), CASE(4), CASE(5), CASE(6), CASE(7), CASE(8), CASE(9), CASE(A), CASE(B), CASE(C), CASE(D), CASE(E), CASE(F), CASE(G), CASE(H), CASE(I), CASE(J), CASE(K), CASE(L), CASE(M), CASE(N), CASE(O), CASE(P), CASE(Q), CASE(R), CASE(S), CASE(T), CASE(U), CASE(V), CASE(W), CASE(X), CASE(Y), CASE(Z), CASE(F1), CASE(F2), CASE(F3), CASE(F4), CASE(F5), CASE(F6), CASE(F7), CASE(F8), CASE(F9), CASE(F10), CASE(F11), CASE(F12), CASE(PAUSE), CASE(PRINT), CASE(ESCAPE), CASE(TAB), CASE(RETURN), CASE(SCROLL), CASE(SNAPSHOT), CASE(CANCEL), CASE(BACK), CASE(CAPITAL), CASE(SHIFT), CASE(CONTROL), CASE(MENU), CASE(APPS), CASE(LWIN), CASE(INSERT), CASE(HOME), CASE(DELETE), CASE(END), CASE(PRIOR), CASE(NEXT), CASE(LEFT), CASE(RIGHT), CASE(UP), CASE(DOWN), CASE(NUMLOCK), CASE(ADD), CASE(SUBTRACT), CASE(MULTIPLY), CASE(DIVIDE), CASE(HOME), CASE(NUMPAD5), CASE(END), CASE(INSERT), CASE(DELETE), CASE(SPACE), CASE(OEM_COMMA), CASE(OEM_MINUS), CASE(OEM_PERIOD), CASE(OEM_PLUS), CASE(OEM_1), CASE(OEM_2), CASE(OEM_4), CASE(OEM_5), CASE(OEM_6), CASE(OEM_7), CASE(PLAY), #undef CASE }); return ret; } std::string TVPGetVKCodeName(int keyCode) { return ""; } ================================================ FILE: src/core/environ/cocos2d/CCKeyCodeConv.h ================================================ #include "tjsTypes.h" #include "tvpinputdefs.h" #include "cocos2d.h" int TVPConvertMouseBtnToVKCode(tTVPMouseButton _mouseBtn); int TVPConvertKeyCodeToVKCode(cocos2d::EventKeyboard::KeyCode keyCode); int TVPConvertPadKeyCodeToVKCode(int keyCode); const std::unordered_map &TVPGetVKCodeNameMap(); std::string TVPGetVKCodeName(int keyCode); ================================================ FILE: src/core/environ/cocos2d/CustomFileUtils.cpp ================================================ #include "CustomFileUtils.h" #if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 #include "platform/win32/CCFileUtils-win32.h" #elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS #import #import "platform/apple/CCFileUtils-apple.h" #elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID #include "platform/android/CCFileUtils-android.h" #endif #ifdef MINIZIP_FROM_SYSTEM #include #else // from our embedded sources #include "external/unzip/unzip.h" #endif #include "ConfigManager/LocaleConfigManager.h" NS_CC_BEGIN typedef #if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 FileUtilsWin32 #elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS FileUtilsApple #elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID FileUtilsAndroid #endif FileUtilsInherit; class CustomFileUtils : public FileUtilsInherit { public: CustomFileUtils(); void addAutoSearchArchive(const std::string& path); virtual std::string fullPathForFilename(const std::string &filename) const override; virtual std::string getStringFromFile(const std::string& filename); virtual Data getDataFromFile(const std::string& filename); virtual unsigned char* getFileData(const std::string& filename, const char* mode, ssize_t *size); virtual bool isFileExistInternal(const std::string& strFilePath) const override; virtual bool isDirectoryExistInternal(const std::string& dirPath) const override; virtual bool init() override { return FileUtilsInherit::init(); } private: unsigned char* getFileDataFromArchive(const std::string& filename, ssize_t *size); std::unordered_map > _autoSearchArchive; std::mutex _lock; }; CustomFileUtils::CustomFileUtils() { } void CustomFileUtils::addAutoSearchArchive(const std::string& path) { if (!this->isFileExist(path)) return; unzFile file = nullptr; file = unzOpen(FileUtils::getInstance()->getSuitableFOpen(path).c_str()); unz_file_info file_info; do { unz_file_pos entry; if (unzGetFilePos(file, &entry) == UNZ_OK) { char filename_inzip[1024]; if (unzGetCurrentFileInfo(file, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0) == UNZ_OK) { _autoSearchArchive[filename_inzip] = std::make_pair(file, entry); } } } while (unzGoToNextFile(file) == UNZ_OK); } std::string CustomFileUtils::fullPathForFilename(const std::string &filename) const { auto it = _autoSearchArchive.find(filename); if (_autoSearchArchive.end() != it) { return filename; } return FileUtilsInherit::fullPathForFilename(filename); } unsigned char* CustomFileUtils::getFileData(const std::string& filename, const char* mode, ssize_t *size) { unsigned char* ret = getFileDataFromArchive(filename, size); if (ret) return ret; return FileUtilsInherit::getFileData(filename, mode, size); } bool CustomFileUtils::isFileExistInternal(const std::string& strFilePath) const { auto it = _autoSearchArchive.find(strFilePath); if (_autoSearchArchive.end() != it) { return true; } return FileUtilsInherit::isFileExistInternal(strFilePath); } bool CustomFileUtils::isDirectoryExistInternal(const std::string& dirPath) const { for (auto &it : _autoSearchArchive) { if (it.first.size() <= dirPath.size()) continue; if (!strncmp(it.first.c_str(), dirPath.c_str(), dirPath.size()) && it.first[dirPath.size()] == '/') { return true; } } return FileUtilsInherit::isDirectoryExistInternal(dirPath); } unsigned char* CustomFileUtils::getFileDataFromArchive(const std::string& filename, ssize_t *size) { auto it = _autoSearchArchive.find(filename); if (_autoSearchArchive.end() != it) { _lock.lock(); if (unzGoToFilePos(it->second.first, &it->second.second) != UNZ_OK) return nullptr; unz_file_info fileInfo; if (unzGetCurrentFileInfo(it->second.first, &fileInfo, NULL, 0, NULL, 0, NULL, 0) != UNZ_OK) return nullptr; unsigned char *buffer = (unsigned char*)malloc(fileInfo.uncompressed_size); int readedSize = unzReadCurrentFile(it->second.first, buffer, static_cast(fileInfo.uncompressed_size)); _lock.unlock(); CCASSERT(readedSize == 0 || readedSize == (int)fileInfo.uncompressed_size, "the file size is wrong"); *size = fileInfo.uncompressed_size; return buffer; } return nullptr; } cocos2d::Data CustomFileUtils::getDataFromFile(const std::string& filename) { ssize_t size; unsigned char* buffer = getFileDataFromArchive(filename, &size); if (buffer) { Data ret; ret.fastSet(buffer, size); return ret; } return FileUtilsInherit::getDataFromFile(filename); } std::string CustomFileUtils::getStringFromFile(const std::string& filename) { Data data = getDataFromFile(filename); if (data.isNull()) return ""; std::string ret((const char*)data.getBytes()); return ret; } NS_CC_END cocos2d::FileUtils *TVPCreateCustomFileUtils() { cocos2d::CustomFileUtils *ret = new cocos2d::CustomFileUtils; ret->init(); return ret; } void TVPAddAutoSearchArchive(const std::string &path) { cocos2d::CustomFileUtils *fileutils =static_cast(cocos2d::FileUtils::getInstance()); fileutils->addAutoSearchArchive(path); } #include "StorageImpl.h" #include "Platform.h" #include "ConfigManager/GlobalConfigManager.h" #include "tinyxml2/tinyxml2.h" USING_NS_CC; static bool TVPCopyFolder(const std::string &from, const std::string &to) { if (!TVPCheckExistentLocalFolder(to) && !TVPCreateFolders(to)) { return false; } bool success = true; TVPListDir(from, [&](const std::string &_name, int mask) { if (_name == "." || _name == "..") return; if (!success) return; if (mask & S_IFREG) { success = TVPCopyFile(from + "/" + _name, to + "/" + _name); } else if (mask & S_IFDIR) { success = TVPCopyFolder(from + "/" + _name, to + "/" + _name); } }); return success; } bool TVPCopyFile(const std::string &from, const std::string &to) { FILE * ffrom = fopen(from.c_str(), "rb"); if (!ffrom) { // try folder copy return TVPCopyFolder(from, to); } FILE * fto = fopen(to.c_str(), "wb"); if (!fto) { if (ffrom) fclose(ffrom); return false; } const int bufSize = 1 * 1024 * 1024; std::vector buffer; buffer.resize(bufSize); int readed = 0; while ((readed = fread(&buffer.front(), 1, bufSize, ffrom))) { fwrite(&buffer.front(), 1, readed, fto); } fclose(ffrom); fclose(fto); return true; } TVPSkinManager* TVPSkinManager::getInstance() { static TVPSkinManager instance; return &instance; } void TVPSkinManager::InitSkin() { std::string skinpath = GlobalConfigManager::GetInstance()->GetValue("skin_path", ""); if (!skinpath.empty()) { if (!Check(skinpath)) { TVPShowSimpleMessageBox( LocaleConfigManager::GetInstance()->GetText("invalid_skin_desc"), LocaleConfigManager::GetInstance()->GetText("invalid_skin")); Reset(); } else { static_cast(FileUtils::getInstance())->addAutoSearchArchive(skinpath); } } } static const char *_adapted_skin_version = "1.3.4"; bool TVPSkinManager::Check(const std::string &path) { if (!cocos2d::FileUtils::getInstance()->isFileExist(path)) { return false; } tinyxml2::XMLDocument doc; unzFile file = nullptr; file = unzOpen(FileUtils::getInstance()->getSuitableFOpen(path).c_str()); unz_file_info file_info; do { unz_file_pos entry; if (unzGetFilePos(file, &entry) == UNZ_OK) { char filename_inzip[1024]; if (unzGetCurrentFileInfo(file, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0) == UNZ_OK) { if (strcmp(filename_inzip, "meta.xml")) { if (unzGoToFilePos(&file, &entry) != UNZ_OK) break; unsigned char *buffer = (unsigned char*)malloc(file_info.uncompressed_size); int readedSize = unzReadCurrentFile(&file, buffer, static_cast(file_info.uncompressed_size)); if (readedSize != (int)file_info.uncompressed_size) { free(buffer); break; } doc.Parse((char*)buffer); free(buffer); break; } } } } while (unzGoToNextFile(file) == UNZ_OK); unzClose(file); tinyxml2::XMLElement* root = doc.RootElement(); if (!root) return false; const char *s = root->Attribute("version"); if (!s) return false; return !strcmp(s, _adapted_skin_version); } void TVPSkinManager::Reset() { GlobalConfigManager::GetInstance()->SetValue("skin_path", ""); GlobalConfigManager::GetInstance()->SaveToFile(); } bool TVPSkinManager::Use(const std::string &skin_path) { GlobalConfigManager::GetInstance()->SetValue("skin_path", skin_path); GlobalConfigManager::GetInstance()->SaveToFile(); return true; } bool TVPSkinManager::InstallAndUse(const std::string &skin_path) { std::string path = FileUtils::getInstance()->getWritablePath() + "default.skin"; FileUtils::getInstance()->removeFile(path); if (!TVPCopyFile(skin_path, path)) { return false; } GlobalConfigManager::GetInstance()->SetValue("skin_path", path); return true; } ================================================ FILE: src/core/environ/cocos2d/CustomFileUtils.h ================================================ #pragma once #include "cocos2d.h" void TVPAddAutoSearchArchive(const std::string &path); class TVPSkinManager { public: static TVPSkinManager* getInstance(); void InitSkin(); static bool Check(const std::string &skin_path); static void Reset(); static bool Use(const std::string &skin_path); static bool InstallAndUse(const std::string &skin_path); }; ================================================ FILE: src/core/environ/cocos2d/CustomFileUtils.mm ================================================ #include "CustomFileUtils.cpp" ================================================ FILE: src/core/environ/cocos2d/MainScene.cpp ================================================ #include "MainScene.h" #include "cocos2d.h" #include "cocos-ext.h" #include "tjsCommHead.h" #include "StorageIntf.h" #include "EventIntf.h" #include "SysInitImpl.h" #include "WindowImpl.h" #include "LayerBitmapIntf.h" #include "LayerBitmapImpl.h" #include "ui/BaseForm.h" #include "ui/GameMainMenu.h" #include "ui/UIHelper.h" #include "TickCount.h" #include "Random.h" #include "UtilStreams.h" #include "vkdefine.h" #include "base/CCEventListenerController.h" #include "base/CCController.h" #include "ConfigManager/IndividualConfigManager.h" #include "Platform.h" #include "ui/ConsoleWindow.h" #include "ui/FileSelectorForm.h" #include "ui/DebugViewLayerForm.h" #include "ui/UIButton.h" #include "Application.h" #include "ScriptMgnIntf.h" #include "win32/TVPWindow.h" #include "VelocityTracker.h" #include "SystemImpl.h" #include "RenderManager.h" #include "VideoOvlIntf.h" #include "Exception.h" #include "win32/SystemControl.h" USING_NS_CC; enum SCENE_ORDER { GAME_SCENE_ORDER, GAME_CONSOLE_ORDER, GAME_WINMGR_ORDER, // also for the virtual mouse cursor GAME_MENU_ORDER, UI_NODE_ORDER, }; const float UI_CHANGE_DURATION = 0.3f; class TVPWindowLayer; static TVPWindowLayer *_lastWindowLayer, *_currentWindowLayer; class TVPWindowManagerOverlay; static TVPWindowManagerOverlay *_windowMgrOverlay = nullptr; static TVPConsoleWindow* _consoleWin = nullptr; static float _touchMoveThresholdSq; static cocos2d::Node *_mouseCursor; static float _mouseCursorScale; static Vec2 _mouseTouchPoint, _mouseBeginPoint; static std::set _mouseTouches; static tTVPMouseButton _mouseBtn; static int _touchBeginTick; static bool _virutalMouseMode = false; static bool _mouseMoved, _mouseClickedDown; static tjs_uint8 _scancode[0x200]; static tjs_uint16 _keymap[0x200]; static Label *_fpsLabel = nullptr; #include "CCKeyCodeConv.h" #ifndef GL_UNPACK_ROW_LENGTH #define GL_UNPACK_ROW_LENGTH 0x0CF2 #endif static void(*_postUpdate)() = nullptr; void TVPSetPostUpdateEvent(void(*f)()) { _postUpdate = f; } static void _refadeMouseCursor() { _mouseCursor->stopAllActions(); _mouseCursor->setOpacity(255); _mouseCursor->runAction(Sequence::createWithTwoActions(DelayTime::create(3), FadeOut::create(0.3f))); } static void AdjustNumerAndDenom(tjs_int &n, tjs_int &d) { tjs_int a = n; tjs_int b = d; while (b) { tjs_int t = b; b = a % b; a = t; } n = n / a; d = d / a; } bool TVPGetKeyMouseAsyncState(tjs_uint keycode, bool getcurrent) { if (keycode >= sizeof(_scancode) / sizeof(_scancode[0])) return false; tjs_uint8 code = _scancode[keycode]; _scancode[keycode] &= 1; return code & (getcurrent ? 1 : 0x10); } bool TVPGetJoyPadAsyncState(tjs_uint keycode, bool getcurrent) { if (keycode >= sizeof(_scancode) / sizeof(_scancode[0])) return false; tjs_uint8 code = _scancode[keycode]; _scancode[keycode] &= 1; return code & (getcurrent ? 1 : 0x10); } void TVPForceSwapBuffer(); void TVPProcessInputEvents(); void TVPControlAdDialog(int adType, int arg1, int arg2); // void TVPShowIME(int x, int y, int w, int h); // void TVPHideIME(); int TVPDrawSceneOnce(int interval) { static tjs_uint64 lastTick = TVPGetRoughTickCount32(); tjs_uint64 curTick = TVPGetRoughTickCount32(); int remain = interval - (curTick - lastTick); if (remain <= 0) { if (_postUpdate) _postUpdate(); Director* director = Director::getInstance(); director->drawScene(/*true*/); TVPForceSwapBuffer(); lastTick = curTick; return 0; } else { return remain; } } struct tTVPCursor { Node *RootNode; Action *Anim = nullptr; }; #pragma pack(push) #pragma pack(1) enum eIconType { eIconTypeNone, eIconTypeICO, eIconTypeCUR }; struct ICONDIR { uint16_t idReserved; // must be 0 uint16_t idType; //eIconType uint16_t idCount; }; struct ICODIREntry { uint8_t bWidth; // 0 -> 256 uint8_t bHeight; // 0 -> 256 uint8_t bColorCount; uint8_t bReserved; union { struct { uint16_t wPlanes; uint16_t wBitCount; }; struct { uint16_t wHotSpotX; uint16_t wHotSpotY; }; }; uint32_t dwBytesInRes; uint32_t dwImageOffset; }; #pragma pack(pop) Sprite *TVPLoadCursorCUR(tTJSBinaryStream *pStream) { ICONDIR header; pStream->ReadBuffer(&header, sizeof(header)); if ((header.idReserved != 0) || (header.idType != eIconTypeCUR) || (header.idCount == 0)) { return nullptr; } std::vector cur_dir; cur_dir.resize(header.idCount); pStream->ReadBuffer(&cur_dir[0], sizeof(ICODIREntry)* header.idCount); ICODIREntry bestentry = { 0 }; for (int i = 0; i < cur_dir.size(); ++i) { const ICODIREntry &entry = cur_dir[i]; if (entry.bHeight > bestentry.bHeight) bestentry = entry; } cur_dir.clear(); cur_dir.emplace_back(bestentry); for (int i = 0; i < cur_dir.size(); ++i) { const ICODIREntry &entry = cur_dir[i]; int bWidth = entry.bWidth; int bHeight = entry.bHeight; int bColorCount = entry.bColorCount; if (!bWidth) bWidth = 256; if (!bHeight) bHeight = 256; if (!bColorCount) bColorCount = 256; pStream->SetPosition(entry.dwImageOffset); TVPBITMAPINFOHEADER bmhdr; pStream->ReadBuffer(&bmhdr, sizeof(bmhdr)); if (bmhdr.biSize != 40) continue; if (bmhdr.biCompression) continue; int bmpPitch, pad; switch (bmhdr.biBitCount) { case 1: bmpPitch = (bmhdr.biWidth + 7) >> 3; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); break; case 4: bmpPitch = (bmhdr.biWidth + 1) >> 1; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); break; case 8: bmpPitch = bmhdr.biWidth; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); break; case 32: break; default: continue; } bmhdr.biHeight /= 2; std::vector pixbuf; pixbuf.resize(bmhdr.biWidth * bmhdr.biHeight * 4); tjs_uint32 palette[256]; if (bmhdr.biBitCount <= 8) { if (bmhdr.biClrUsed == 0) bmhdr.biClrUsed = 1 << bmhdr.biBitCount; for (unsigned int j = 0; j < bmhdr.biClrUsed; ++j) { union { tjs_uint32 u32; tjs_uint8 u8[4]; } clr, rclr; pStream->ReadBuffer(&clr.u32, 4); rclr.u8[0] = clr.u8[2]; rclr.u8[1] = clr.u8[1]; rclr.u8[2] = clr.u8[0]; rclr.u8[3] = clr.u8[3]; palette[j] = rclr.u32; } } /* Read the surface pixels. Note that the bmp image is upside down */ int pitch = bmhdr.biWidth * 4; tjs_uint8 *bits = (tjs_uint8 *)&pixbuf[0] + (bmhdr.biHeight * pitch); switch (bmhdr.biBitCount) { case 1: case 4: case 8: while (bits > (tjs_uint8 *)&pixbuf[0]) { bits -= pitch; tjs_uint8 pixel = 0; int shift = (8 - bmhdr.biBitCount); for (i = 0; i < bmhdr.biWidth; ++i) { if (i % (8 / bmhdr.biBitCount) == 0) { pStream->ReadBuffer(&pixel, 1); } *((tjs_uint32 *)bits + i) = (palette[pixel >> shift]); pixel <<= bmhdr.biBitCount; } } /* Skip padding bytes, ugh */ if (pad) { tjs_uint8 padbyte; for (i = 0; i < pad; ++i) { pStream->ReadBuffer(&padbyte, 1); } } break; case 32: bmpPitch = bmhdr.biWidth * 4; pad = 0; while (bits > (tjs_uint8 *) &pixbuf[0]) { bits -= pitch; pStream->ReadBuffer(bits, pitch); } break; } /* Read the mask pixels. Note that the bmp image is upside down */ bits = (tjs_uint8 *)&pixbuf[0] + (bmhdr.biHeight * pitch); bmpPitch = (bmhdr.biWidth + 7) >> 3; pad = (((bmpPitch) % 4) ? (4 - ((bmpPitch) % 4)) : 0); while (bits > (tjs_uint8 *)&pixbuf[0]) { tjs_uint8 pixel = 0; int shift = (8 - 1); bits -= pitch; for (i = 0; i < bmhdr.biWidth; ++i) { if (i % (8 / 1) == 0) { pStream->ReadBuffer(&pixel, 1); } *((tjs_uint32 *)bits + i) |= ((pixel >> shift) ? 0 : 0xFF000000); pixel <<= 1; } /* Skip padding bytes, ugh */ if (pad) { tjs_uint8 padbyte; for (i = 0; i < pad; ++i) { pStream->ReadBuffer(&padbyte, 1); } } } cocos2d::Image *surface = new cocos2d::Image; surface->initWithRawData(&pixbuf[0], pixbuf.size(), bmhdr.biWidth, bmhdr.biHeight, 0, false) ; //Texture2D::PixelFormat::RGBA8888, false); Texture2D *tex = new Texture2D(); tex->initWithImage(surface); Sprite *sprite = Sprite::create(); sprite->setTexture(tex); sprite->setTextureRect(Rect(0, 0, bmhdr.biWidth, bmhdr.biHeight)); sprite->setAnchorPoint(Vec2((float)entry.wHotSpotX / bmhdr.biWidth, 1.f - (float)entry.wHotSpotY / bmhdr.biHeight)); float scale = sqrtf(Device::getDPI() / 150.f); sprite->setScale(scale); return sprite; // only the first one } return nullptr; } tTVPCursor *TVPLoadCursorANI(tTJSBinaryStream *pStream) { // TODO http://www.gdgsoft.com/anituner/help/aniformat.htm return nullptr; } tTVPCursor *TVPLoadCursor(tTJSBinaryStream *stream) { if (!stream) return nullptr; unsigned char sig[4]; stream->Read(sig, 4); stream->SetPosition(0); if (memcmp(sig, "RIFF", 4) == 0) { // ani format return TVPLoadCursorANI(stream); } else { // cur format Sprite * cur = TVPLoadCursorCUR(stream); tTVPCursor * ret = nullptr; if (cur) { ret = new tTVPCursor; ret->RootNode = cur; cur->retain(); } return ret; } } tTVPMouseButton TVP_TMouseButton_To_tTVPMouseButton(int button) { return (tTVPMouseButton)button; } // instead of TTVPWindowForm class TVPWindowLayer : public cocos2d::extension::ScrollView, public iWindowLayer { typedef cocos2d::extension::ScrollView inherit; tTJSNI_Window *TJSNativeInstance; tjs_int ActualZoomDenom; // Zooming factor denominator (actual) tjs_int ActualZoomNumer; // Zooming factor numerator (actual) Sprite *DrawSprite = nullptr; Node *PrimaryLayerArea = nullptr; int LayerWidth = 0, LayerHeight = 0; //iTVPTexture2D *DrawTexture = nullptr; TVPWindowLayer *_prevWindow, *_nextWindow; friend class TVPWindowManagerOverlay; friend class TVPMainScene; int _LastMouseX = 0, _LastMouseY = 0; std::string _caption; // std::map _AllOverlay; float _drawSpriteScaleX = 1.0f, _drawSpriteScaleY = 1.0f; float _drawTextureScaleX = 1.f, _drawTextureScaleY = 1.f; bool UseMouseKey = false, MouseLeftButtonEmulatedPushed = false, MouseRightButtonEmulatedPushed = false; bool LastMouseMoved = false, Visible = false; tjs_uint32 LastMouseKeyTick = 0; tjs_int MouseKeyXAccel = 0; tjs_int MouseKeyYAccel = 0; int LastMouseDownX = 0, LastMouseDownY = 0; VelocityTrackers TouchVelocityTracker; VelocityTracker MouseVelocityTracker; static const int TVP_MOUSE_MAX_ACCEL = 30; static const int TVP_MOUSE_SHIFT_ACCEL = 40; static const int TVP_TOOLTIP_SHOW_DELAY = 500; public: TVPWindowLayer(tTJSNI_Window *w) : TJSNativeInstance(w) { _nextWindow = nullptr; _prevWindow = _lastWindowLayer; _lastWindowLayer = this; ActualZoomDenom = 1; ActualZoomNumer = 1; if (_prevWindow) { _prevWindow->_nextWindow = this; } } virtual ~TVPWindowLayer() { if (_lastWindowLayer == this) _lastWindowLayer = _prevWindow; if (_nextWindow) _nextWindow->_prevWindow = _prevWindow; if (_prevWindow) _prevWindow->_nextWindow = _nextWindow; if (_currentWindowLayer == this) { TVPWindowLayer *anotherWin = _lastWindowLayer; while (anotherWin && !anotherWin->isVisible()) { anotherWin = anotherWin->_prevWindow; } if (anotherWin && anotherWin->isVisible()) { anotherWin->setPosition(0, 0); //anotherWin->setVisible(true); } _currentWindowLayer = anotherWin; } } bool init() { bool ret = inherit::init(); setClippingToBounds(false); DrawSprite = Sprite::create(); DrawSprite->setAnchorPoint(Vec2(0, 1)); // top-left PrimaryLayerArea = Node::create(); addChild(PrimaryLayerArea); PrimaryLayerArea->addChild(DrawSprite); setAnchorPoint(Size::ZERO); EventListenerMouse *evmouse = EventListenerMouse::create(); evmouse->onMouseScroll = std::bind(&TVPWindowLayer::onMouseScroll, this, std::placeholders::_1); evmouse->onMouseDown = std::bind(&TVPWindowLayer::onMouseDownEvent, this, std::placeholders::_1); evmouse->onMouseUp = std::bind(&TVPWindowLayer::onMouseUpEvent, this, std::placeholders::_1); evmouse->onMouseMove = std::bind(&TVPWindowLayer::onMouseMoveEvent, this, std::placeholders::_1); _eventDispatcher->addEventListenerWithSceneGraphPriority(evmouse, this); setTouchEnabled(false); //_touchListener->setSwallowTouches(true); setVisible(false); return ret; } static TVPWindowLayer *create(tTJSNI_Window *w) { TVPWindowLayer *ret = new TVPWindowLayer (w); ret->init(); ret->autorelease(); return ret; } virtual cocos2d::Node *GetPrimaryArea() override { return PrimaryLayerArea; } virtual Vec2 minContainerOffset() { // override { const Size &size = getContentSize(); float scale = _container->getScale(); Vec2 ret(_viewSize.width - size.width * scale * _drawSpriteScaleX, _viewSize.height - size.height * scale * _drawSpriteScaleY); if (ret.x > 0) { ret.x /= 2; } else { //ret.x = 0; } if (ret.y > 0) { ret.y /= 2; } else { //ret.y = 0; } return ret; } virtual Vec2 maxContainerOffset(){ // override { // bottom-left const Size &size = getContentSize(); float scale = _container->getScale(); Vec2 ret(_viewSize.width - size.width * scale * _drawSpriteScaleX, _viewSize.height - size.height * scale * _drawSpriteScaleY); if (ret.x > 0) { ret.x /= 2; } else { ret.x = 0; } if (ret.y > 0) { ret.y /= 2; } else { ret.y = 0; } return ret; } void onMouseDownEvent(Event *_e) { EventMouse *e = static_cast(_e); switch (e->getMouseButton()) { case EventMouse::MouseButton::BUTTON_RIGHT: _mouseBtn = mbRight; onMouseDown(e->getLocation()); break; case EventMouse::MouseButton::BUTTON_MIDDLE: _mouseBtn = mbMiddle; onMouseDown(e->getLocation()); break; default: break; } } void onMouseUpEvent(Event *_e) { EventMouse *e = static_cast(_e); switch (e->getMouseButton()) { case EventMouse::MouseButton::BUTTON_RIGHT: _mouseBtn = mbRight; onMouseUp(e->getLocation()); break; case EventMouse::MouseButton::BUTTON_MIDDLE: _mouseBtn = mbMiddle; onMouseUp(e->getLocation()); break; default: break; } } void onMouseMoveEvent(Event *_e) { if (!_virutalMouseMode && _currentWindowLayer == this && !_touchMoved) { EventMouse *e = static_cast(_e); Vec2 pt(e->getCursorX(), e->getCursorY()); onMouseMove(pt); } } void onMouseScroll(Event *_e) { EventMouse *e = static_cast(_e); if (!_windowMgrOverlay) { Vec2 nsp = PrimaryLayerArea->convertToNodeSpace(e->getLocation()); int X = nsp.x, Y = PrimaryLayerArea->getContentSize().height - nsp.y; TJSNativeInstance->OnMouseWheel(TVPGetCurrentShiftKeyState(), e->getScrollY() > 0 ? -120 : 120, X, Y); return; } float scale = getZoomScale(); if (e->getScrollY() > 0) { scale *= 0.9f; } else { scale *= 1.1f; } setZoomScale(scale); setContentOffset(getContentOffset()); updateInset(); relocateContainer(false); } virtual bool onTouchBegan(Touch *touch, Event *unused_event) override { if (_windowMgrOverlay) return inherit::onTouchBegan(touch, unused_event); if (std::find(_touches.begin(), _touches.end(), touch) == _touches.end()) { _touches.push_back(touch); } switch (_touches.size()) { case 1: _touchPoint = touch->getLocation(); _touchMoved = false; _touchLength = 0.0f; _touchBeginTick = TVPGetRoughTickCount32(); _mouseBtn = ::mbLeft; break; case 2: _mouseBtn = ::mbRight; _touchPoint = (_touchPoint + touch->getLocation()) / 2; break; case 3: _mouseBtn = ::mbMiddle; //_touchPoint = (_touchPoint + touch->getLocation()) / 2; default: break; } return true; } virtual void onTouchMoved(Touch* touch, Event* unused_event) override { if (_windowMgrOverlay) return inherit::onTouchMoved(touch, unused_event); if (TJSNativeInstance) { if (_touches.size() == 1) { if (!_touchMoved && (TVPGetRoughTickCount32() - _touchBeginTick > 150 || _touchPoint.getDistanceSq(touch->getLocation()) > _touchMoveThresholdSq)) { Vec2 nsp = PrimaryLayerArea->convertToNodeSpace(_touchPoint); _LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y; TVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState())); _scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] = 0x11; TVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState())); _touchMoved = true; } else if (_touchMoved) { Vec2 nsp = PrimaryLayerArea->convertTouchToNodeSpace(touch); _LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y; TVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState()), TVP_EPT_DISCARDABLE); int pos = (_LastMouseY << 16) + _LastMouseX; TVPPushEnvironNoise(&pos, sizeof(pos)); } } } } virtual void onTouchEnded(Touch *touch, Event *unused_event) override { if (_windowMgrOverlay) return inherit::onTouchEnded(touch, unused_event); auto touchIter = std::find(_touches.begin(), _touches.end(), touch); if (touchIter != _touches.end()) { if (_touches.size() == 1) { if (TJSNativeInstance) { Vec2 nsp = PrimaryLayerArea->convertTouchToNodeSpace(touch); _LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y; if (!_touchMoved) { TVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState())); Vec2 nsp = PrimaryLayerArea->convertToNodeSpace(_touchPoint); TVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, nsp.x, PrimaryLayerArea->getContentSize().height - nsp.y, _mouseBtn, TVPGetCurrentShiftKeyState())); TVPPostInputEvent(new tTVPOnClickInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY)); } _scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] = 0x10; TVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState())); } } _touches.erase(touchIter); } if (_touches.size() == 0) { _dragging = false; _touchMoved = false; _scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] &= 0x10; } } virtual void onTouchCancelled(Touch *touch, Event *unused_event) override { if (_windowMgrOverlay) return inherit::onTouchCancelled(touch, unused_event); auto touchIter = std::find(_touches.begin(), _touches.end(), touch); if (touchIter != _touches.end()) { _touches.erase(touchIter); } if (_touches.size() == 0) { _dragging = false; _touchMoved = false; if (TJSNativeInstance) { Vec2 nsp = PrimaryLayerArea->convertTouchToNodeSpace(touch); _LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y; TVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState())); } } } void onMouseDown(const Vec2 &pt) { Vec2 nsp = PrimaryLayerArea->convertToNodeSpace(pt); _LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y; _scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] = 0x11; TVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState())); } void onMouseUp(const Vec2 &pt) { Vec2 nsp = PrimaryLayerArea->convertToNodeSpace(pt); _LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y; _scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] &= 0x10; TVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState())); } void onMouseMove(const Vec2 &pt) { Vec2 nsp = PrimaryLayerArea->convertToNodeSpace(pt); _LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y; TVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState()), TVP_EPT_DISCARDABLE); int pos = (_LastMouseY << 16) + _LastMouseX; TVPPushEnvironNoise(&pos, sizeof(pos)); } void onMouseClick(const Vec2 &pt) { Vec2 nsp = PrimaryLayerArea->convertToNodeSpace(pt); _LastMouseX = nsp.x, _LastMouseY = PrimaryLayerArea->getContentSize().height - nsp.y; TVPPostInputEvent(new tTVPOnMouseMoveInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, TVPGetCurrentShiftKeyState()), TVP_EPT_DISCARDABLE); _scancode[TVPConvertMouseBtnToVKCode(_mouseBtn)] = 0x10; TVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState())); TVPPostInputEvent(new tTVPOnClickInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY)); TVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, _LastMouseX, _LastMouseY, _mouseBtn, TVPGetCurrentShiftKeyState())); } virtual void SetPaintBoxSize(tjs_int w, tjs_int h) { LayerWidth = w; LayerHeight = h; RecalcPaintBox(); } virtual bool GetFormEnabled() { return isVisible(); } virtual void SetDefaultMouseCursor() { ; } virtual void GetCursorPos(tjs_int &x, tjs_int &y) { x = _LastMouseX; y = _LastMouseY; } virtual void SetCursorPos(tjs_int x, tjs_int y) { Vec2 worldPt = PrimaryLayerArea->convertToWorldSpace(Vec2(x, PrimaryLayerArea->getContentSize().height - y)); Vec2 pt = getParent()->convertToNodeSpace(worldPt); _LastMouseX = pt.x; _LastMouseY = pt.y; if (_mouseCursor) { _mouseCursor->setPosition(pt); _refadeMouseCursor(); } } virtual void SetHintText(const ttstr &text) { } tjs_int _textInputPosY; virtual void SetAttentionPoint(tjs_int left, tjs_int top, const struct tTVPFont * font) override { _textInputPosY = top; } virtual void SetImeMode(tTVPImeMode mode) { switch (mode) { case ::imDisable: case ::imClose: #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID TVPHideIME(); #else //#ifdef _MSC_VER TVPMainScene::GetInstance()->detachWithIME(); #endif break; case ::imOpen: //TVPMainScene::GetInstance()->attachWithIME(); //break; default: #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID { Size screenSize = cocos2d::Director::getInstance()->getOpenGLView()->getFrameSize(); TVPShowIME(0, _textInputPosY, screenSize.width, screenSize.height / 4); } #else //#ifdef _MSC_VER TVPMainScene::GetInstance()->attachWithIME(); #endif break; } } virtual void ZoomRectangle( tjs_int & left, tjs_int & top, tjs_int & right, tjs_int & bottom) { left = tjs_int64(left) * ActualZoomNumer / ActualZoomDenom; top = tjs_int64(top) * ActualZoomNumer / ActualZoomDenom; right = tjs_int64(right) * ActualZoomNumer / ActualZoomDenom; bottom = tjs_int64(bottom) * ActualZoomNumer / ActualZoomDenom; } virtual void BringToFront() { if (_currentWindowLayer != this) { if (_currentWindowLayer) { const Size &size = _currentWindowLayer->getViewSize(); _currentWindowLayer->setPosition(Vec2(size.width, 0)); _currentWindowLayer->TJSNativeInstance->OnReleaseCapture(); } _currentWindowLayer = this; } } virtual void ShowWindowAsModal() { in_mode_ = true; setVisible(true); BringToFront(); if (_consoleWin) { _consoleWin->removeFromParent(); _consoleWin = nullptr; TVPMainScene::GetInstance()->scheduleUpdate(); cocos2d::Director::getInstance()->purgeCachedData(); TVPControlAdDialog(0x10002, 0, 0); // ensure to close banner ad } Director* director = Director::getInstance(); modal_result_ = 0; while (this == _currentWindowLayer && !modal_result_) { int remain = TVPDrawSceneOnce(30); // 30 fps TVPProcessInputEvents(); // for iOS if (::Application->IsTarminate()) { modal_result_ = mrCancel; } else if (modal_result_ != 0) { break; } else if (remain > 0) { std::this_thread::sleep_for(std::chrono::milliseconds(remain)); } } in_mode_ = false; } virtual bool GetVisible() { return isVisible(); } virtual void SetVisible(bool bVisible) { Visible = bVisible; setVisible(bVisible); if (bVisible) { BringToFront(); } else { if (_currentWindowLayer == this) { _currentWindowLayer = _prevWindow ? _prevWindow : _nextWindow; } } } virtual const char *GetCaption() { return _caption.c_str(); } virtual void SetCaption(const std::string &s) { _caption = s; } void ResetDrawSprite() { if (DrawSprite) { Size size = getContentSize(); float scale = (float)ActualZoomNumer / ActualZoomDenom; #ifdef _DEBUG SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); printf("reset sprite: size=(%f,%f), Numer=%d, Denom=%d Layer=(%d,%d)\n", size.width, size.height, ActualZoomNumer, ActualZoomDenom, LayerWidth, LayerHeight); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); if (!LayerWidth || !LayerHeight) { LayerHeight = LayerHeight; } #endif size = size / scale; //DrawSprite->setTextureRect(Rect(0, 0, size.width, size.height)); DrawSprite->setScale(_drawTextureScaleX, _drawTextureScaleY); DrawSprite->setTextureRect(Rect(0, 0, LayerWidth, LayerHeight)); DrawSprite->setPosition(Vec2(0, size.height)); PrimaryLayerArea->setContentSize(size); PrimaryLayerArea->setScale(scale); } } void RecalcPaintBox() { if (!LayerWidth || !LayerHeight) return; ResetDrawSprite(); Size size = getViewSize(); Size contSize = getContentSize(); float r = size.width / size.height; float R = contSize.width / contSize.height; float scale; Vec2 offset; if (R > r) { scale = size.width / contSize.width; offset.x = 0; offset.y = (size.height - contSize.height * scale) / 2; } else { scale = size.height / contSize.height; offset.x = (size.width - contSize.width * scale) / 2; offset.y = 0; } setMinScale(scale); setMaxScale(scale * 2); setZoomScale(scale); setContentOffset(offset); updateInset(); } virtual void SetWidth(tjs_int w) { Size size = getContentSize(); size.width = w; setContentSize(size); RecalcPaintBox(); } virtual void SetHeight(tjs_int h) { Size size = getContentSize(); size.height = h; setContentSize(size); RecalcPaintBox(); } virtual void SetSize(tjs_int w, tjs_int h) { setContentSize(Size(w,h)); RecalcPaintBox(); } virtual void GetSize(tjs_int &w, tjs_int &h) { Size size = getContentSize(); w = size.width; h = size.height; } virtual void GetWinSize(tjs_int &w, tjs_int &h) { Size size = getViewSize(); w = size.width; h = size.height; } virtual tjs_int GetWidth() const override { return getContentSize().width; } virtual tjs_int GetHeight() const override { return getContentSize().height; } virtual void SetZoom(tjs_int numer, tjs_int denom) { AdjustNumerAndDenom(numer, denom); ZoomNumer = numer; ZoomDenom = denom; ActualZoomDenom = denom; ActualZoomNumer = numer; RecalcPaintBox(); } virtual void UpdateDrawBuffer(iTVPTexture2D *tex) { if (!tex) return; // iTVPRenderManager *mgr = TVPGetRenderManager(); // if (!mgr->IsSoftware()) { // static iTVPRenderMethod *method = TVPGetRenderManager()->GetRenderMethod("CopyOpaqueImage"); // Size size = DrawSprite->getContentSize(); // tTVPRect rctar(0, 0, size.width, size.height); // if (!DrawTexture) { // DrawTexture = mgr->CreateTexture2D(nullptr, 0, size.width, size.height, TVPTextureFormat::RGBA); // } else { // DrawTexture->SetSize(size.width, size.height); // } // std::pair src_tex[] = { // std::pair(tex, rctar) // }; // mgr->OperateRect(method, DrawTexture, nullptr, rctar, src_tex); // tex = DrawTexture; // } Texture2D *tex2d = DrawSprite->getTexture(); Texture2D *newtex = tex->GetAdapterTexture(tex2d); if (tex2d != newtex) { DrawSprite->setTexture(newtex); float sw, sh; tex->GetScale(_drawTextureScaleX, _drawTextureScaleY); if (_drawTextureScaleX == 1.f) sw = LayerWidth;// tex->GetWidth(); else { sw = tex->GetInternalWidth() * ((float)LayerWidth / tex->GetWidth()); _drawTextureScaleX = 1 / _drawTextureScaleX; } if (_drawTextureScaleY == 1.f) sh = LayerHeight;// tex->GetHeight(); else { sh = tex->GetInternalHeight()* ((float)LayerHeight / tex->GetHeight()); _drawTextureScaleY = 1 / _drawTextureScaleY; } DrawSprite->setTextureRect(Rect(0, 0, sw, sh)); DrawSprite->setBlendFunc(BlendFunc::DISABLE); ResetDrawSprite(); } } tTJSNI_Window* GetWindow() { return TJSNativeInstance; } #if 0 virtual void AddOverlay(tTJSNI_BaseVideoOverlay *ovl) { if (_AllOverlay.find(ovl) != _AllOverlay.end()) return; Sprite *pSprite = Sprite::create(); cocos2d::Texture2D* pTex = new cocos2d::Texture2D; pSprite->setTexture(pTex); //pSprite->setFlippedY(true); pSprite->setAnchorPoint(Vec2(0, 1)); PrimaryLayerArea->addChild(pSprite); _AllOverlay[ovl] = pSprite; } virtual void RemoveOverlay(tTJSNI_BaseVideoOverlay *ovl) { auto it = _AllOverlay.find(ovl); if (it == _AllOverlay.end()) return; it->second->removeFromParent(); _AllOverlay.erase(it); } virtual void UpdateOverlay() { for (auto it : _AllOverlay) { Sprite *pSprite = it.second; if (!it.first->GetVisible()) { pSprite->setVisible(false); continue; } else { pSprite->setVisible(true); } tjs_int w, h; if (!it.first->GetVideoSize(w, h)) continue; Size videoSize(w, h); cocos2d::Texture2D *pTex = pSprite->getTexture(); const Size &size = pTex->getContentSize(); std::function drawer; if (size.width != videoSize.width || size.height != videoSize.height) { if (size.width < videoSize.width || size.height < videoSize.height) { drawer = [pTex, pSprite](const void* data, int pitch, int w, int h) { pTex->initWithData(data, pitch * h, cocos2d::Texture2D::PixelFormat::RGBA8888, w, h, cocos2d::Size::ZERO); pSprite->setTextureRect(Rect(0, 0, w, h)); }; } else { pSprite->setTextureRect(Rect(0, 0, videoSize.width, videoSize.height)); } } if (!drawer) { drawer = [pTex](const void* data, int pitch, int w, int h) { pTex->updateWithData(data, 0, 0, w, h); }; } if (!it.first->DrawToTexture(drawer)) continue; const tTVPRect & rc = it.first->GetBounds(); float scaleX = rc.get_width() / videoSize.width; float scaleY = rc.get_height() / videoSize.height; if (scaleX != pSprite->getScaleX()) pSprite->setScaleX(scaleX); if(scaleY != pSprite->getScaleY()) pSprite->setScaleY(scaleY); Vec2 pos = pSprite->getPosition(); int top = PrimaryLayerArea->getContentSize().height - rc.top; if ((int)pos.x != rc.left || (int)pos.y != top) { pSprite->setPosition(rc.left, top); } } } #endif void toogleFillScale() { float scaleX = PrimaryLayerArea->getScaleX(); float scaleY = PrimaryLayerArea->getScaleY(); const Size &drawSize = PrimaryLayerArea->getContentSize(); Size viewSize = getViewSize(); float R = viewSize.width / viewSize.height; float r = drawSize.width / drawSize.height; if (fabs(R - r) < 0.01) { return; // do not fill border if screen ratio is almost the same } if (scaleX == scaleY) { if (R > r) { // border @ left/right _drawSpriteScaleX = R / r; PrimaryLayerArea->setScaleX(scaleY * _drawSpriteScaleX); } else { // border @ top/bottom _drawSpriteScaleY = r / R; PrimaryLayerArea->setScaleY(scaleX * _drawSpriteScaleY); } } else { PrimaryLayerArea->setScale(std::min(scaleX, scaleY)); _drawSpriteScaleX = 1.0f; _drawSpriteScaleY = 1.0f; } updateInset(); setContentOffset(Vec2::ZERO); relocateContainer(false); } virtual void InvalidateClose() override { // closing action by object invalidation; // this will not cause any user confirmation of closing the window. //TVPRemoveWindowLayer(this); this->removeFromParent(); // and delete this } virtual bool GetWindowActive() override { return _currentWindowLayer == this; } int GetMouseButtonState() const { int s = 0; if (TVPGetAsyncKeyState(VK_LBUTTON)) s |= ssLeft; if (TVPGetAsyncKeyState(VK_RBUTTON)) s |= ssRight; if (TVPGetAsyncKeyState(VK_MBUTTON)) s |= ssMiddle; return s; } void OnMouseDown(int button, int shift, int x, int y) { //if (!CanSendPopupHide()) DeliverPopupHide(); MouseVelocityTracker.addMovement(TVPGetRoughTickCount32(), (float)x, (float)y); LastMouseDownX = x; LastMouseDownY = y; if (TJSNativeInstance) { tjs_uint32 s = shift; s |= GetMouseButtonState(); tTVPMouseButton b = TVP_TMouseButton_To_tTVPMouseButton(button); TVPPostInputEvent(new tTVPOnMouseDownInputEvent(TJSNativeInstance, x, y, b, s)); } } void OnMouseClick(int button, int shift, int x, int y) { // fire click event if (TJSNativeInstance) { TVPPostInputEvent(new tTVPOnClickInputEvent(TJSNativeInstance, LastMouseDownX, LastMouseDownY)); } } void GenerateMouseEvent(bool fl, bool fr, bool fu, bool fd) { if (!fl && !fr && !fu && !fd) { if (TVPGetRoughTickCount32() - 45 < LastMouseKeyTick) return; } bool shift = 0 != (TVPGetKeyMouseAsyncState(VK_SHIFT, true)); bool left = fl || TVPGetKeyMouseAsyncState(VK_LEFT, true) || TVPGetJoyPadAsyncState(VK_PADLEFT, true); bool right = fr || TVPGetKeyMouseAsyncState(VK_RIGHT, true) || TVPGetJoyPadAsyncState(VK_PADRIGHT, true); bool up = fu || TVPGetKeyMouseAsyncState(VK_UP, true) || TVPGetJoyPadAsyncState(VK_PADUP, true); bool down = fd || TVPGetKeyMouseAsyncState(VK_DOWN, true) || TVPGetJoyPadAsyncState(VK_PADDOWN, true); uint32_t flags = 0; if (left || right || up || down) flags |= /*MOUSEEVENTF_MOVE*/1; if (!right && !left && !up && !down) { LastMouseMoved = false; MouseKeyXAccel = MouseKeyYAccel = 0; } if (!shift) { if (!right && left && MouseKeyXAccel > 0) MouseKeyXAccel = -0; if (!left && right && MouseKeyXAccel < 0) MouseKeyXAccel = 0; if (!down && up && MouseKeyYAccel > 0) MouseKeyYAccel = -0; if (!up && down && MouseKeyYAccel < 0) MouseKeyYAccel = 0; } else { if (left) MouseKeyXAccel = -TVP_MOUSE_SHIFT_ACCEL; if (right) MouseKeyXAccel = TVP_MOUSE_SHIFT_ACCEL; if (up) MouseKeyYAccel = -TVP_MOUSE_SHIFT_ACCEL; if (down) MouseKeyYAccel = TVP_MOUSE_SHIFT_ACCEL; } if (right || left || up || down) { if (left) if (MouseKeyXAccel > -TVP_MOUSE_MAX_ACCEL) MouseKeyXAccel = MouseKeyXAccel ? MouseKeyXAccel - 2 : -2; if (right) if (MouseKeyXAccel < TVP_MOUSE_MAX_ACCEL) MouseKeyXAccel = MouseKeyXAccel ? MouseKeyXAccel + 2 : +2; if (!left && !right) { if (MouseKeyXAccel > 0) MouseKeyXAccel--; else if (MouseKeyXAccel < 0) MouseKeyXAccel++; } if (up) if (MouseKeyYAccel > -TVP_MOUSE_MAX_ACCEL) MouseKeyYAccel = MouseKeyYAccel ? MouseKeyYAccel - 2 : -2; if (down) if (MouseKeyYAccel < TVP_MOUSE_MAX_ACCEL) MouseKeyYAccel = MouseKeyYAccel ? MouseKeyYAccel + 2 : +2; if (!up && !down) { if (MouseKeyYAccel > 0) MouseKeyYAccel--; else if (MouseKeyYAccel < 0) MouseKeyYAccel++; } } if (flags) { _LastMouseX += MouseKeyXAccel >> 1; _LastMouseY += MouseKeyYAccel >> 1; LastMouseMoved = true; } LastMouseKeyTick = TVPGetRoughTickCount32(); } virtual void InternalKeyDown(tjs_uint16 key, tjs_uint32 shift) override { tjs_uint32 tick = TVPGetRoughTickCount32(); TVPPushEnvironNoise(&tick, sizeof(tick)); TVPPushEnvironNoise(&key, sizeof(key)); TVPPushEnvironNoise(&shift, sizeof(shift)); if (UseMouseKey) { if (key == VK_RETURN || key == VK_SPACE || key == VK_ESCAPE || key == VK_PAD1 || key == VK_PAD2) { Vec2 p(_LastMouseX, _LastMouseY); Size size = PrimaryLayerArea->getContentSize(); if (p.x >= 0 && p.y >= 0 && p.x < size.width && p.y < size.height) { if (key == VK_RETURN || key == VK_SPACE || key == VK_PAD1) { MouseLeftButtonEmulatedPushed = true; OnMouseDown(mbLeft, 0, p.x, p.y); } if (key == VK_ESCAPE || key == VK_PAD2) { MouseRightButtonEmulatedPushed = true; OnMouseDown(mbLeft, 0, p.x, p.y); } } return; } switch (key) { case VK_LEFT: case VK_PADLEFT: if (MouseKeyXAccel == 0 && MouseKeyYAccel == 0) { GenerateMouseEvent(true, false, false, false); LastMouseKeyTick = TVPGetRoughTickCount32() + 100; } return; case VK_RIGHT: case VK_PADRIGHT: if (MouseKeyXAccel == 0 && MouseKeyYAccel == 0) { GenerateMouseEvent(false, true, false, false); LastMouseKeyTick = TVPGetRoughTickCount32() + 100; } return; case VK_UP: case VK_PADUP: if (MouseKeyXAccel == 0 && MouseKeyYAccel == 0) { GenerateMouseEvent(false, false, true, false); LastMouseKeyTick = TVPGetRoughTickCount32() + 100; } return; case VK_DOWN: case VK_PADDOWN: if (MouseKeyXAccel == 0 && MouseKeyYAccel == 0) { GenerateMouseEvent(false, false, false, true); LastMouseKeyTick = TVPGetRoughTickCount32() + 100; } return; } } TVPPostInputEvent(new tTVPOnKeyDownInputEvent(TJSNativeInstance, key, shift)); } void InternalKeyUp(tjs_uint16 key, tjs_uint32 shift) { tjs_uint32 tick = TVPGetRoughTickCount32(); TVPPushEnvironNoise(&tick, sizeof(tick)); TVPPushEnvironNoise(&key, sizeof(key)); TVPPushEnvironNoise(&shift, sizeof(shift)); if (TJSNativeInstance) { if (UseMouseKey /*&& PaintBox*/) { if (key == VK_RETURN || key == VK_SPACE || key == VK_ESCAPE || key == VK_PAD1 || key == VK_PAD2) { Vec2 p(_LastMouseX, _LastMouseY); Size size = PrimaryLayerArea->getContentSize(); if (p.x >= 0 && p.y >= 0 && p.x < size.width && p.y < size.height) { if (key == VK_RETURN || key == VK_SPACE || key == VK_PAD1) { OnMouseClick(mbLeft, 0, p.x, p.y); MouseLeftButtonEmulatedPushed = false; OnMouseUp(mbLeft, 0, p.x, p.y); } if (key == VK_ESCAPE || key == VK_PAD2) { MouseRightButtonEmulatedPushed = false; OnMouseUp(mbRight, 0, p.x, p.y); } } return; } } TVPPostInputEvent(new tTVPOnKeyUpInputEvent(TJSNativeInstance, key, shift)); } } virtual void OnKeyUp(tjs_uint16 vk, int shift) override { tjs_uint32 s = (shift); s |= GetMouseButtonState(); InternalKeyUp(vk, s); } virtual void OnKeyPress(tjs_uint16 vk, int repeat, bool prevkeystate, bool convertkey) override { if (TJSNativeInstance && vk) { if (UseMouseKey && (vk == 0x1b || vk == 13 || vk == 32)) return; // UNICODE ʤΤǤΤޤ޶ɤƤޤ TVPPostInputEvent(new tTVPOnKeyPressInputEvent(TJSNativeInstance, vk)); } } tTVPImeMode LastSetImeMode = ::imDisable; tTVPImeMode DefaultImeMode = ::imDisable; virtual tTVPImeMode GetDefaultImeMode() const override { return DefaultImeMode; } virtual void ResetImeMode() override { SetImeMode(DefaultImeMode); } bool Closing = false, ProgramClosing = false, CanCloseWork = false; bool in_mode_ = false; // is modal int modal_result_ = 0; enum CloseAction { caNone, caHide, caFree, caMinimize }; void OnClose(CloseAction& action) { if (modal_result_ == 0) action = caNone; else action = caHide; if (ProgramClosing) { if (TJSNativeInstance) { if (TJSNativeInstance->IsMainWindow()) { // this is the main window } else { // not the main window action = caFree; } //if (TVPFullScreenedWindow != this) { // if this is not a fullscreened window // SetVisible(false); //} iTJSDispatch2 * obj = TJSNativeInstance->GetOwnerNoAddRef(); TJSNativeInstance->NotifyWindowClose(); obj->Invalidate(0, NULL, NULL, obj); TJSNativeInstance = NULL; SetVisible(false); scheduleOnce([this](float){removeFromParent(); }, 0, "remove"); } } } bool OnCloseQuery() { // closing actions are 3 patterns; // 1. closing action by the user // 2. "close" method // 3. object invalidation if (TVPGetBreathing()) { return false; } // the default event handler will invalidate this object when an onCloseQuery // event reaches the handler. if (TJSNativeInstance && (modal_result_ == 0 || modal_result_ == mrCancel/* mrCancel=when close button is pushed in modal window */)) { iTJSDispatch2 * obj = TJSNativeInstance->GetOwnerNoAddRef(); if (obj) { tTJSVariant arg[1] = { true }; static ttstr eventname(TJS_W("onCloseQuery")); if (!ProgramClosing) { // close action does not happen immediately if (TJSNativeInstance) { TVPPostInputEvent(new tTVPOnCloseInputEvent(TJSNativeInstance)); } Closing = true; // waiting closing... // TVPSystemControl->NotifyCloseClicked(); return false; } else { CanCloseWork = true; TVPPostEvent(obj, obj, eventname, 0, TVP_EPT_IMMEDIATE, 1, arg); TVPDrawSceneOnce(0); // for post event // this event happens immediately // and does not return until done return CanCloseWork; // CanCloseWork is set by the event handler } } else { return true; } } else { return true; } } virtual void Close() override { // closing action by "close" method if (Closing) return; // already waiting closing... ProgramClosing = true; try { //tTVPWindow::Close(); if (in_mode_) { modal_result_ = mrCancel; } else if (OnCloseQuery()) { CloseAction action = caFree; OnClose(action); switch (action) { case caNone: break; case caHide: Hide(); break; case caMinimize: //::ShowWindow(GetHandle(), SW_MINIMIZE); break; case caFree: default: scheduleOnce([this](float){ removeFromParent(); }, 0, "Close"); //::PostMessage(GetHandle(), TVP_EV_WINDOW_RELEASE, 0, 0); break; } } } catch (...) { ProgramClosing = false; throw; } ProgramClosing = false; } virtual void OnCloseQueryCalled(bool b) { // closing is allowed by onCloseQuery event handler if (!ProgramClosing) { // closing action by the user if (b) { if (in_mode_) modal_result_ = 1; // when modal else SetVisible(false); // just hide Closing = false; if (TJSNativeInstance) { if (TJSNativeInstance->IsMainWindow()) { // this is the main window iTJSDispatch2 * obj = TJSNativeInstance->GetOwnerNoAddRef(); obj->Invalidate(0, NULL, NULL, obj); // TJSNativeInstance = NULL; // ζAǤϼȤthisƤ뤿ᡢЩ`إƤϤʤ } } else { delete this; } } else { Closing = false; } } else { // closing action by the program CanCloseWork = b; } } virtual void UpdateWindow(tTVPUpdateType type) { if (TJSNativeInstance) { tTVPRect r; r.left = 0; r.top = 0; r.right = LayerWidth; r.bottom = LayerHeight; TJSNativeInstance->NotifyWindowExposureToLayer(r); TVPDeliverWindowUpdateEvents(); } } virtual void SetVisibleFromScript(bool b) { SetVisible(b); // if (Focusable) { // SetVisible(b); // } else { // if (!GetVisible()) { // // just show window, not activate // SetWindowPos(GetHandle(), GetStayOnTop() ? HWND_TOPMOST : HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); // SetVisible(true); // } else { // SetVisible(false); // } // } } virtual void SetUseMouseKey(bool b) { UseMouseKey = b; if (b) { MouseLeftButtonEmulatedPushed = false; MouseRightButtonEmulatedPushed = false; LastMouseKeyTick = TVPGetRoughTickCount32(); } else { if (MouseLeftButtonEmulatedPushed) { MouseLeftButtonEmulatedPushed = false; OnMouseUp(mbLeft, 0, _LastMouseX, _LastMouseY); } if (MouseRightButtonEmulatedPushed) { MouseRightButtonEmulatedPushed = false; OnMouseUp(mbRight, 0, _LastMouseX, _LastMouseY); } } } virtual bool GetUseMouseKey() const { return UseMouseKey; } void OnMouseUp(int button, int shift, int x, int y) { // TranslateWindowToDrawArea(x, y); // ReleaseMouseCapture(); MouseVelocityTracker.addMovement(TVPGetRoughTickCount32(), (float)x, (float)y); if (TJSNativeInstance) { tjs_uint32 s = shift; s |= GetMouseButtonState(); tTVPMouseButton b = TVP_TMouseButton_To_tTVPMouseButton(button); TVPPostInputEvent(new tTVPOnMouseUpInputEvent(TJSNativeInstance, x, y, b, s)); } } virtual void ResetTouchVelocity(tjs_int id) { TouchVelocityTracker.end(id); } virtual void ResetMouseVelocity() { MouseVelocityTracker.clear(); } bool GetMouseVelocity(float& x, float& y, float& speed) const { if (MouseVelocityTracker.getVelocity(x, y)) { speed = hypotf(x, y); return true; } return false; } virtual void TickBeat() override { bool focused = _currentWindowLayer == this; // mouse key if (UseMouseKey && focused) { GenerateMouseEvent(false, false, false, false); } } }; tTJSNI_Window *TVPGetActiveWindow() { if (!_currentWindowLayer) return nullptr; return _currentWindowLayer->GetWindow(); } class TVPWindowManagerOverlay : public iTVPBaseForm { public: static TVPWindowManagerOverlay *create() { TVPWindowManagerOverlay* ret = new TVPWindowManagerOverlay(); ret->autorelease(); ret->initFromFile(nullptr, "ui/WinMgrOverlay.csb", nullptr); return ret; } virtual void rearrangeLayout() { Size sceneSize = TVPMainScene::GetInstance()->getGameNodeSize(); setContentSize(sceneSize); RootNode->setContentSize(sceneSize); ui::Helper::doLayout(RootNode); } virtual void bindBodyController(const NodeMap &allNodes) { _left = static_cast(allNodes.findController("left")); _right = static_cast(allNodes.findController("right")); _ok = static_cast(allNodes.findController("ok")); auto funcUpdate = std::bind(&TVPWindowManagerOverlay::updateButtons, this); _left->addClickEventListener([=](Ref*){ if (!_currentWindowLayer || !_currentWindowLayer->_prevWindow) return; //_currentWindowLayer->_prevWindow->setVisible(true); Size size = _currentWindowLayer->_prevWindow->getViewSize(); _currentWindowLayer->_prevWindow->setPosition(-size.width, 0); _currentWindowLayer->_prevWindow->runAction( EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO))); _currentWindowLayer->runAction(Sequence::createWithTwoActions( EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(size.width, 0))), Sequence::createWithTwoActions(Hide::create(), CallFunc::create(funcUpdate)) )); _currentWindowLayer = _currentWindowLayer->_prevWindow; _left->setVisible(false); _right->setVisible(false); }); _right->addClickEventListener([=](Ref*){ if (!_currentWindowLayer || !_currentWindowLayer->_nextWindow) return; //_currentWindowLayer->_nextWindow->setVisible(true); Size size = _currentWindowLayer->_nextWindow->getViewSize(); _currentWindowLayer->_nextWindow->setPosition(size.width, 0); _currentWindowLayer->_nextWindow->runAction( EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO))); _currentWindowLayer->runAction(Sequence::createWithTwoActions( EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(-size.width, 0))), Sequence::createWithTwoActions(Hide::create(), CallFunc::create(funcUpdate)) )); _currentWindowLayer = _currentWindowLayer->_nextWindow; _left->setVisible(false); _right->setVisible(false); }); _ok->addClickEventListener([](Ref*){ TVPMainScene::GetInstance()->showWindowManagerOverlay(false); }); ui::Button* fillscr = static_cast(allNodes.findController("fillscr")); fillscr->addClickEventListener([](Ref*){ if (!_currentWindowLayer) return; _currentWindowLayer->toogleFillScale(); }); updateButtons(); } void updateButtons() { if (!_currentWindowLayer) return; if (_left) { TVPWindowLayer *pLay = _currentWindowLayer->_prevWindow; while (pLay && !pLay->Visible) { pLay = pLay->_prevWindow; } _left->setVisible(pLay && pLay->Visible); } if (_right) { TVPWindowLayer *pLay = _currentWindowLayer->_nextWindow; while (pLay && !pLay->Visible) { pLay = pLay->_nextWindow; } _right->setVisible(pLay && pLay->Visible); } } private: ui::Button *_left, *_right, *_ok; }; static std::function _func_mask_layer_touchbegan; class MaskLayer : public LayerColor { public: static LayerColor * create(const Color4B& color, GLfloat width, GLfloat height) { LayerColor * layer = LayerColor::create(color, width, height); auto listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); if (_func_mask_layer_touchbegan) { listener->onTouchBegan = _func_mask_layer_touchbegan; _func_mask_layer_touchbegan = nullptr; } else { listener->onTouchBegan = [](Touch *, Event *)->bool{return true; }; } listener->onTouchMoved = [](Touch *, Event *) {}; listener->onTouchEnded = [](Touch *, Event *) {}; listener->onTouchCancelled = [](Touch *, Event *) {}; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, layer); return layer; } }; static TVPMainScene *_instance = nullptr; TVPMainScene* TVPMainScene::GetInstance() { return _instance; } TVPMainScene* TVPMainScene::CreateInstance() { _instance = create(); return _instance; } void TVPMainScene::initialize() { auto glview = cocos2d::Director::getInstance()->getOpenGLView(); Size screenSize = glview->getFrameSize(); Size designSize = glview->getDesignResolutionSize(); ScreenRatio = screenSize.height / designSize.height; designSize.width = designSize.height * screenSize.width / screenSize.height; initWithSize(designSize); addChild(LayerColor::create(Color4B::BLACK, designSize.width, designSize.height)); GameNode = cocos2d::Node::create(); // horizontal //std::swap(designSize.width, designSize.height); GameNode->setContentSize(designSize); UINode = cocos2d::Node::create(); UINode->setContentSize(designSize); UINode->setAnchorPoint(Vec2::ZERO); UINode->setPosition(Vec2::ZERO); UISize = designSize; addChild(UINode, UI_NODE_ORDER); GameNode->setAnchorPoint(Vec2(0, 0)); //GameNode->setRotation(-90); //GameNode->setPosition(getContentSize() / 2); addChild(GameNode, GAME_SCENE_ORDER); EventListenerKeyboard* keylistener = EventListenerKeyboard::create(); keylistener->onKeyPressed = CC_CALLBACK_2(TVPMainScene::onKeyPressed, this); keylistener->onKeyReleased = CC_CALLBACK_2(TVPMainScene::onKeyReleased, this); _eventDispatcher->addEventListenerWithFixedPriority(keylistener, 1); _touchListener = EventListenerTouchOneByOne::create(); _touchListener->onTouchBegan = CC_CALLBACK_2(TVPMainScene::onTouchBegan, this); _touchListener->onTouchMoved = CC_CALLBACK_2(TVPMainScene::onTouchMoved, this); _touchListener->onTouchEnded = CC_CALLBACK_2(TVPMainScene::onTouchEnded, this); _touchListener->onTouchCancelled = CC_CALLBACK_2(TVPMainScene::onTouchCancelled, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(_touchListener, this); EventListenerController *ctrllistener = EventListenerController::create(); ctrllistener->onAxisEvent = CC_CALLBACK_3(TVPMainScene::onAxisEvent, this); ctrllistener->onKeyDown = CC_CALLBACK_3(TVPMainScene::onPadKeyDown, this); ctrllistener->onKeyUp = CC_CALLBACK_3(TVPMainScene::onPadKeyUp, this); ctrllistener->onKeyRepeat = CC_CALLBACK_3(TVPMainScene::onPadKeyRepeat, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(ctrllistener, this); cocos2d::Controller::startDiscoveryController(); // for win32 & iOS } TVPMainScene * TVPMainScene::create() { TVPMainScene * ret = new TVPMainScene; ret->initialize(); ret->autorelease(); _touchMoveThresholdSq = Device::getDPI() / 10; _touchMoveThresholdSq *= _touchMoveThresholdSq; return ret; } void TVPMainScene::pushUIForm(cocos2d::Node *ui, eEnterAni ani) { TVPControlAdDialog(0x10002, 1, 0); int n = UINode->getChildrenCount(); if (ani == eEnterAniNone) { UINode->addChild(ui); } else if (ani == eEnterAniOverFromRight) { if (n > 0) { Size size = UINode->getContentSize(); cocos2d::Node *lastui = UINode->getChildren().back(); lastui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(size.width / -5, 0)))); cocos2d::Node *ColorMask = MaskLayer::create(Color4B(0, 0, 0, 0), size.width, size.height); ColorMask->setPosition(Vec2(-size.width, 0)); ui->addChild(ColorMask); ColorMask->runAction(FadeTo::create(UI_CHANGE_DURATION, 128)); ui->setPosition(size.width, 0); ui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO))); runAction(Sequence::createWithTwoActions(DelayTime::create(UI_CHANGE_DURATION), CallFunc::create([=](){ ColorMask->removeFromParent(); }))); } UINode->addChild(ui); } else if (ani == eEnterFromBottom) { Size size = UINode->getContentSize(); cocos2d::Node *ColorMask = MaskLayer::create(Color4B(0, 0, 0, 0), size.width, size.height); ColorMask->runAction(FadeTo::create(UI_CHANGE_DURATION, 128)); ui->setPositionY(-ui->getContentSize().height); ColorMask->addChild(ui); UINode->addChild(ColorMask); ui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO))); } } void TVPMainScene::popUIForm(cocos2d::Node *form, eLeaveAni ani) { int n = UINode->getChildrenCount(); if (n <= 0) return; if (n == 1) { TVPControlAdDialog(0x10002, 0, 0); } auto children = UINode->getChildren(); if (ani == eLeaveAniNone) { if (n > 1) { Node *lastui = children.at(n - 2); lastui->setPosition(0, 0); } Node *ui = children.back(); if (form) CCAssert(form == ui, "must be the same form"); ui->removeFromParent(); } else if (ani == eLeaveAniLeaveFromLeft) { Node *ui = children.back(); if (form) CCAssert(form == ui, "must be the same form"); Size size = UINode->getContentSize(); if (n > 1) { Node *lastui = children.at(n - 2); lastui->setPosition(size.width / -5, 0); lastui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2::ZERO))); } cocos2d::Node *ColorMask = MaskLayer::create(Color4B(0, 0, 0, 128), size.width, size.height); ColorMask->setPosition(Vec2(-size.width, 0)); ui->addChild(ColorMask); ColorMask->runAction(FadeOut::create(UI_CHANGE_DURATION)); ui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(size.width, 0)))); runAction(Sequence::createWithTwoActions(DelayTime::create(UI_CHANGE_DURATION), CallFunc::create([=](){ ui->removeFromParent(); }))); } else if (ani == eLeaveToBottom) { cocos2d::Node *ColorMask = children.back(); ColorMask->runAction(FadeOut::create(UI_CHANGE_DURATION)); Node *ui = ColorMask->getChildren().at(0); if (form) CCAssert(form == ui, "must be the same form"); ui->runAction(EaseQuadraticActionIn::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(0, -ui->getContentSize().height)))); runAction(Sequence::createWithTwoActions(DelayTime::create(UI_CHANGE_DURATION), CallFunc::create([=](){ ColorMask->removeFromParent(); }))); } } bool TVPMainScene::startupFrom(const std::string &path) { // startup from dir #ifdef _MSC_VER //TVPSetSystemOption("outputlog", "yes"); // TVPSetSystemOption("ogl_dup_target", "yes"); //_set_new_handler(_no_memory_cb_vc); #endif if (!TVPCheckStartupPath(path)) { return false; } IndividualConfigManager *pGlobalCfgMgr = IndividualConfigManager::GetInstance(); pGlobalCfgMgr->UsePreferenceAt(TVPBaseFileSelectorForm::PathSplit(path).first); if (UINode->getChildrenCount()) { popUIForm(nullptr); } if (GlobalConfigManager::GetInstance()->GetValue("keep_screen_alive", true)) { Device::setKeepScreenOn(true); } for (int i = 0; i < sizeof(_keymap) / sizeof(_keymap[0]); ++i) { _keymap[i] = i; } const auto& keymap = pGlobalCfgMgr->GetKeyMap(); for (const auto &it : keymap) { if (!it.second) continue; _keymap[it.first] = _keymap[it.second]; } // if (pGlobalCfgMgr->GetValueBool("rot_screen_180", false)) { // GameNode->setRotation(90); // } scheduleOnce(std::bind(&TVPMainScene::doStartup, this, std::placeholders::_1, path), 0, "startup"); return true; } void TVPMainScene::doStartup(float dt, std::string path) { unschedule("startup"); IndividualConfigManager *pGlobalCfgMgr = IndividualConfigManager::GetInstance(); _consoleWin = TVPConsoleWindow::create(14, nullptr); auto glview = cocos2d::Director::getInstance()->getOpenGLView(); Size screenSize = glview->getFrameSize(); float scale = screenSize.height / getContentSize().height; _consoleWin->setScale(1 / scale); _consoleWin->setContentSize(getContentSize() * scale); _consoleWin->setFontSize(16); GameNode->addChild(_consoleWin, GAME_CONSOLE_ORDER); ::Application->StartApplication(path); // update one frame update(0); //_ResotreGLStatues(); // already in update() GLubyte handlerOpacity = pGlobalCfgMgr->GetValue("menu_handler_opa", 0.15f) * 255; _gameMenu = TVPGameMainMenu::create(handlerOpacity); GameNode->addChild(_gameMenu, GAME_MENU_ORDER); _gameMenu->shrinkWithTime(1); if (_consoleWin) { _consoleWin->removeFromParent(); _consoleWin = nullptr; scheduleUpdate(); cocos2d::Director::getInstance()->purgeCachedData(); TVPControlAdDialog(0x10002, 0, 0); // ensure to close banner ad } TVPWindowLayer *pWin = _lastWindowLayer; while (pWin) { pWin->setVisible(true); pWin = pWin->_prevWindow; } if (pGlobalCfgMgr->GetValue("showfps", false)) { _fpsLabel = cocos2d::Label::createWithTTF("", "DroidSansFallback.ttf", 16); _fpsLabel->setAnchorPoint(Vec2(0, 1)); _fpsLabel->setPosition(Vec2(0, GameNode->getContentSize().height)); _fpsLabel->setColor(Color3B::WHITE); _fpsLabel->enableOutline(Color4B::BLACK, 1); GameNode->addChild(_fpsLabel, GAME_MENU_ORDER); } int fps = pGlobalCfgMgr->GetValue("fps_limit", 60); cocos2d::Director::getInstance()->setAnimationInterval(1.0f / fps); } extern ttstr TVPGetErrorDialogTitle(); void TVPOnError(); tjs_uint TVPGetGraphicCacheTotalBytes(); void TVPMainScene::update(float delta) { ::Application->Run(); // if (_currentWindowLayer) _currentWindowLayer->UpdateOverlay(); iTVPTexture2D::RecycleProcess(); //_ResotreGLStatues(); if (_postUpdate) _postUpdate(); if (_fpsLabel) { unsigned int drawCount; uint64_t vmemsize; TVPGetRenderManager()->GetRenderStat(drawCount, vmemsize); static timeval _lastUpdate; //static int _lastUpdateReq = gettimeofday(&_lastUpdate, nullptr); struct timeval now; gettimeofday(&now, nullptr); float _deltaTime = (now.tv_sec - _lastUpdate.tv_sec) + (now.tv_usec - _lastUpdate.tv_usec) / 1000000.0f; _lastUpdate = now; static float prevDeltaTime = 0.016f; // 60FPS static const float FPS_FILTER = 0.10f; static float _accumDt = 0; static unsigned int prevDrawCount = 0; _accumDt += _deltaTime; float dt = _deltaTime * FPS_FILTER + (1 - FPS_FILTER) * prevDeltaTime; prevDeltaTime = dt; if (drawCount > prevDrawCount) prevDrawCount = drawCount; char buffer[30]; if (_accumDt > 0.1f) { sprintf(buffer, "%.1f (%d draws)", 1 / dt, drawCount); _fpsLabel->setString(buffer); //#ifdef _MSC_VER std::string msg = buffer; msg += "\n"; //sprintf(buffer, "%.2f MB", TVPGetGraphicCacheTotalBytes() / (float)(1024 * 1024)); vmemsize >>= 10; sprintf(buffer, "%d MB(%.2f MB) %d MB\n", TVPGetSelfUsedMemory(), (float)vmemsize / 1024.f, TVPGetSystemFreeMemory()); msg += buffer; _fpsLabel->setString(msg); //#endif _accumDt = 0; prevDrawCount = 0; } } } cocos2d::Size TVPMainScene::getUINodeSize() { return UINode->getContentSize(); } void TVPMainScene::addLayer(TVPWindowLayer* lay) { GameNode->addChild(lay, GAME_SCENE_ORDER); lay->setViewSize(GameNode->getContentSize()); lay->setContentSize(lay->getViewSize()); // if (_currentWindowLayer) { // _currentWindowLayer->setVisible(false); // } // _currentWindowLayer = lay; } void TVPMainScene::rotateUI() { float rot = UINode->getRotation(); if (rot < 1) { UINode->setRotation(90); UINode->setContentSize(Size(UISize.height, UISize.width)); } else { UINode->setRotation(0); UINode->setContentSize(UISize); } for (Node* ui : UINode->getChildren()) { static_cast(ui)->rearrangeLayout(); } } void TVPMainScene::setMaskLayTouchBegain(const std::function &func) { _func_mask_layer_touchbegan = func; } static float _getUIScale() { auto glview = Director::getInstance()->getOpenGLView(); float factor = (glview->getScaleX() + glview->getScaleY()) / 2; factor /= Device::getDPI(); // inch per pixel Size screenSize = glview->getFrameSize(); Size designSize = glview->getDesignResolutionSize(); designSize.width = designSize.height * screenSize.width / screenSize.height; screenSize.width = factor * designSize.width; #ifdef _WIN32 //if (screenSize.width > 3.5433) return 0.35f; // 7 inch @ 16:9 device return 0.35f; #endif // char tmp[128]; // sprintf(tmp, "screenSize.width = %f", (float)screenSize.width); // TVPPrintLog(tmp); // #if CC_PLATFORM_IOS == CC_TARGET_PLATFORM // return /*sqrtf*/(0.0005f / factor) * screenSize.width; // #else return /*sqrtf*/(0.0005f / factor) * screenSize.width; //#endif } float TVPMainScene::getUIScale() { static float uiscale = _getUIScale(); return uiscale; } void TVPMainScene::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event) { Vector& uiChild = UINode->getChildren(); if (!uiChild.empty()) { iTVPBaseForm* uiform = dynamic_cast(uiChild.back()); if (uiform) uiform->onKeyPressed(keyCode, event); return; } switch (keyCode) { case EventKeyboard::KeyCode::KEY_MENU: if (UINode->getChildren().empty()) { if (_gameMenu) _gameMenu->toggle(); } return; break; case EventKeyboard::KeyCode::KEY_BACK: if (!UINode->getChildren().empty()) { return; } if (_gameMenu && !_gameMenu->isShrinked()) { _gameMenu->shrink(); return; } keyCode = EventKeyboard::KeyCode::KEY_ESCAPE; break; #ifdef _DEBUG case EventKeyboard::KeyCode::KEY_PAUSE: GameNode->addChild(DebugViewLayerForm::create()); return; case EventKeyboard::KeyCode::KEY_F12: if (TVPGetCurrentShiftKeyState() & ssShift) { std::vector btns({ "OK", "Cancel" }); ttstr text; tTJSVariant result; if (TVPShowSimpleInputBox(text, "console command", "", btns) == 0) { try { TVPExecuteExpression(text, &result); } catch (...) { ; } } result = text; } break; #endif default: break; } unsigned int code = TVPConvertKeyCodeToVKCode(keyCode); if (!code || code >= 0x200) return; code = _keymap[code]; _scancode[code] = 0x11; if (_currentWindowLayer) { _currentWindowLayer->InternalKeyDown(code, TVPGetCurrentShiftKeyState()); } } void TVPMainScene::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event) { #ifdef _DEBUG if (keyCode == EventKeyboard::KeyCode::KEY_PAUSE) return; #endif if (keyCode == EventKeyboard::KeyCode::KEY_MENU) return; if (keyCode == EventKeyboard::KeyCode::KEY_BACK) keyCode = EventKeyboard::KeyCode::KEY_ESCAPE; if (keyCode == EventKeyboard::KeyCode::KEY_PLAY) { // auto play iTJSDispatch2* global = TVPGetScriptDispatch(); tTJSVariant var; if (global->PropGet(0, TJS_W("kag"), nullptr, &var, global) == TJS_S_OK && var.Type() == tvtObject) { iTJSDispatch2* kag = var.AsObjectNoAddRef(); if (kag->PropGet(0, TJS_W("autoMode"), nullptr, &var, kag) == TJS_S_OK) { if (var.operator bool()) { if (kag->PropGet(0, TJS_W("cancelAutoMode"), nullptr, &var, kag) == TJS_S_OK && var.Type() == tvtObject) { iTJSDispatch2* fn = var.AsObjectNoAddRef(); if (fn->IsInstanceOf(0, 0, 0, TJS_W("Function"), fn)) { tTJSVariant *args = nullptr; fn->FuncCall(0, nullptr, nullptr, nullptr, 0, &args, kag); return; } } } else { if (kag->PropGet(0, TJS_W("enterAutoMode"), nullptr, &var, kag) == TJS_S_OK && var.Type() == tvtObject) { iTJSDispatch2* fn = var.AsObjectNoAddRef(); if (fn->IsInstanceOf(0, 0, 0, TJS_W("Function"), fn)) { tTJSVariant *args = nullptr; fn->FuncCall(0, nullptr, nullptr, nullptr, 0, &args, kag); return; } } } } } global->Release(); } unsigned int code = TVPConvertKeyCodeToVKCode(keyCode); if (!code || code >= 0x200) return; code = _keymap[code]; bool isPressed = _scancode[code] & 1; _scancode[code] &= 0x10; if (isPressed && _currentWindowLayer) { _currentWindowLayer->OnKeyUp(code, TVPGetCurrentShiftKeyState()); } } TVPMainScene::TVPMainScene() { _gameMenu = nullptr; _windowMgrOverlay = nullptr; } void TVPMainScene::showWindowManagerOverlay(bool bVisible) { if (bVisible) { if (!_windowMgrOverlay) { if (_currentWindowLayer && _currentWindowLayer->in_mode_) return; _windowMgrOverlay = TVPWindowManagerOverlay::create(); GameNode->addChild(_windowMgrOverlay, GAME_WINMGR_ORDER); _gameMenu->setVisible(false); } } else { if (_windowMgrOverlay) { _windowMgrOverlay->removeFromParent(); _windowMgrOverlay = nullptr; _gameMenu->setVisible(true); } } } void TVPMainScene::popAllUIForm() { TVPControlAdDialog(0x10002, 0, 0); auto children = UINode->getChildren(); for (auto ui : children) { Size size = getContentSize(); cocos2d::Node *ColorMask = MaskLayer::create(Color4B(0, 0, 0, 128), size.width, size.height); ColorMask->setPosition(Vec2(-size.width, 0)); ui->addChild(ColorMask); ColorMask->runAction(FadeOut::create(UI_CHANGE_DURATION)); ui->runAction(EaseQuadraticActionOut::create(MoveTo::create(UI_CHANGE_DURATION, Vec2(size.width, 0)))); runAction(Sequence::createWithTwoActions(DelayTime::create(UI_CHANGE_DURATION), CallFunc::create([=](){ ui->removeFromParent(); }))); } } void TVPMainScene::toggleVirtualMouseCursor() { showVirtualMouseCursor(!_mouseCursor || !_mouseCursor->isVisible()); } Sprite *TVPCreateCUR() { std::string fullPath = FileUtils::getInstance()->fullPathForFilename("default.cur"); Data buf = FileUtils::getInstance()->getDataFromFile(fullPath); tTVPMemoryStream stream(buf.getBytes(), buf.getSize()); return TVPLoadCursorCUR(&stream); } void TVPMainScene::showVirtualMouseCursor(bool bVisible) { if (!bVisible) { if (_mouseCursor) _mouseCursor->setVisible(false); _virutalMouseMode = bVisible; return; } if (!_mouseCursor) { _mouseCursor = TVPCreateCUR(); if (!_mouseCursor) return; _mouseCursorScale = _mouseCursor->getScale() * convertCursorScale(IndividualConfigManager::GetInstance()->GetValue("vcursor_scale", 0.5f)); _mouseCursor->setScale(_mouseCursorScale); GameNode->addChild(_mouseCursor, GAME_WINMGR_ORDER); _mouseCursor->setPosition(GameNode->getContentSize() / 2); } _mouseCursor->setVisible(true); _virutalMouseMode = bVisible; } bool TVPMainScene::isVirtualMouseMode() const { return _mouseCursor && _mouseCursor->isVisible(); } bool TVPMainScene::onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event) { if (UINode->getChildrenCount()) return false; if (!_currentWindowLayer) return false; if (!_virutalMouseMode || _windowMgrOverlay) return _currentWindowLayer->onTouchBegan(touch, event); _mouseTouches.insert(touch); switch (_mouseTouches.size()) { case 1: _mouseTouchPoint = GameNode->convertToNodeSpace(touch->getLocation()); _mouseBeginPoint = _mouseCursor->getPosition(); _touchBeginTick = TVPGetRoughTickCount32(); _mouseMoved = false; _mouseClickedDown = false; _mouseBtn = ::mbLeft; _mouseCursor->stopAllActions(); _mouseCursor->setOpacity(255); _mouseCursor->setScale(_mouseCursorScale); _mouseCursor->runAction(Sequence::createWithTwoActions(DelayTime::create(1), CallFuncN::create([this](Node*p){ p->setScale(_mouseCursorScale * 0.8f); _currentWindowLayer->onMouseMove(GameNode->convertToWorldSpace(_mouseBeginPoint)); _currentWindowLayer->onMouseDown(GameNode->convertToWorldSpace(_mouseBeginPoint)); _mouseClickedDown = true; _mouseMoved = true; }))); break; case 2: _mouseBtn = ::mbRight; _mouseTouchPoint = (_mouseTouchPoint + GameNode->convertToNodeSpace(touch->getLocation())) / 2; break; default: break; } return true; } void TVPMainScene::onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event) { if (!_currentWindowLayer) return; if (!_virutalMouseMode || _windowMgrOverlay) return _currentWindowLayer->onTouchMoved(touch, event); if (_mouseTouches.size()) { Vec2 pt, newpt; if (_mouseTouches.size() == 1) { pt = touch->getLocation(); } else if (_mouseTouches.size() == 2) { auto it = _mouseTouches.begin(); pt = (*it)->getLocation(); pt = (pt + (*++it)->getLocation()) / 2; } Vec2 moveDistance, newPoint; newPoint = GameNode->convertToNodeSpace(pt); moveDistance = newPoint - _mouseTouchPoint; pt = _mouseBeginPoint + moveDistance; Size size = GameNode->getContentSize(); newpt = pt; if (pt.x < 0) newpt.x = 0; else if (pt.x > size.width) newpt.x = size.width; if (pt.y < 0) newpt.y = 0; else if (pt.y > size.height) newpt.y = size.height; _mouseBeginPoint += newpt - pt; _mouseCursor->setPosition(newpt); _currentWindowLayer->onMouseMove(GameNode->convertToWorldSpace(newpt)); if (!_mouseMoved) { if (TVPGetRoughTickCount32() - _touchBeginTick > 1000) { _currentWindowLayer->onMouseDown(GameNode->convertToWorldSpace(newpt)); _mouseClickedDown = true; _mouseMoved = true; } else if (moveDistance.getLengthSq() > _touchMoveThresholdSq) { _mouseCursor->stopAllActions(); _mouseMoved = true; } } } } void TVPMainScene::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event) { if (!_currentWindowLayer) return; if (!_virutalMouseMode || _windowMgrOverlay) return _currentWindowLayer->onTouchEnded(touch, event); if (_mouseTouches.size() == 1) { Vec2 pt = _mouseCursor->getPosition(); if (!_mouseClickedDown && TVPGetRoughTickCount32() - _touchBeginTick < 150) { _currentWindowLayer->onMouseClick(GameNode->convertToWorldSpace(pt)); } else if (_mouseClickedDown) { _currentWindowLayer->onMouseUp(GameNode->convertToWorldSpace(pt)); } } _mouseTouches.erase(touch); if (_mouseTouches.size() == 0) { _mouseMoved = false; _mouseClickedDown = false; _refadeMouseCursor(); _mouseCursor->setScale(_mouseCursorScale); _mouseCursor->stopAllActions(); } } void TVPMainScene::onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *event) { if (!_currentWindowLayer) return; if (!_virutalMouseMode || _windowMgrOverlay) return _currentWindowLayer->onTouchCancelled(touch, event); _mouseTouches.erase(touch); _mouseMoved = false; _refadeMouseCursor(); } bool TVPMainScene::attachWithIME() { bool ret = IMEDelegate::attachWithIME(); if (ret) { // open keyboard auto pGlView = Director::getInstance()->getOpenGLView(); if (pGlView) { #if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8 && CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) pGlView->setIMEKeyboardState(true); #else pGlView->setIMEKeyboardState(true, ""); #endif } } return ret; } bool TVPMainScene::detachWithIME() { bool ret = IMEDelegate::detachWithIME(); if (ret) { // close keyboard auto glView = Director::getInstance()->getOpenGLView(); if (glView) { #if (CC_TARGET_PLATFORM != CC_PLATFORM_WP8 && CC_TARGET_PLATFORM != CC_PLATFORM_WINRT) glView->setIMEKeyboardState(false); #else glView->setIMEKeyboardState(false, ""); #endif } } return ret; } bool TVPMainScene::canAttachWithIME() { return true; } bool TVPMainScene::canDetachWithIME() { return true; } void TVPMainScene::deleteBackward() { #ifndef _WIN32 if (_currentWindowLayer) { _currentWindowLayer->InternalKeyDown(VK_BACK, TVPGetCurrentShiftKeyState()); _currentWindowLayer->OnKeyUp(VK_BACK, TVPGetCurrentShiftKeyState()); } #endif } void TVPMainScene::insertText(const char * text, size_t len) { std::string utf8(text, len); onTextInput(utf8); } void TVPMainScene::onCharInput(int keyCode) { _currentWindowLayer->OnKeyPress((tjs_char)keyCode, 0, false, false); } void TVPMainScene::onTextInput(const std::string &text) { std::u16string buf; if (StringUtils::UTF8ToUTF16(text, buf)) { for (int i = 0; i < buf.size(); ++i) { _currentWindowLayer->OnKeyPress(buf[i], 0, false, false); } } } void TVPMainScene::onAxisEvent(cocos2d::Controller* ctrl, int keyCode, cocos2d::Event *e) { if (!_currentWindowLayer || !_currentWindowLayer->PrimaryLayerArea) return; if (!_virutalMouseMode || _windowMgrOverlay) return; const float threashold = 0.1f; const cocos2d::Controller::KeyStatus& keyStatus = ctrl->getKeyStatus(keyCode); // CCLOG("Axis KeyCode:%d Axis Value:%f", keyCode, keyStatus.value); if (std::abs(keyStatus.value) < threashold) { return; } float offv = keyStatus.value; if (offv > 0) offv = (offv - threashold) / (1 - threashold); else offv = (offv + threashold) / (1 - threashold); Vec2 pt = Vec2(_currentWindowLayer->_LastMouseX, _currentWindowLayer->_LastMouseY); float *pValue = nullptr; switch (keyCode) { case cocos2d::Controller::JOYSTICK_LEFT_X: pValue = &pt.x; break; case cocos2d::Controller::JOYSTICK_LEFT_Y: pValue = &pt.y; break; default: return; } *pValue += offv * 16; pt = _currentWindowLayer->PrimaryLayerArea->convertToWorldSpace(pt); pt = GameNode->convertToNodeSpace(pt); Vec2 newpt = pt; Size size = GameNode->getContentSize(); if (pt.x < 0) newpt.x = 0; else if (pt.x > size.width) newpt.x = size.width; if (pt.y < 0) newpt.y = 0; else if (pt.y > size.height) newpt.y = size.height; _mouseCursor->setPosition(newpt); _currentWindowLayer->onMouseMove(GameNode->convertToWorldSpace(newpt)); } void TVPMainScene::onPadKeyDown(cocos2d::Controller* ctrl, int keyCode, cocos2d::Event *e) { if (!UINode->getChildren().empty()) return; unsigned int code = TVPConvertPadKeyCodeToVKCode(keyCode); if (!code || code >= 0x200) return; code = _keymap[code]; _scancode[code] = 0x11; if (_currentWindowLayer) { _currentWindowLayer->InternalKeyDown(code, TVPGetCurrentShiftKeyState()); } } void TVPMainScene::onPadKeyUp(cocos2d::Controller* ctrl, int keyCode, cocos2d::Event *e) { unsigned int code = TVPConvertPadKeyCodeToVKCode(keyCode); if (!code || code >= 0x200) return; code = _keymap[code]; bool isPressed = _scancode[code] & 1; _scancode[code] &= 0x10; if (isPressed && _currentWindowLayer) { _currentWindowLayer->OnKeyUp(code, TVPGetCurrentShiftKeyState()); } } void TVPMainScene::onPadKeyRepeat(cocos2d::Controller* ctrl, int code, cocos2d::Event *e) { } float TVPMainScene::convertCursorScale(float val/*0 ~ 1*/) { if (val <= 0.5f) { return 0.25f + (val * 2) * 0.75f; } else { return 1.f + (val - 0.5f) * 2.f; } } iWindowLayer *TVPCreateAndAddWindow(tTJSNI_Window *w) { TVPWindowLayer* ret = TVPWindowLayer::create(w); TVPMainScene::GetInstance()->addLayer(ret); if (_consoleWin) ret->setVisible(false); return ret; } void TVPRemoveWindowLayer(iWindowLayer *lay) { static_cast(lay)->removeFromParent(); } void TVPConsoleLog(const ttstr &l, bool important) { static bool TVPLoggingToConsole = IndividualConfigManager::GetInstance()->GetValue("outputlog", true); if (!TVPLoggingToConsole) return; if (_consoleWin) { _consoleWin->addLine(l, important ? Color3B::YELLOW : Color3B::GRAY); TVPDrawSceneOnce(100); // force update in 10fps } #ifdef _WIN32 //cocos2d::log("%s", utf8.c_str()); char buf[16384] = { 0 }; WideCharToMultiByte(CP_ACP, 0, l.c_str(), -1, buf, sizeof(buf), nullptr, FALSE); puts(buf); #else cocos2d::log("%ls", l.c_str()); // std::string utf8; // if (StringUtils::UTF16ToUTF8(l.c_str(), utf8)) // cocos2d::log("%s", utf8.c_str()); #endif } namespace TJS { static const int MAX_LOG_LENGTH = 16 * 1024; void TVPConsoleLog(const tjs_char *l) { std::string utf8; assert(sizeof(tjs_char) == sizeof(char16_t)); std::u16string buf((const char16_t*)l); if (StringUtils::UTF16ToUTF8(buf, utf8)) cocos2d::log("%s", utf8.c_str()); } void TVPConsoleLog(const tjs_nchar *format, ...) { va_list args; va_start(args, format); char buf[MAX_LOG_LENGTH]; vsnprintf(buf, MAX_LOG_LENGTH - 3, format, args); cocos2d::log("%s", buf); va_end(args); } } bool TVPGetScreenSize(tjs_int idx, tjs_int &w, tjs_int &h) { if (idx != 0) return false; const cocos2d::Size &size = cocos2d::Director::getInstance()->getOpenGLView()->getFrameSize(); //w = size.height; h = size.width; w = 2048; h = w * (size.height / size.width); return true; } ttstr TVPGetDataPath() { std::string path = cocos2d::FileUtils::getInstance()->getWritablePath(); return path; } #include "StorageImpl.h" static std::string _TVPGetInternalPreferencePath() { std::string path = cocos2d::FileUtils::getInstance()->getWritablePath(); path += ".preference"; if (!TVPCheckExistentLocalFolder(path)) { TVPCreateFolders(path); } path += "/"; return path; } const std::string &TVPGetInternalPreferencePath() { static std::string ret = _TVPGetInternalPreferencePath(); return ret; } tjs_uint32 TVPGetCurrentShiftKeyState() { tjs_uint32 f = 0; if (_scancode[VK_SHIFT] & 1) f |= ssShift; if (_scancode[VK_MENU] & 1) f |= ssAlt; if (_scancode[VK_CONTROL] & 1) f |= ssCtrl; if (_scancode[VK_LBUTTON] & 1) f |= ssLeft; if (_scancode[VK_RBUTTON] & 1) f |= ssRight; //if (_scancode[VK_MBUTTON] & 1) f |= TVP_SS_MIDDLE; return f; } ttstr TVPGetPlatformName() { switch (cocos2d::Application::getInstance()->getTargetPlatform()) { case ApplicationProtocol::Platform::OS_WINDOWS: return "Win32"; case ApplicationProtocol::Platform::OS_LINUX: return "Linux"; case ApplicationProtocol::Platform::OS_MAC: return "MacOS"; case ApplicationProtocol::Platform::OS_ANDROID: return "Android"; case ApplicationProtocol::Platform::OS_IPHONE: return "iPhone"; case ApplicationProtocol::Platform::OS_IPAD: return "iPad"; case ApplicationProtocol::Platform::OS_BLACKBERRY: return "BlackBerry"; case ApplicationProtocol::Platform::OS_NACL: return "Nacl"; case ApplicationProtocol::Platform::OS_TIZEN: return "Tizen"; case ApplicationProtocol::Platform::OS_WINRT: return "WinRT"; case ApplicationProtocol::Platform::OS_WP8: return "WinPhone8"; default: return "Unknown"; } } ttstr TVPGetOSName() { return TVPGetPlatformName(); } ================================================ FILE: src/core/environ/cocos2d/MainScene.h ================================================ #pragma once #include "2d/CCScene.h" #include "ui/UIWidget.h" #include "base/CCIMEDelegate.h" namespace cocos2d { class Controller; } class TVPWindowLayer; class TVPGameMainMenu; class TVPMainScene : public cocos2d::Scene, public cocos2d::IMEDelegate { TVPMainScene(); static TVPMainScene *create(); virtual void update(float delta) override; void initialize(); friend class TVPAppDelegate; public: static TVPMainScene* GetInstance(); static TVPMainScene* CreateInstance(); static void setMaskLayTouchBegain(const std::function &func); enum eEnterAni { eEnterAniNone, eEnterAniOverFromRight, eEnterFromBottom, }; void pushUIForm(cocos2d::Node *node, eEnterAni ani = eEnterAniOverFromRight); enum eLeaveAni { eLeaveAniNone, eLeaveAniLeaveFromLeft, eLeaveToBottom, }; void popUIForm(cocos2d::Node *node, eLeaveAni ani = eLeaveAniLeaveFromLeft); void popAllUIForm(); void addLayer(TVPWindowLayer* lay); cocos2d::Size getUINodeSize(); cocos2d::Size getGameNodeSize() { return GameNode->getContentSize(); } void rotateUI(); bool startupFrom(const std::string &path); float getUIScale(); void showWindowManagerOverlay(bool bVisible); void toggleVirtualMouseCursor(); void showVirtualMouseCursor(bool bVisible); bool isVirtualMouseMode() const; virtual bool attachWithIME() override; virtual bool detachWithIME() override; static void onCharInput(int keyCode); static void onTextInput(const std::string &text); static float convertCursorScale(float cfgScale/*0 ~ 1*/); private: void onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event); void onKeyReleased(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event); bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event); void onTouchMoved(cocos2d::Touch *touch, cocos2d::Event *event); void onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event); void onTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *event); void onAxisEvent(cocos2d::Controller* ctrl, int code, cocos2d::Event *e); void onPadKeyDown(cocos2d::Controller* ctrl, int code, cocos2d::Event *e); void onPadKeyUp(cocos2d::Controller* ctrl, int code, cocos2d::Event *e); void onPadKeyRepeat(cocos2d::Controller* ctrl, int code, cocos2d::Event *e); virtual bool canAttachWithIME() override; virtual bool canDetachWithIME() override; virtual void deleteBackward(); virtual void insertText(const char * text, size_t len); void doStartup(float dt, std::string path); float ScreenRatio; cocos2d::Size SceneSize, UISize; cocos2d::Node *UINode, *GameNode; cocos2d::EventListenerTouchOneByOne* _touchListener; TVPGameMainMenu *_gameMenu; }; ================================================ FILE: src/core/environ/cocos2d/YUVSprite.cpp ================================================ #include "YUVSprite.h" using namespace cocos2d; // #define USE_VAO static const char *_yuvRenderProgram_fsh = "#ifdef GL_ES" "\n" "precision lowp float;" "\n" "#endif" "\n" "varying vec4 v_fragmentColor;" "\n" "varying vec2 v_texCoord;" "\n" "void main() {" "\n" " vec3 yuv;" "\n" " yuv.x = texture2D(CC_Texture0, v_texCoord).r - 0.0625;" "\n" " yuv.y = texture2D(CC_Texture1, v_texCoord).r - 0.5;" "\n" " yuv.z = texture2D(CC_Texture2, v_texCoord).r - 0.5;" "\n" " vec3 rgb = mat3(1.164, 1.164, 1.164," "\n" " 0.0, -0.392, 2.017," "\n" " 1.596, -0.813, 0.0) * yuv;" "\n" " gl_FragColor = vec4(rgb, 1.0) * v_fragmentColor;" "\n" "}" ; static cocos2d::GLProgram* _getYUVRenderProgram() { static cocos2d::GLProgram* _program = nullptr; if (!_program) { static cocos2d::EventListenerCustom *_backgroundListener = nullptr; if (!_backgroundListener) { _backgroundListener = cocos2d::EventListenerCustom::create(EVENT_RENDERER_RECREATED, [](cocos2d::EventCustom*) { _program->reset(); _program->initWithByteArrays(cocos2d::ccPositionTextureColor_vert, _yuvRenderProgram_fsh); _program->link(); _program->updateUniforms(); }); cocos2d::Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_backgroundListener, -1); } _program = cocos2d::GLProgram::createWithByteArrays(cocos2d::ccPositionTextureColor_vert, _yuvRenderProgram_fsh); } return _program; } void TVPYUVSprite::setupVBOAndVAO() { #ifdef USE_VAO //generate vbo and vao for trianglesCommand glGenVertexArrays(1, &_buffersVAO); cocos2d::GL::bindVAO(_buffersVAO); glGenBuffers(2, &_buffersVBO[0]); glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); glBufferData(GL_ARRAY_BUFFER, sizeof(_polyInfo.triangles.verts[0]) * _polyInfo.triangles.vertCount, _polyInfo.triangles.verts, GL_DYNAMIC_DRAW); // vertices GL::enableVertexAttribs(cocos2d::GLProgram::VERTEX_ATTRIB_POSITION); glVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(_polyInfo.triangles.verts[0]), (GLvoid*)offsetof(cocos2d::V3F_C4B_T2F, vertices)); // colors GL::enableVertexAttribs(cocos2d::GLProgram::VERTEX_ATTRIB_COLOR); glVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(_polyInfo.triangles.verts[0]), (GLvoid*)offsetof(cocos2d::V3F_C4B_T2F, colors)); // tex coords GL::enableVertexAttribs(cocos2d::GLProgram::VERTEX_ATTRIB_TEX_COORD); glVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, sizeof(_polyInfo.triangles.verts[0]), (GLvoid*)offsetof(cocos2d::V3F_C4B_T2F, texCoords)); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_polyInfo.triangles.indices[0]) * _polyInfo.triangles.indexCount, _polyInfo.triangles.indices, GL_DYNAMIC_DRAW); // Must unbind the VAO before changing the element buffer. GL::bindVAO(0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); CHECK_GL_ERROR_DEBUG(); #endif } void TVPYUVSprite::updateTextureDataInternal(cocos2d::Texture2D *pTex, const void* data, int width, int height, cocos2d::Texture2D::PixelFormat pixfmt) { const cocos2d::Size &size = pTex->getContentSize(); cocos2d::Size videoSize(width, height); if (size.width != videoSize.width || size.height != videoSize.height || pTex->getPixelFormat() != pixfmt) { if (size.width < videoSize.width || size.height < videoSize.height || pTex->getPixelFormat() != pixfmt) { ssize_t datasize = width * height; switch (pixfmt) { case cocos2d::Texture2D::PixelFormat::BGRA8888: case cocos2d::Texture2D::PixelFormat::RGBA8888: datasize *= 4; break; case cocos2d::Texture2D::PixelFormat::RGB888: datasize *= 3; break; case cocos2d::Texture2D::PixelFormat::RGB565: case cocos2d::Texture2D::PixelFormat::AI88: case cocos2d::Texture2D::PixelFormat::RGBA4444: datasize *= 2; break; default: break; } pTex->initWithData(data, datasize, pixfmt, width, height, cocos2d::Size::ZERO); pTex = nullptr; } } if (pTex) { pTex->updateWithData(data, 0, 0, width, height); } } TVPYUVSprite::~TVPYUVSprite() { CC_SAFE_RELEASE(_textureU); CC_SAFE_RELEASE(_textureV); } TVPYUVSprite* TVPYUVSprite::create() { TVPYUVSprite* sprite = new TVPYUVSprite; sprite->init(); sprite->autorelease(); return sprite; } bool TVPYUVSprite::init() { initWithTexture(new cocos2d::Texture2D); setupVBOAndVAO(); _drawCommand.func = std::bind(&TVPYUVSprite::onDraw, this); _textureU = new cocos2d::Texture2D; _textureU->retain(); _textureV = new cocos2d::Texture2D; _textureV->retain(); setGLProgram(_getYUVRenderProgram()); return true; } void TVPYUVSprite::updateTextureData(const void* data, int width, int height) { cocos2d::Texture2D *pTex = getTexture(); const cocos2d::Size &size = pTex->getContentSize(); updateTextureDataInternal(getTexture(), data, width, height, cocos2d::Texture2D::PixelFormat::RGBA8888); if (size.width != width || size.height != height) { setTextureRect(cocos2d::Rect(0, 0, width, height)); } } void TVPYUVSprite::updateTextureData(const void* Y, int YW, int YH, const void* U, int UW, int UH, const void* V, int VW, int VH) { cocos2d::Texture2D *pTex = getTexture(); const cocos2d::Size &size = pTex->getContentSize(); updateTextureDataInternal(getTexture(), Y, YW, YH, cocos2d::Texture2D::PixelFormat::I8); updateTextureDataInternal(_textureU, U, UW, UH, cocos2d::Texture2D::PixelFormat::I8); updateTextureDataInternal(_textureV, V, VW, VH, cocos2d::Texture2D::PixelFormat::I8); if (size.width != YW || size.height != YH) { setTextureRect(cocos2d::Rect(0, 0, YW, YH)); } } void TVPYUVSprite::onDraw() { CCAssert(_polyInfo.triangles.vertCount == 4, ""); #ifdef USE_VAO GL::bindVAO(_buffersVAO); glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]); // glBufferData(GL_ARRAY_BUFFER, sizeof(_polyInfo.triangles.verts[0]) * _polyInfo.triangles.vertCount, nullptr, GL_DYNAMIC_DRAW); void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); memcpy(buf, _polyInfo.triangles.verts, sizeof(_polyInfo.triangles.verts[0]) * 4); glUnmapBuffer(GL_ARRAY_BUFFER); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _buffersVBO[1]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_polyInfo.triangles.indices[0]) * _polyInfo.triangles.indexCount, _polyInfo.triangles.indices, GL_DYNAMIC_DRAW); cocos2d::GL::bindTexture2DN(0, _texture->getName()); cocos2d::GL::bindTexture2DN(1, _textureU->getName()); cocos2d::GL::bindTexture2DN(2, _textureV->getName()); cocos2d::GL::blendFunc(_blendFunc.src, _blendFunc.dst); _glProgramState->apply(_mv); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, NULL); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); GL::bindVAO(0); CHECK_GL_ERROR_DEBUG(); return; #endif cocos2d::GL::bindTexture2DN(0, _texture->getName()); cocos2d::GL::bindTexture2DN(1, _textureU->getName()); cocos2d::GL::bindTexture2DN(2, _textureV->getName()); cocos2d::GL::blendFunc(_blendFunc.src, _blendFunc.dst); _glProgramState->apply(_mv); cocos2d::GL::enableVertexAttribs(cocos2d::GL::VERTEX_ATTRIB_FLAG_POS_COLOR_TEX); cocos2d::Vec3 vertices[4] = { _polyInfo.triangles.verts[0].vertices, _polyInfo.triangles.verts[1].vertices, _polyInfo.triangles.verts[2].vertices, _polyInfo.triangles.verts[3].vertices }; glVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, 0, vertices); cocos2d::Color4B colors[4] = { _polyInfo.triangles.verts[0].colors, _polyInfo.triangles.verts[1].colors, _polyInfo.triangles.verts[2].colors, _polyInfo.triangles.verts[3].colors }; glVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, colors); cocos2d::Tex2F texCoords[4] = { _polyInfo.triangles.verts[0].texCoords, _polyInfo.triangles.verts[1].texCoords, _polyInfo.triangles.verts[2].texCoords, _polyInfo.triangles.verts[3].texCoords }; glVertexAttribPointer(cocos2d::GLProgram::VERTEX_ATTRIB_TEX_COORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } void TVPYUVSprite::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) { _mv = transform; _drawCommand.init(_globalZOrder); renderer->addCommand(&_drawCommand); } ================================================ FILE: src/core/environ/cocos2d/YUVSprite.h ================================================ #pragma once #include "cocos2d.h" class TVPYUVSprite : public cocos2d::Sprite { cocos2d::Texture2D* _textureU = nullptr, *_textureV = nullptr; cocos2d::Texture2D::PixelFormat _texfmtY = cocos2d::Texture2D::PixelFormat::NONE, _texfmtU = cocos2d::Texture2D::PixelFormat::NONE, _texfmtV = cocos2d::Texture2D::PixelFormat::NONE; cocos2d::CustomCommand _drawCommand; GLuint _buffersVAO; GLuint _buffersVBO[2]; //0: vertex 1: indices void setupVBOAndVAO(); void updateTextureDataInternal(cocos2d::Texture2D *pTex, const void* data, int width, int height, cocos2d::Texture2D::PixelFormat pixfmt); public: virtual ~TVPYUVSprite(); static TVPYUVSprite* create(); bool init(); void updateTextureData(const void* data, int width, int height); void updateTextureData( const void* Y, int YW, int YH, const void* U, int UW, int UH, const void* V, int VW, int VH); private: cocos2d::Mat4 _mv; void onDraw(); void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) override; }; ================================================ FILE: src/core/environ/combase.h ================================================ #pragma once #include "typedefine.h" #include "win32type.h" #include #ifndef S_OK #define S_OK ((HRESULT)0L) #define S_FALSE ((HRESULT)1L) #define S_UNKNOWN ((HRESULT)0x7FFFFFFFL) #define E_NOINTERFACE ((HRESULT)0x80004002L) #define E_INVALIDARG ((HRESULT)0x80000003L) #define E_FAIL ((HRESULT)0x80004005L) #define E_NOTIMPL ((HRESULT)0x80004001L) #define E_NOINTERFACE ((HRESULT)0x80004002L) #define E_OUTOFMEMORY ((HRESULT)0x8007000EL) #define FAILED(hr) (((HRESULT)(hr)) < 0) #define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0) #define TRUE 1 typedef struct _IID { uint32_t x; uint16_t s1; uint16_t s2; uint8_t c[8]; } IID/*IID*/; #define REFIID const IID & #endif #ifndef STDMETHODCALLTYPE #ifdef WIN32 #define STDMETHODCALLTYPE __stdcall #else #define STDMETHODCALLTYPE #endif class IUnknown { public: virtual HRESULT STDMETHODCALLTYPE QueryInterface( /* [in] */ REFIID riid, /* [iid_is][out] */ void **ppvObject) = 0; virtual ULONG STDMETHODCALLTYPE AddRef( void) = 0; virtual ULONG STDMETHODCALLTYPE Release( void) = 0; }; class ISequentialStream : public IUnknown { public: virtual HRESULT STDMETHODCALLTYPE Read( /* [annotation][write_to] */ void *pv, /* [annotation][in] */ ULONG cb, /* [annotation][out_opt] */ ULONG *pcbRead) = 0; virtual HRESULT STDMETHODCALLTYPE Write( /* [annotation] */ const void *pv, /* [annotation][in] */ ULONG cb, /* [annotation][out_opt] */ ULONG *pcbWritten) = 0; }; typedef char OLECHAR; typedef LPSTR LPOLESTR; typedef LPCSTR LPCOLESTR; typedef struct tagSTATSTG { LPOLESTR pwcsName; #ifdef _MAC //FSSpec is Macintosh only, defined in macos\files.h FSSpec *pspec; #endif //_MAC DWORD type; ULARGE_INTEGER cbSize; FILETIME mtime; FILETIME ctime; FILETIME atime; DWORD grfMode; DWORD grfLocksSupported; //CLSID clsid; DWORD grfStateBits; DWORD reserved; } STATSTG; typedef enum tagSTREAM_SEEK { STREAM_SEEK_SET = 0, STREAM_SEEK_CUR = 1, STREAM_SEEK_END = 2 } STREAM_SEEK; typedef enum tagSTATFLAG { STATFLAG_DEFAULT = 0, STATFLAG_NONAME = 1, STATFLAG_NOOPEN = 2 } STATFLAG; typedef enum tagSTGTY { STGTY_STORAGE = 1, STGTY_STREAM = 2, STGTY_LOCKBYTES = 3, STGTY_PROPERTY = 4 } STGTY; #define STGM_DIRECT 0x00000000L #define STGM_TRANSACTED 0x00010000L #define STGM_SIMPLE 0x08000000L #define STGM_READ 0x00000000L #define STGM_WRITE 0x00000001L #define STGM_READWRITE 0x00000002L #define STGM_SHARE_DENY_NONE 0x00000040L #define STGM_SHARE_DENY_READ 0x00000030L #define STGM_SHARE_DENY_WRITE 0x00000020L #define STGM_SHARE_EXCLUSIVE 0x00000010L struct IStream : public ISequentialStream { public: virtual /* [local] */ HRESULT STDMETHODCALLTYPE Seek( /* [in] */ LARGE_INTEGER dlibMove, /* [in] */ DWORD dwOrigin, /* [annotation] */ ULARGE_INTEGER *plibNewPosition) = 0; virtual HRESULT STDMETHODCALLTYPE SetSize( /* [in] */ ULARGE_INTEGER libNewSize) = 0; virtual /* [local] */ HRESULT STDMETHODCALLTYPE CopyTo( /* [annotation][unique][in] */ IStream *pstm, /* [in] */ ULARGE_INTEGER cb, /* [annotation] */ ULARGE_INTEGER *pcbRead, /* [annotation] */ ULARGE_INTEGER *pcbWritten) = 0; virtual HRESULT STDMETHODCALLTYPE Commit( /* [in] */ DWORD grfCommitFlags) = 0; virtual HRESULT STDMETHODCALLTYPE Revert( void) = 0; virtual HRESULT STDMETHODCALLTYPE LockRegion( /* [in] */ ULARGE_INTEGER libOffset, /* [in] */ ULARGE_INTEGER cb, /* [in] */ DWORD dwLockType) = 0; virtual HRESULT STDMETHODCALLTYPE UnlockRegion( /* [in] */ ULARGE_INTEGER libOffset, /* [in] */ ULARGE_INTEGER cb, /* [in] */ DWORD dwLockType) = 0; virtual HRESULT STDMETHODCALLTYPE Stat( /* [out] */ STATSTG *pstatstg, /* [in] */ DWORD grfStatFlag) = 0; virtual HRESULT STDMETHODCALLTYPE Clone( /* [out] */ IStream **ppstm) = 0; }; #endif ================================================ FILE: src/core/environ/cpu_types.h ================================================ // ; this is a part of TVP (KIRIKIRI) software source. // ; see other sources for license. // ; (C)2001-2003 W.Dee and contributors // // ;;[emit_c_h]/*[*/ // ;;[emit_c_h]//--------------------------------------------------------------------------- // ;;[emit_c_h]// CPU Types // ;;[emit_c_h]//--------------------------------------------------------------------------- // ;;[emit_c_h]/*]*/ // // ;;[emit_c_h_equ_begin] #pragma once #define TVP_CPU_HAS_FPU 0x00010000 #define TVP_CPU_HAS_MMX 0x00020000 #define TVP_CPU_HAS_3DN 0x00040000 #define TVP_CPU_HAS_SSE 0x00080000 #define TVP_CPU_HAS_CMOV 0x00100000 #define TVP_CPU_HAS_E3DN 0x00200000 #define TVP_CPU_HAS_EMMX 0x00400000 #define TVP_CPU_HAS_SSE2 0x00800000 #define TVP_CPU_HAS_TSC 0x01000000 #define TVP_CPU_HAS_NEON 0x02000000 #define TVP_CPU_FEATURE_MASK 0xffff0000 #define TVP_CPU_IS_INTEL 0x00000010 #define TVP_CPU_IS_AMD 0x00000020 #define TVP_CPU_IS_IDT 0x00000030 #define TVP_CPU_IS_CYRIX 0x00000040 #define TVP_CPU_IS_NEXGEN 0x00000050 #define TVP_CPU_IS_RISE 0x00000060 #define TVP_CPU_IS_UMC 0x00000070 #define TVP_CPU_IS_TRANSMETA 0x00000080 #define TVP_CPU_IS_UNKNOWN 0x00000000 #define TVP_CPU_VENDOR_MASK 0x00000ff0 #define TVP_CPU_FAMILY_X86 0x00000001 #define TVP_CPU_FAMILY_X64 0x00000002 #define TVP_CPU_FAMILY_ARM 0x00000003 #define TVP_CPU_FAMILY_MIPS 0x00000003 #define TVP_CPU_FAMILY_MASK 0x0000000f #ifdef __cplusplus extern "C" unsigned int TVPCPUFeatures; #else extern unsigned int TVPCPUFeatures; #endif // ;;[emit_c_h_equ_end] // // ; note: EMMX is refered to as MMX2 ================================================ FILE: src/core/environ/linux/Platform.cpp ================================================ #include "Platform.h" #include #include #include #include #include #include #include void TVPGetMemoryInfo(TVPMemoryInfo &m) { /* to read /proc/meminfo */ FILE* meminfo; char buffer[100] = {0}; char* end; int found = 0; /* Try to read /proc/meminfo, bail out if fails */ meminfo = fopen("/proc/meminfo", "r"); static const char pszMemFree[] = "MemFree:", pszMemTotal[] = "MemTotal:", pszSwapTotal[] = "SwapTotal:", pszSwapFree[] = "SwapFree:", pszVmallocTotal[] = "VmallocTotal:", pszVmallocUsed[] = "VmallocUsed:"; /* Read each line untill we got all we ned */ while( fgets( buffer, sizeof( buffer ), meminfo ) ) { if( strstr( buffer, pszMemFree ) == buffer ) { m.MemFree = strtol( buffer + sizeof(pszMemFree), &end, 10 ); found++; } else if( strstr( buffer, pszMemTotal ) == buffer ) { m.MemTotal = strtol( buffer + sizeof(pszMemTotal), &end, 10 ); found++; } else if( strstr( buffer, pszSwapTotal ) == buffer ) { m.SwapTotal = strtol( buffer + sizeof(pszSwapTotal), &end, 10 ); found++; break; } else if( strstr( buffer, pszSwapFree ) == buffer ) { m.SwapFree = strtol( buffer + sizeof(pszSwapFree), &end, 10 ); found++; break; } else if( strstr( buffer, pszVmallocTotal ) == buffer ) { m.VirtualTotal = strtol( buffer + sizeof(pszVmallocTotal), &end, 10 ); found++; break; } else if( strstr( buffer, pszVmallocUsed ) == buffer ) { m.VirtualUsed = strtol( buffer + sizeof(pszVmallocUsed), &end, 10 ); found++; break; } } fclose(meminfo); } #include void TVPRelinquishCPU(){ sched_yield(); } void TVP_utime(const char *name, time_t modtime) { timeval mt[2]; mt[0].tv_sec = modtime; mt[0].tv_usec = 0; mt[1].tv_sec = modtime; mt[1].tv_usec = 0; utimes(name, mt); } ================================================ FILE: src/core/environ/sdl/tvpsdl.cpp ================================================ //--------------------------------------------------------------------------- /* TVP2 ( T Visual Presenter 2 ) A script authoring tool Copyright (C) 2000-2007 W.Dee and contributors See details of license at "license.txt" */ //--------------------------------------------------------------------------- // TVP Win32 Project File //--------------------------------------------------------------------------- #include "tjsCommHead.h" #include //--------------------------------------------------------------------------- void TVPOnError(); //--------------------------------------------------------------------------- #ifdef TVP_SUPPORT_ERI # pragma link "../../../../Lib/liberina.lib" #endif //--------------------------------------------------------------------------- #if defined(WIN32) && defined(_DEBUG) #include #define TVP_MAIN_DEBUG //#include #include "GraphicsLoaderIntf.h" #include #else #include #endif #include "StorageIntf.h" #include #include "EventIntf.h" #include "Application.h" #include "SysInitImpl.h" #include "TickCount.h" #include "ScriptMgnIntf.h" #include "DebugIntf.h" //#include "PluginImpl.h" #include "ScriptMgnImpl.h" #include "SystemIntf.h" #include "ThreadIntf.h" #include "Platform.h" #include "ConfigManager/LocaleConfigManager.h" #include "Exception.h" //#define HOOK_MALLOC_FOR_OVERRUN //#define TC_MALLOC extern "C" void monstartup(const char *libname); static bool tc_malloc_startup = false; ================================================ FILE: src/core/environ/typedefine.h ================================================ #pragma once #ifndef _BASETSD_H_ #ifndef MAX_PATH #define MAX_PATH 260 #endif #include "tjsTypes.h" #include /* public enums and structures that GDI+ reuse from the other Windows API */ #define LF_FACESIZE 32 /* SetBkMode */ //#define TRANSPARENT 1 //#define OPAQUE 2 /* SetMapMode */ #define MM_TEXT 1 #define MM_LOMETRIC 2 #define MM_HIMETRIC 3 #define MM_LOENGLISH 4 #define MM_HIENGLISH 5 #define MM_TWIPS 6 #define MM_ISOTROPIC 7 #define MM_ANISOTROPIC 8 /* CreatePenIndirect */ #define PS_NULL 0x00000005 #define PS_STYLE_MASK 0x0000000F #define PS_ENDCAP_ROUND 0x00000000 #define PS_ENDCAP_SQUARE 0x00000100 #define PS_ENDCAP_FLAT 0x00000200 #define PS_ENDCAP_MASK 0x00000F00 #define PS_JOIN_ROUND 0x00000000 #define PS_JOIN_BEVEL 0x00001000 #define PS_JOIN_MITER 0x00002000 #define PS_JOIN_MASK 0x0000F000 /* CreateBrushIndirect */ #define BS_SOLID 0 #define BS_NULL 1 #define BS_HATCHED 2 #define BS_PATTERN 3 #define BS_INDEXED 4 /* SetPolyFillMode */ //#define ALTERNATE 1 //#define WINDING 2 /* SetRelabs */ //#define ABSOLUTE 1 //#define RELATIVE 2 /* ModifyWorldTransform */ #define MWT_IDENTITY 1 #define MWT_LEFTMULTIPLY 2 #define MWT_RIGHTMULTIPLY 3 typedef int LANGID; typedef int INT; typedef uint32_t UINT; typedef uint32_t ARGB; typedef uint32_t UINT32; typedef int32_t PROPID; //typedef uint32_t ULONG_PTR; /* not a pointer! */ typedef float REAL; typedef void* HBITMAP; typedef void* HDC; typedef void* HENHMETAFILE; typedef void* HFONT; typedef void* HICON; typedef void* HINSTANCE; typedef void* HMETAFILE; typedef void* HPALETTE; /* mono/io-layer/uglify.h also has these typedefs. * To avoid a dependency on mono we have copied all * the required stuff here. We don't include our defs * if uglify.h is included somehow. */ //#ifndef _WAPI_UGLIFY_H_ /* to avoid conflict with uglify.h */ //typedef const tjs_char *LPCTSTR; //typedef tjs_char *LPTSTR; typedef uint8_t BYTE; typedef uint8_t *LPBYTE; typedef uint16_t WORD; #ifdef _MSC_VER #define DWORD uint32_t #else typedef uint32_t DWORD; #endif typedef void* PVOID; typedef void* LPVOID; typedef uint32_t *LPDWORD; typedef int16_t SHORT; typedef int32_t LONG; typedef uint32_t ULONG; typedef int32_t *PLONG; typedef int64_t LONGLONG; //typedef tjs_char TCHAR; typedef size_t SIZE_T; typedef void* HANDLE; typedef void* *LPHANDLE; typedef uint32_t SOCKET; typedef void* HMODULE; typedef void* HRGN; #define CONST const #define VOID void #define IN #define OUT //#define WINAPI typedef unsigned char BYTE; typedef unsigned char *LPBYTE; typedef unsigned short WORD; typedef unsigned short UINT16; typedef short INT16; typedef unsigned int UINT_PTR; typedef unsigned int UINT; typedef unsigned int UINT32; typedef float REAL; typedef int INT; typedef signed int INT32; //typedef long long LONGLONG; typedef uint64_t ULONGLONG; typedef tjs_char *LPWSTR; typedef union _ULARGE_INTEGER { struct { DWORD LowPart; DWORD HighPart; } u; ULONGLONG QuadPart; } ULARGE_INTEGER; typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; } u; LONGLONG QuadPart; } LARGE_INTEGER; typedef char CHAR; typedef CHAR *NPSTR, *LPSTR, *PSTR; typedef const CHAR *LPCSTR; typedef struct _FILETIME { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME; typedef void *HWND; #define TYPE_RECT_DEFINED typedef struct { int left; int top; int right; int bottom; } RECT, RECTL; typedef intptr_t LONG_PTR; typedef LONG HRESULT; #define TYPE_GUID_DEFINED typedef struct { DWORD Data1; WORD Data2; WORD Data3; BYTE Data4[8]; } GUID, Guid, CLSID; #endif ================================================ FILE: src/core/environ/ui/BaseForm.cpp ================================================ #include "BaseForm.h" #include "cocos2d.h" #include "cocostudio/ActionTimeline/CSLoader.h" #include "Application.h" #include "ui/UIWidget.h" #include "cocos2d/MainScene.h" #include "ui/UIHelper.h" #include "ui/UIText.h" #include "ui/UIButton.h" #include "ui/UIListView.h" #include "Platform.h" #include "cocostudio/ActionTimeline/CCActionTimeline.h" #include "extensions/GUI/CCScrollView/CCTableView.h" using namespace cocos2d; using namespace cocos2d::ui; NodeMap::NodeMap() : FileName(nullptr) { } NodeMap::NodeMap(const char *filename, cocos2d::Node* node) : FileName(filename) { initFromNode(node); } template <> cocos2d::Node * NodeMap::findController(const std::string &name, bool notice) const { auto it = this->find(name); if (it != this->end()) return it->second; if (notice) { std::string warntext("Node "); warntext += name.c_str(); warntext += " not exist in "; warntext += FileName; TVPShowSimpleMessageBox(warntext, "Fail to load ui"); } return nullptr; } void NodeMap::initFromNode(cocos2d::Node* node) { const Vector& childlist = node->getChildren(); for (auto it = childlist.begin(); it != childlist.end(); ++it) { Node *child = *it; std::string name = child->getName(); if (!name.empty()) (*this)[name] = child; initFromNode(child); } } void NodeMap::onLoadError(const std::string &name) const { std::string warntext("Node "); warntext += name.c_str(); warntext += " wrong controller type in "; warntext += FileName; TVPShowSimpleMessageBox(warntext, "Fail to load ui"); } Node* CSBReader::Load(const char *filename) { clear(); FileName = filename; Node* ret = CSLoader::createNode(filename, [this](Ref* p){ Node* node = static_cast(p); std::string name = node->getName(); if (!name.empty()) operator[](name) = node; int nAction = node->getNumberOfRunningActions(); if (nAction == 1) { cocostudio::timeline::ActionTimeline* action = dynamic_cast(node->getActionByTag(node->getTag())); if (action && action->IsAnimationInfoExists("autoplay")) { action->play("autoplay", true); } } }); if (!ret) { TVPShowSimpleMessageBox(filename, "Fail to load ui file"); } return ret; } iTVPBaseForm::~iTVPBaseForm() { } void iTVPBaseForm::Show() { } bool iTVPBaseForm::initFromFile(const char *navibar, const char *body, const char *bottombar, cocos2d::Node *parent) { bool ret = cocos2d::Node::init(); //NaviBar.Title = nullptr; NaviBar.Left = nullptr; NaviBar.Right = nullptr; NaviBar.Root = nullptr; CSBReader reader; if (navibar) { NaviBar.Root = reader.Load(navibar); if (!NaviBar.Root) { return false; } // NaviBar.Title = static_cast(reader.findController("title")); // if (NaviBar.Title) { // NaviBar.Title->setEnabled(false); // normally // } NaviBar.Left = static_cast(reader.findController("left", false)); NaviBar.Right = static_cast(reader.findController("right", false)); bindHeaderController(reader); } BottomBar.Root = nullptr; //BottomBar.Panel = nullptr; if (bottombar) { BottomBar.Root = reader.Load(bottombar); if (!BottomBar.Root) { return false; } //BottomBar.Panel = static_cast(reader.findController("panel")); bindFooterController(reader); } RootNode = static_cast(reader.Load(body)); if (!RootNode) { return false; } if (!parent) { parent = this; } parent->addChild(RootNode); if (NaviBar.Root) parent->addChild(NaviBar.Root); if (BottomBar.Root) parent->addChild(BottomBar.Root); rearrangeLayout(); bindBodyController(reader); return ret; } void iTVPBaseForm::rearrangeLayout() { float scale = TVPMainScene::GetInstance()->getUIScale(); Size sceneSize = TVPMainScene::GetInstance()->getUINodeSize(); setContentSize(sceneSize); Size bodySize = RootNode->getParent()->getContentSize(); if (NaviBar.Root) { Size size = NaviBar.Root->getContentSize(); size.width = bodySize.width / scale; NaviBar.Root->setContentSize(size); NaviBar.Root->setScale(scale); ui::Helper::doLayout(NaviBar.Root); size.height *= scale; bodySize.height -= size.height; NaviBar.Root->setPosition(0, bodySize.height); } if (BottomBar.Root) { Size size = BottomBar.Root->getContentSize(); size.width = bodySize.width / scale; BottomBar.Root->setContentSize(size); BottomBar.Root->setScale(scale); ui::Helper::doLayout(BottomBar.Root); size.height *= scale; bodySize.height -= size.height; BottomBar.Root->setPosition(Vec2::ZERO); } if (RootNode) { bodySize.height /= scale; bodySize.width /= scale; RootNode->setContentSize(bodySize); RootNode->setScale(scale); ui::Helper::doLayout(RootNode); if (BottomBar.Root) RootNode->setPosition(Vec2(0, BottomBar.Root->getContentSize().height * scale)); } } void iTVPBaseForm::onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event) { if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK) { TVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveAniLeaveFromLeft); } } // void iTVPBaseForm::initBottomBar(std::vector > > args) { // if (!BottomBar.Panel) return; // BottomBar.Panel->removeAllItems(); // CSBReader reader; // for (auto it : args) { // Widget *root = static_cast(reader.Load(it.first.c_str())); // Widget *btn = static_cast(reader.findController("button")); // std::function func = it.second; // if (btn) btn->addClickEventListener([=](cocos2d::Ref*){ func(); }); // BottomBar.Panel->pushBackCustomItem(root); // } // } void iTVPFloatForm::rearrangeLayout() { float scale = TVPMainScene::GetInstance()->getUIScale(); Size sceneSize = TVPMainScene::GetInstance()->getUINodeSize(); setContentSize(sceneSize); Vec2 center = sceneSize / 2; sceneSize.height *= 0.75f; sceneSize.width *= 0.75f; if (RootNode) { sceneSize.width /= scale; sceneSize.height /= scale; RootNode->setContentSize(sceneSize); ui::Helper::doLayout(RootNode); RootNode->setScale(scale); RootNode->setAnchorPoint(Vec2(0.5f, 0.5f)); RootNode->setPosition(center); } } void ReloadTableViewAndKeepPos(cocos2d::extension::TableView *pTableView) { Vec2 off = pTableView->getContentOffset(); float origHeight = pTableView->getContentSize().height; pTableView->reloadData(); off.y += origHeight - pTableView->getContentSize().height; bool bounceable = pTableView->isBounceable(); pTableView->setBounceable(false); pTableView->setContentOffset(off); pTableView->setBounceable(bounceable); } ================================================ FILE: src/core/environ/ui/BaseForm.h ================================================ #pragma once #include "2d/CCNode.h" #include #include "ui/UIWidget.h" #include "extensions/GUI/CCScrollView/CCTableViewCell.h" namespace cocos2d { class Ref; class Node; namespace ui { class Widget; class Button; class Text; class ListView; class CheckBox; class PageView; class TextField; class Slider; class ScrollView; class LoadingBar; } namespace extension { class TableView; } } namespace cocostudio { namespace timeline { class ActionTimeline; } } class NodeMap : public std::unordered_map { protected: const char *FileName; void onLoadError(const std::string &name) const; public: NodeMap(); NodeMap(const char *filename, cocos2d::Node* node); template T *findController(const std::string &name, bool notice = true) const { cocos2d::Node *node = findController(name, notice); if (node) { T *ret = dynamic_cast(node); if (!ret) { onLoadError(name); } return ret; } return nullptr; } cocos2d::ui::Widget *findWidget(const std::string &name, bool notice = true) const { return findController(name, notice); } void initFromNode(cocos2d::Node* node); }; template<> cocos2d::Node *NodeMap::findController(const std::string &name, bool notice) const; class CSBReader : public NodeMap { public: cocos2d::Node* Load(const char *filename); }; class iTVPBaseForm : public cocos2d::Node { public: iTVPBaseForm() : RootNode(nullptr){} virtual ~iTVPBaseForm(); void Show(); virtual void rearrangeLayout(); virtual void onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event); protected: bool initFromFile(const char *navibar, const char *body, const char *bottombar, cocos2d::Node *parent = nullptr); bool initFromFile(const char *body) { return initFromFile(nullptr, body, nullptr); } virtual void bindBodyController(const NodeMap &allNodes) {} virtual void bindFooterController(const NodeMap &allNodes) {} virtual void bindHeaderController(const NodeMap &allNodes) {} cocos2d::ui::Widget *RootNode; struct { //cocos2d::ui::Button *Title; cocos2d::ui::Button *Left; cocos2d::ui::Widget *Right; cocos2d::Node *Root; } NaviBar; struct { //cocos2d::ui::ListView *Panel; cocos2d::Node *Root; } BottomBar; }; class TTouchEventRouter : public cocos2d::ui::Widget { public: typedef std::function EventFunc; static TTouchEventRouter *create() { TTouchEventRouter * ret = new TTouchEventRouter; ret->init(); ret->autorelease(); return ret; } void setEventFunc(const EventFunc &func) { _func = func; } virtual void interceptTouchEvent(cocos2d::ui::Widget::TouchEventType event, cocos2d::ui::Widget* sender, cocos2d::Touch *touch) override { if (_func) _func(event, sender, touch); } private: EventFunc _func; }; class TCommonTableCell : public cocos2d::extension::TableViewCell { typedef cocos2d::extension::TableViewCell inherit; protected: // must be inherited TCommonTableCell() : _router(nullptr) {} public: virtual ~TCommonTableCell() { if (_router) _router->release(); } virtual void setContentSize(const cocos2d::Size& contentSize) { inherit::setContentSize(contentSize); if (_router) _router->setContentSize(contentSize); } virtual bool init() { bool ret = inherit::init(); _router = TTouchEventRouter::create(); return ret; } protected: TTouchEventRouter *_router; }; class iTVPFloatForm : public iTVPBaseForm { public: virtual void rearrangeLayout() override; }; void ReloadTableViewAndKeepPos(cocos2d::extension::TableView *pTableView); ================================================ FILE: src/core/environ/ui/ConsoleWindow.cpp ================================================ #include "ConsoleWindow.h" #include "cocos2d/MainScene.h" using namespace cocos2d; TVPConsoleWindow::TVPConsoleWindow() { } TVPConsoleWindow* TVPConsoleWindow::create(int fontSize, cocos2d::Node *parent) { TVPConsoleWindow *ret = new TVPConsoleWindow; ret->init(); ret->setAnchorPoint(Vec2::ZERO); ret->setFontSize(fontSize); ret->autorelease(); if (parent) { ret->setContentSize(parent->getContentSize()); } return ret; } extern std::thread::id TVPMainThreadID; void TVPConsoleWindow::addLine(const ttstr &line, cocos2d::Color3B clr) { assert(TVPMainThreadID == std::this_thread::get_id()); if (_queuedLines.size() > _maxQueueSize) { _queuedLines.pop_front(); } _queuedLines.emplace_back(line, clr); } void TVPConsoleWindow::setFontSize(float size) { _fontSize = size; _maxQueueSize = getContentSize().height / size + 2; } void TVPConsoleWindow::visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags) { if (!_queuedLines.empty()) { float height = 0; std::vector _queuedLabels; for (std::pair &line : _queuedLines) { cocos2d::Label* label; if (_unusedLabels.empty()) { Size dim(getContentSize()); dim.height = 0; label = cocos2d::Label::createWithTTF("", "DroidSansFallback.ttf", _fontSize, dim); label->setAnchorPoint(Vec2::ZERO); addChild(label); } else { label = _unusedLabels.back(); _unusedLabels.pop_back(); label->setVisible(true); } label->setColor(line.second); ttstr t = line.first.length() > 200 ? line.first.SubString(0, 200) : line.first; label->setString(t.AsStdString()); label->setPosition(0, height); height += label->getContentSize().height; _queuedLabels.emplace_back(label); } Size size = getContentSize(); // remove out of range text while (!_dispLabels.empty()) { cocos2d::Label* label = _dispLabels.front(); const Vec2 &pos = label->getPosition(); if (pos.y + height > size.height) { label->setVisible(false); _unusedLabels.emplace_back(label); _dispLabels.pop_front(); } else { break; } } // adjust position for (cocos2d::Label* label : _dispLabels) { Vec2 pos = label->getPosition(); pos.y += height; label->setPosition(pos); } for (cocos2d::Label* label : _queuedLabels) { _dispLabels.emplace_back(label); } _queuedLabels.clear(); _queuedLines.clear(); } cocos2d::Node::visit(renderer, parentTransform, parentFlags); } ================================================ FILE: src/core/environ/ui/ConsoleWindow.h ================================================ #pragma once #include "2d/CCNode.h" #include "2d/CCLabel.h" #include #include #include "tjsCommHead.h" class TVPConsoleWindow : public cocos2d::Node { TVPConsoleWindow(); public: static TVPConsoleWindow* create(int fontSize, cocos2d::Node *parent); void addLine(const ttstr &line, cocos2d::Color3B clr); void setFontSize(float size); virtual void visit(cocos2d::Renderer *renderer, const cocos2d::Mat4& parentTransform, uint32_t parentFlags) override; private: float _fontSize; std::deque _dispLabels; std::vector _unusedLabels; std::deque > _queuedLines; unsigned int _maxQueueSize; }; ================================================ FILE: src/core/environ/ui/DebugViewLayerForm.cpp ================================================ #include "DebugViewLayerForm.h" #include "extensions/GUI/CCScrollView/CCTableView.h" #include "WindowIntf.h" #include "DrawDevice.h" #include "cocos2d/MainScene.h" #include #include <2d/CCSprite.h> #include <2d/CCLabel.h> #include "RenderManager.h" USING_NS_CC; USING_NS_CC_EXT; class DebugViewLayerForm::DebugViewLayerCell : public TableViewCell { public: static DebugViewLayerCell* create() { DebugViewLayerCell* ret = new DebugViewLayerCell; ret->autorelease(); ret->init(); return ret; } virtual bool init() override { TableViewCell::init(); _bottomLine = LayerColor::create(Color4B::WHITE, 100, 1); addChild(_bottomLine); _sprite = Sprite::create(); _sprite->setAnchorPoint(Vec2::ZERO); addChild(_sprite); _name = Label::createWithTTF("", "DroidSansFallback.ttf", 16); _name->setAnchorPoint(Vec2::ZERO); addChild(_name); _memsize = Label::createWithTTF("", "DroidSansFallback.ttf", 16); _memsize->setAnchorPoint(Vec2(1, 0)); addChild(_memsize); return true; } virtual void setContentSize(const Size& contentSize) override { TableViewCell::setContentSize(contentSize); _bottomLine->setContentSize(Size(contentSize.width, 2)); } void setData(const Size &laySize, const LayerInfo &data) { float left = data.Indent * 5; iTVPTexture2D *tex = data.Texture; if (tex) { _sprite->setVisible(true); Texture2D* cctex = _sprite->getTexture(); Texture2D* newtex = tex->GetAdapterTexture(cctex); float scalex, scaley; tex->GetScale(scalex, scaley); if (newtex != cctex) { _sprite->setTexture(newtex); float sw, sh; if (scalex == 1.f) sw = tex->GetWidth(); else sw = tex->GetInternalWidth(); if (scaley == 1.f) sh = tex->GetHeight(); else sh = tex->GetInternalHeight(); _sprite->setTextureRect(Rect(0, 0, sw, sh)); } _sprite->setPosition(left, 2); float r = laySize.height / tex->GetHeight(); _sprite->setScale(r * scalex, r * scaley); const char *prefix = tex->IsStatic() ? "static " : ""; char tmp[64]; sprintf(tmp, "%s[%d x %d] %.2fMB", prefix, (int)tex->GetWidth(), (int)tex->GetHeight(), data.VMemSize / (1024.f * 1024.f)); _memsize->setVisible(true); _memsize->setString(tmp); _memsize->setPosition(laySize.width, laySize.height + 2); } else { _sprite->setVisible(false); _memsize->setVisible(false); } _name->setPosition(/*left*/0, laySize.height + 2); _name->setString(data.Name); Size newSize(laySize); newSize.height += 24; setContentSize(newSize); } private: LayerColor *_bottomLine; Sprite *_sprite; Label *_name, *_memsize; }; DebugViewLayerForm * DebugViewLayerForm::create() { DebugViewLayerForm * ret = new DebugViewLayerForm; ret->autorelease(); ret->init(); return ret; } class tHackTVPDrawDevice : public tTVPDrawDevice { public: iTVPLayerManager *getPrimaryLayerManager() { return GetLayerManagerAt(PrimaryLayerManagerIndex); } }; class tHackTableView : public TableView { public: void setSwallowTouches(bool swallow) { if (_touchListener) { _touchListener->setSwallowTouches(swallow); } } }; static unsigned char _2x2_block_Image[] = { // RGBA8888 0x2F, 0x2F, 0x2F, 0xFF, 0x40, 0x40, 0x40, 0xFF, 0x40, 0x40, 0x40, 0xFF, 0x2F, 0x2F, 0x2F, 0xFF }; bool DebugViewLayerForm::init() { Node::init(); Size selfsize = TVPMainScene::GetInstance()->getGameNodeSize(); setContentSize(selfsize); Texture2D* tex = new Texture2D(); tex->autorelease(); tex->initWithData(_2x2_block_Image, 16, Texture2D::PixelFormat::RGBA8888, 2, 2, Size::ZERO); tex->setTexParameters(Texture2D::TexParams{ GL_NEAREST, GL_NEAREST, GL_REPEAT, GL_REPEAT }); Sprite *_backGround = Sprite::create(); _backGround->setTexture(tex); _backGround->setScale(16); _backGround->setTextureRect(Rect(0, 0, selfsize.width / 16, selfsize.height / 16)); //LayerColor *_backGround = LayerColor::create(Color4B(16, 16, 16, 255), selfsize.width, selfsize.height); _backGround->setAnchorPoint(Vec2::ZERO); addChild(_backGround); _tableView = TableView::create(this, getContentSize()); _tableView->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN); static_cast(_tableView)->setSwallowTouches(true); addChild(_tableView); setOnExitCallback(std::bind(&DebugViewLayerForm::onExitCallback, this)); _totalSize = Label::createWithTTF("", "DroidSansFallback.ttf", 16); _totalSize->setAnchorPoint(Vec2(1, 1)); iTVPLayerManager *manager = static_cast(TVPMainWindow->GetDrawDevice())->getPrimaryLayerManager(); uint64_t totalSize = addToLayerVec(0, "", manager->GetPrimaryLayer()); char tmp[32]; sprintf(tmp, "%.2fMB", (float)((double)totalSize / (1024.f * 1024.f))); _totalSize->setString(tmp); addChild(_totalSize); ui::Button *btnClose = ui::Button::create("img/Cancel_Normal.png", "img/Cancel_Press.png"); btnClose->setTouchEnabled(true); btnClose->addClickEventListener([this](Ref*){ removeFromParent(); }); btnClose->setPosition(getContentSize() - btnClose->getContentSize()); addChild(btnClose); _totalSize->setPosition(btnClose->getPosition().x, getContentSize().height); _tableView->reloadData(); return true; } Size DebugViewLayerForm::tableCellSizeForIndex(TableView *table, ssize_t idx) { iTVPTexture2D *tex = _layers[idx].Texture; cocos2d::Size laySize(getContentSize().width, 0); if (tex) { laySize.width = tex->GetWidth(); laySize.height = tex->GetHeight(); float maxHeight = getContentSize().height / 2.5f; if (laySize.height > maxHeight) { laySize.height = maxHeight; } } laySize.height += 24; return laySize; } cocos2d::extension::TableViewCell* DebugViewLayerForm::tableCellAtIndex(cocos2d::extension::TableView *table, ssize_t idx) { iTVPTexture2D *tex = _layers[idx].Texture; cocos2d::Size laySize(getContentSize().width, 0); if (tex) { laySize.height = tex->GetHeight(); float maxHeight = getContentSize().height / 2.5f; if (laySize.height > maxHeight) { laySize.height = maxHeight; } } DebugViewLayerCell *cell = static_cast(table->dequeueCell()); if (!cell) cell = DebugViewLayerCell::create(); cell->setData(laySize, _layers[idx]); return cell; } void DebugViewLayerForm::onExitCallback() { for (const LayerInfo& info : _layers) { if (info.Texture) info.Texture->Release(); } TVPMainScene::GetInstance()->scheduleUpdate(); } uint64_t DebugViewLayerForm::addToLayerVec(int indent, const std::string &prefix, tTJSNI_BaseLayer* lay) { if (!lay) return 0; iTVPBaseBitmap *img = lay->GetMainImage(); iTVPTexture2D *tex = nullptr; uint64_t vmemsize = 0; if (img) { tex = img->GetTexture(); tex->AddRef(); if (!TVPGetRenderManager()->GetTextureStat(tex, vmemsize)) vmemsize = 0; } std::string name(prefix + lay->GetName().AsStdString()); _layers.emplace_back(LayerInfo{ name, tex, (size_t)vmemsize, indent++ }); std::string _prefix(name); _prefix += "/"; //lay->GetOwnerNoAddRef()->AddRef(); tjs_int childCount = lay->GetCount(); for (tjs_int i = 0; i < childCount; ++i) { vmemsize += addToLayerVec(indent, _prefix, lay->GetChildren(i)); } return vmemsize; } ================================================ FILE: src/core/environ/ui/DebugViewLayerForm.h ================================================ #pragma once #include "2d/CCNode.h" #include "extensions/GUI/CCScrollView/CCTableView.h" #include "2d/CCLabel.h" class tTJSNI_BaseLayer; class iTVPTexture2D; class DebugViewLayerForm : public cocos2d::Node, public cocos2d::extension::TableViewDataSource { public: static DebugViewLayerForm *create(); virtual bool init() override; private: virtual cocos2d::Size tableCellSizeForIndex(cocos2d::extension::TableView *table, ssize_t idx) override; virtual cocos2d::extension::TableViewCell* tableCellAtIndex(cocos2d::extension::TableView *table, ssize_t idx) override; virtual ssize_t numberOfCellsInTableView(cocos2d::extension::TableView *table) override { return _layers.size(); } void onExitCallback(); uint64_t addToLayerVec(int indent, const std::string &prefix, tTJSNI_BaseLayer* lay); class DebugViewLayerCell; struct LayerInfo { std::string Name; iTVPTexture2D *Texture; size_t VMemSize; int Indent; }; cocos2d::Label *_totalSize; cocos2d::extension::TableView *_tableView; // pair std::vector _layers; }; ================================================ FILE: src/core/environ/ui/FileSelectorForm.cpp ================================================ #include "FileSelectorForm.h" #include "StorageImpl.h" #include "ui/UIListView.h" #include "ui/UIHelper.h" #include "ui/UIButton.h" #include "ui/UIText.h" #include "ui/UITextField.h" #include "ui/UICheckBox.h" #include "Platform.h" #include "cocos2d/MainScene.h" #include "cocostudio/ActionTimeline/CSLoader.h" #include "ConfigManager/LocaleConfigManager.h" #include "platform/CCFileUtils.h" #include "base/CCDirector.h" #include "MessageBox.h" #include "platform/CCDevice.h" #include "base/CCScheduler.h" #include "utils/TickCount.h" #include using namespace cocos2d; using namespace cocos2d::extension; using namespace cocos2d::ui; extern std::thread::id TVPMainThreadID; const char * const FileName_Cell = "ui/FileItem.csb"; static TVPListForm* _listform; #define MOVE_INCH 7.0f/160.0f static const std::string str_long_press("long_press"); static float convertDistanceFromPointToInch(const Vec2& dis) { auto glview = cocos2d::Director::getInstance()->getOpenGLView(); int dpi = cocos2d::Device::getDPI(); float distance = Vec2(dis.x * glview->getScaleX() / dpi, dis.y * glview->getScaleY() / dpi).getLength(); return distance; } static bool IsPathExist(const std::string &path) { tTVP_stat s; if (!TVP_stat(path.c_str(), s)) { return false; // not exist } return true; } std::pair TVPBaseFileSelectorForm::PathSplit(const std::string &path) { std::pair ret; if (path.size() <= 1) { ret.second = path; return ret; } for (auto it = path.end() - 1; it > path.begin(); --it) { switch (*it) { case '/': case '\\': if (it == path.end() - 1) { ret.second = path; return ret; } ret.first = std::string(path.begin(), it); ret.second = std::string(it + 1, path.end()); while(!ret.first.empty()) { char c = ret.first.back(); if (c == '/' || c == '\\') { ret.first.pop_back(); } else { break; } } #if CC_PLATFORM_WIN32 != CC_TARGET_PLATFORM && CC_PLATFORM_WINRT != CC_TARGET_PLATFORM && CC_PLATFORM_WP8 != CC_TARGET_PLATFORM if (ret.first.empty()) ret.first = "/"; // posix root #endif return ret; default: break; } } ret.second = path; return ret; } TVPBaseFileSelectorForm::TVPBaseFileSelectorForm() : FileList(nullptr) { std::vector paths; getShortCutDirList(paths); // for init std::vector appPath = TVPGetAppStoragePath(); if (appPath.empty() && paths.size() == 1) { // ios-like sandbox environment RootPathLen = paths.front().size(); } } TVPBaseFileSelectorForm::~TVPBaseFileSelectorForm() { CC_SAFE_RELEASE_NULL(CellTemplateForSize); } void TVPBaseFileSelectorForm::bindHeaderController(const NodeMap &allNodes) { _title = static_cast(allNodes.findController("title")); if (_title) { _title->setEnabled(true); _title->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onTitleClicked, this, std::placeholders::_1)); } } void TVPBaseFileSelectorForm::bindBodyController(const NodeMap &allNodes) { Node *TableNode = allNodes.findController("table"); FileList = TableView::create(this, TableNode->getContentSize()); FileList->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN); FileList->setAnchorPoint(Vec2::ZERO); FileList->setClippingToBounds(false); TableNode->addChild(FileList); // ListView::ccListViewCallback func = [this](Ref* cell, ListView::EventType e){ // if (e == ListView::EventType::ON_SELECTED_ITEM_END) { // onCellClicked(static_cast(cell)->getCurSelectedIndex()); // } // }; // FileList->addEventListener(func); if (NaviBar.Left) { NaviBar.Left->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onBackClicked, this, std::placeholders::_1)); } } static const std::string _path_current("."); static const std::string _path_parent(".."); static const std::string str_diricon("dir_icon"); static const std::string str_select("select_check"); static const std::string str_filename("filename"); void TVPBaseFileSelectorForm::ListDir(std::string path) { std::pair split_path = PathSplit(path); ParentPath = split_path.first; if (_title) { #if CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM // for better screenshot _title->setTitleFontName("SIMHEI.ttf"); if (!split_path.second.empty() && (split_path.second.back() == '/' || split_path.second.back() == '\\')) { split_path.second.pop_back(); } #endif _title->setTitleText(split_path.second); Size dispSize = _title->getTitleRenderer()->getContentSize(); Size realSize = _title->getContentSize(); if (dispSize.width > realSize.width) { const std::string suffix("..."); _title->setTitleText(suffix); float suffixlen = _title->getTitleRenderer()->getContentSize().width * 1.5; float ratio = (realSize.width - suffixlen) / dispSize.width; ttstr path = split_path.second; int charCutCount = path.length() * ratio - suffix.size() + 1; path = path.SubString(0, charCutCount); _title->setTitleText(path.AsStdString() + suffix); } } if (path.size() > RootPathLen && path.back() == '/') { path.pop_back(); } if (NaviBar.Left) { NaviBar.Left->setVisible(path.size() > RootPathLen); } CurrentDirList.clear(); CurrentDirList.reserve(16); TVPListDir(path, [&](const std::string &name, int mask) { if (mask & (S_IFREG | S_IFDIR)) { if (name.empty() || name.front() == '.') return; CurrentDirList.resize(CurrentDirList.size() + 1); FileInfo &info = CurrentDirList.back(); info.NameForDisplay = name; info.NameForCompare = name; info.IsDir = mask & S_IFDIR; std::transform(info.NameForCompare.begin(), info.NameForCompare.end(), info.NameForCompare.begin(), [](int c)->int { if (c <= 'Z' && c >= 'A') return c - ('A' - 'a'); return c; }); } }); // fill fullpath for (auto it = CurrentDirList.begin(); it != CurrentDirList.end(); ++it) { it->FullPath = path + "/" + it->NameForDisplay; } std::sort(CurrentDirList.begin(), CurrentDirList.end()); // update bool keepPos = CurrentPath == path; CurrentPath = path; if (keepPos) { ReloadTableViewAndKeepPos(FileList); } else { FileList->reloadData(); } if (!_selectedFileIndex.empty()) { _selectedFileIndex.clear(); updateFileMenu(); } else if (_clipboardForFileManager.size()) { updateFileMenu(); } } void TVPBaseFileSelectorForm::onCellClicked(int idx) { const FileInfo &info = CurrentDirList[idx]; if (info.IsDir) { ListDir(info.FullPath); } } void TVPBaseFileSelectorForm::onCellLongPress(int idx) { if (_fileOperateMenuNode) { // full file function if (!_selectedFileIndex.empty()) { return; } if (!_fileOperateMenu) { CSBReader reader; _fileOperateMenu = reader.Load("ui/FileManageMenu.csb"); LocaleConfigManager::GetInstance()->initText(reader.findController("title")); LocaleConfigManager::GetInstance()->initText(reader.findController("titleUnselect")); LocaleConfigManager::GetInstance()->initText(reader.findController("titleView", false)); LocaleConfigManager::GetInstance()->initText(reader.findController("titleCopy")); LocaleConfigManager::GetInstance()->initText(reader.findController("titleCut")); LocaleConfigManager::GetInstance()->initText(reader.findController("titlePaste")); LocaleConfigManager::GetInstance()->initText(reader.findController("titleUnpack")); LocaleConfigManager::GetInstance()->initText(reader.findController("titleDelete")); LocaleConfigManager::GetInstance()->initText(reader.findController("titleSendTo")); LocaleConfigManager::GetInstance()->initText(reader.findController("titleRename")); _fileOperateMenulist = reader.findController("list"); _fileOperateCell_unselect = reader.findWidget("unselect"); _fileOperateCell_view = reader.findWidget("view", false); _fileOperateCell_copy = reader.findWidget("copy"); _fileOperateCell_cut = reader.findWidget("cut"); _fileOperateCell_paste = reader.findWidget("paste"); _fileOperateCell_delete = reader.findWidget("delete"); _fileOperateCell_unpack = reader.findWidget("unpack", false); _fileOperateCell_sendto = reader.findWidget("sendto"); _fileOperateCell_rename = reader.findWidget("rename", false); Widget *btn;; if ((btn = reader.findWidget("btnUnselect"))) { btn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onUnselectClicked, this, std::placeholders::_1)); } if ((btn = reader.findWidget("btnView", false))) { btn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onViewClicked, this, std::placeholders::_1)); } if ((btn = reader.findWidget("btnCopy"))) { btn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onCopyClicked, this, std::placeholders::_1)); } if ((btn = reader.findWidget("btnCut"))) { btn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onCutClicked, this, std::placeholders::_1)); } if ((btn = reader.findWidget("btnPaste"))) { btn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onPasteClicked, this, std::placeholders::_1)); } if ((btn = reader.findWidget("btnUnpack", false))) { btn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onUnpackClicked, this, std::placeholders::_1)); } if ((btn = reader.findWidget("btnDelete"))) { btn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onDeleteClicked, this, std::placeholders::_1)); } if ((btn = reader.findWidget("btnSendTo"))) { btn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onSendToClicked, this, std::placeholders::_1)); } if ((btn = reader.findWidget("btnRename"))) { btn->addClickEventListener(std::bind(&TVPBaseFileSelectorForm::onBtnRenameClicked, this, std::placeholders::_1)); } _fileOperateMenulist->removeAllChildrenWithCleanup(false); float scale = 1.5; _fileOperateMenu->setScale(1 / scale); _fileOperateMenu->setContentSize(_fileOperateMenuNode->getContentSize() * scale); _fileOperateMenu->setPosition(_fileOperateMenuNode->getPosition()); _fileOperateMenuNode->getParent()->addChild(_fileOperateMenu); ui::Helper::doLayout(_fileOperateMenu); _fileOperateMenu->setVisible(false); } if (!_fileOperateMenu->isVisible()) { _fileOperateMenu->setVisible(true); // _fileOperateMenu->setAnchorPoint(Vec2(1, 0)); } FileList->setTouchEnabled(false); // trick to release all touches FileList->setTouchEnabled(true); _selectedFileIndex.clear(); _selectedFileIndex.insert(idx); updateFileMenu(); return; } // simple file manage LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); const char *btnTitles[] = { localeMgr->GetText("delete").c_str(), localeMgr->GetText("cancel").c_str(), }; int n = TVPShowSimpleMessageBox( localeMgr->GetText("file_operate_menu_text").c_str(), localeMgr->GetText("file_operate_menu_title").c_str(), sizeof(btnTitles) / sizeof(btnTitles[0]), btnTitles); const FileInfo &info = CurrentDirList[idx]; switch (n) { case 0: _selectedFileIndex.insert(idx); onDeleteClicked(nullptr); _selectedFileIndex.clear(); break; default: break; } } void TVPBaseFileSelectorForm::getShortCutDirList(std::vector &pathlist) { std::vector paths = TVPGetDriverPath(); for (const std::string &path : paths) { pathlist.emplace_back(path); } std::vector appPath = TVPGetAppStoragePath(); for (auto path : appPath) { cocos2d::log("appPath: %s", path.c_str()); pathlist.emplace_back(path); } } void TVPBaseFileSelectorForm::onTitleClicked(cocos2d::Ref *owner) { if (_listform) return; std::vector paths; getShortCutDirList(paths); std::vector cells; std::vector buttons; auto func = [this](cocos2d::Ref* node) { // __android_log_print(ANDROID_LOG_INFO, "## krkr2yuri", "onTitleClicked listener %p", node); ListDir(static_cast(node)->getCallbackName()); TVPMainScene::GetInstance()->popUIForm(nullptr, TVPMainScene::eLeaveToBottom); }; for (const std::string &path : paths) { CSBReader reader; Widget *cell = static_cast(reader.Load("ui/ListItem.csb")); Button *item = dynamic_cast(reader.findController("item")); __android_log_print(ANDROID_LOG_INFO, "## krkr2yuri", "onTitleClicked path=%s, cell=%p, item=%p, func=%p", path.c_str(), cell, item, func); // ## fix Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x39 cocos2d::ui::LinearLayoutParameter::setGravity // Widget Inherits ProtectedNode, and LayoutParameterProtocol. // Widget* cell2 = new Widget(); // cell2->setContentSize(cell->getContentSize()); // cell2->addChild(item); item->setContentSize(cell->getContentSize()); item->setCallbackName(path); item->setTitleText(path); item->addClickEventListener(func); // ## fixme, button click position error cells.emplace_back(item); buttons.emplace_back(item); } _listform = TVPListForm::create(cells); _listform->show(); // march all button's text in its width for (Button* btn : buttons) { Size dispSize = btn->getTitleRenderer()->getContentSize(); Size realSize = btn->getContentSize(); if (dispSize.width > realSize.width) { std::string text = btn->getTitleText(); float ratio = realSize.width / dispSize.width; const std::string prefix("..."); int charCutCount = text.size() * (1 - ratio) + prefix.size() + 1; btn->setTitleText(prefix + text.substr(charCutCount)); } } } void TVPBaseFileSelectorForm::onBackClicked(cocos2d::Ref *owner) { ListDir(ParentPath); } TVPBaseFileSelectorForm::FileItemCellImpl* TVPBaseFileSelectorForm::FetchCell(FileItemCellImpl* CellModel, cocos2d::extension::TableView *table, ssize_t idx) { if (!CellModel) { CellModel = FileItemCellImpl::create(FileName_Cell, table->getViewSize().width); CellModel->setAnchorPoint(Vec2::ZERO); CellModel->setEventFunc([this](Widget::TouchEventType ev, Widget* sender, Touch *touch){ Vec2 touchPoint = touch->getLocation(); switch (ev) { case Widget::TouchEventType::BEGAN: FileList->onTouchBegan(touch, nullptr); break; case Widget::TouchEventType::MOVED: FileList->onTouchMoved(touch, nullptr); if (sender->isHighlighted() && convertDistanceFromPointToInch(sender->getTouchBeganPosition() - touchPoint) > MOVE_INCH) { sender->setHighlighted(false); } break; case Widget::TouchEventType::CANCELED: FileList->onTouchCancelled(touch, nullptr); break; case Widget::TouchEventType::ENDED: FileList->onTouchEnded(touch, nullptr); break; } }); CellModel->retain(); } bool selected = _selectedFileIndex.find(idx) != _selectedFileIndex.end(); CellModel->setInfo(idx, CurrentDirList[idx], selected, !_selectedFileIndex.empty()); return CellModel; } TableViewCell* TVPBaseFileSelectorForm::tableCellAtIndex(TableView *table, ssize_t idx) { TableViewCell *pCell = table->dequeueCell(); FileItemCell *cell = nullptr; if (pCell) { cell = static_cast(pCell); } else { cell = FileItemCell::create(this); } if ((size_t)idx >= CurrentDirList.size()) { cell->setVisible(false); return cell; } cell->setVisible(true); FileItemCellImpl *impl = cell->detach(); cell->attach(FetchCell(impl, table, idx)); return cell; } ssize_t TVPBaseFileSelectorForm::numberOfCellsInTableView(TableView *table) { return CurrentDirList.empty() ? 0 : CurrentDirList.size() + 1; } Size TVPBaseFileSelectorForm::tableCellSizeForIndex(TableView *table, ssize_t idx) { if ((size_t)idx >= CurrentDirList.size()) { return Size(table->getContentSize().width, 200); } FileInfo &info = CurrentDirList[idx]; if (info.CellSize.width == 0.f) { if (!CellTemplateForSize) { CellTemplateForSize = FetchCell(nullptr, table, idx); } else { CellTemplateForSize->setInfo(idx, CurrentDirList[idx], false, false); } info.CellSize = CellTemplateForSize->getContentSize(); } return info.CellSize; } void TVPBaseFileSelectorForm::rearrangeLayout() { iTVPBaseForm::rearrangeLayout(); if (FileList) FileList->setViewSize(FileList->getParent()->getContentSize()); } void TVPBaseFileSelectorForm::onUnselectClicked(cocos2d::Ref *owner) { clearFileMenu(); } void TVPBaseFileSelectorForm::onViewClicked(cocos2d::Ref *owner) { } void TVPBaseFileSelectorForm::onCopyClicked(cocos2d::Ref *owner) { _clipboardForMoving = false; _clipboardForFileManager.clear(); for (int idx : _selectedFileIndex) { _clipboardForFileManager.emplace_back(CurrentDirList[idx].FullPath); } _clipboardPath = CurrentPath; _selectedFileIndex.clear(); updateFileMenu(); } void TVPBaseFileSelectorForm::onCutClicked(cocos2d::Ref *owner) { onCopyClicked(owner); _clipboardForMoving = true; } void TVPBaseFileSelectorForm::onPasteClicked(cocos2d::Ref *owner) { // TODO progress bar auto func = _clipboardForMoving ? TVPRenameFile : TVPCopyFile; for (const std::string &path : _clipboardForFileManager) { auto split_path = PathSplit(path); std::string target = CurrentPath + "/" + split_path.second; if (IsPathExist(target)) { LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); if (TVPShowSimpleMessageBoxYesNo(target, localeMgr->GetText("ensure_to_override_file")) != 0) { continue; } } if (!func(path, target)) { LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); TVPShowSimpleMessageBox(target, localeMgr->GetText("file_operate_failed")); break; } } clearFileMenu(); ListDir(CurrentPath); } void TVPBaseFileSelectorForm::onUnpackClicked(cocos2d::Ref *owner) { if (_selectedFileIndex.size() != 1) { return; } FileInfo &info = CurrentDirList[*_selectedFileIndex.begin()]; _selectedFileIndex.clear(); clearFileMenu(); ttstr outpath = TVPChopStorageExt(info.FullPath); class UnpackArchive { const int UpdateMS = 100; // update rate 10 fps tTVPUnpackArchive ArcUnpacker; std::string ArcPath; std::string PasswordBuffer; public: bool Init(const std::string &path, const std::string &outpath) { ArcPath = path; ArcUnpacker.SetCallback( std::bind(&UnpackArchive::OnEnded, this), std::bind(&UnpackArchive::OnError, this, std::placeholders::_1, std::placeholders::_2), std::bind(&UnpackArchive::OnProgress, this, std::placeholders::_1, std::placeholders::_2), std::bind(&UnpackArchive::OnNewFile, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::bind(&UnpackArchive::OnPassword, this) ); if (ArcUnpacker.Prepare(path, outpath, &TotalSize) <= 0) { return false; } if (TotalSize > 1024 * 1024) { ProgressForm = TVPSimpleProgressForm::create(); TVPMainScene::GetInstance()->pushUIForm(ProgressForm, TVPMainScene::eEnterAniNone); std::vector > > vecButtons; vecButtons.emplace_back("Stop", [this](Ref*) { ArcUnpacker.Stop(); }); ProgressForm->initButtons(vecButtons); ProgressForm->setTitle("Unpacking..."); ProgressForm->setPercentOnly(0); ProgressForm->setPercentOnly2(0); ProgressForm->setPercentText(""); ProgressForm->setPercentText2(""); ProgressForm->setContent(""); } return true; } virtual ~UnpackArchive() { if (ProgressForm) { TVPMainScene::GetInstance()->popUIForm(ProgressForm, TVPMainScene::eLeaveAniNone); ProgressForm = nullptr; } } void Start(const std::function &onEnded) { FuncOnEnded = onEnded; ArcUnpacker.Start(); } private: void OnEnded() { Director::getInstance()->getScheduler()->performFunctionInCocosThread([this] { if (FuncOnEnded) FuncOnEnded(); delete this; }); } void OnError(int err, const char *msg) { Director::getInstance()->getScheduler()->performFunctionInCocosThread([this, err, msg] { char buf[64]; sprintf(buf, "Error %d\n", err); ttstr strmsg(buf); strmsg += msg; TVPShowSimpleMessageBox(strmsg, TJS_W("Fail to unpack archive")); }); } void OnProgress(tjs_uint64 total_size, tjs_uint64 file_size) { if (!ProgressForm) return; tjs_uint32 tick = TVPGetRoughTickCount32(); if ((int)(tick - LastUpdate) < UpdateMS) { return; } LastUpdate = tick; Director::getInstance()->getScheduler()->performFunctionInCocosThread([this, total_size, file_size] { ProgressForm->setPercentOnly((float)total_size / TotalSize); ProgressForm->setPercentOnly2((float)file_size / CurrentFileSize); char buf[64]; int sizeMB = static_cast(total_size / (1024 * 1024)), totalMB = static_cast(TotalSize / (1024 * 1024)); sprintf(buf, "%d / %dMB", sizeMB, totalMB); ProgressForm->setPercentText(buf); sizeMB = static_cast(file_size / (1024 * 1024)); totalMB = static_cast(CurrentFileSize / (1024 * 1024)); sprintf(buf, "%d / %dMB", sizeMB, totalMB); ProgressForm->setPercentText2(buf); }); } void OnNewFile(int idx, const std::string &utf8name, tjs_uint64 file_size) { if (!ProgressForm) return; tjs_uint32 tick = TVPGetRoughTickCount32(); if ((int)(tick - LastUpdate) < UpdateMS && file_size < 1024 * 1024) { return; } LastUpdate = tick; CurrentFileSize = file_size; std::string filename(utf8name); Director::getInstance()->getScheduler()->performFunctionInCocosThread([this, filename] { ProgressForm->setContent(filename); }); } bool _onPassword() { LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); std::vector btns; btns.emplace_back(localeMgr->GetText("ok")); btns.emplace_back(localeMgr->GetText("cancel")); ttstr text(ArcPath); if (TVPShowSimpleInputBox(text, localeMgr->GetText("please_input_password"), "", btns) == 0) { PasswordBuffer = text.AsStdString(); return true; } else { ArcUnpacker.Stop(); PasswordBuffer.clear(); return false; } } std::string OnPassword() { if (TVPMainThreadID == std::this_thread::get_id()) { _onPassword(); } else { std::mutex mtx; std::condition_variable cond; std::unique_lock lk(mtx); Director::getInstance()->getScheduler()->performFunctionInCocosThread([&]() { _onPassword(); cond.notify_all(); }); cond.wait(lk); } return PasswordBuffer; } TVPSimpleProgressForm *ProgressForm = nullptr; tjs_uint32 LastUpdate = 0; tjs_uint64 TotalSize, CurrentFileSize; std::function FuncOnEnded; }; UnpackArchive *unpacker = new UnpackArchive; // using libarchive to unpack archive if (unpacker->Init(info.FullPath, outpath.AsStdString())) { unpacker->Start([this]() { ListDir(CurrentPath); }); return; } delete unpacker; // use internal archive module tTVPArchive *arc = TVPOpenArchive(info.FullPath, false); if (!arc) { LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); TVPShowSimpleMessageBox(info.FullPath, localeMgr->GetText("fail_to_open_archive")); return; } tjs_uint count = arc->GetCount(); for (tjs_uint i = 0; i < count; ++i) { ttstr name = arc->GetName(i); ttstr fullpath = outpath + name; tTJSBinaryStream *st = arc->CreateStreamByIndex(i); if (!st) continue; TVPSaveStreamToFile(st, 0, st->GetSize(), fullpath); delete st; } delete arc; } void TVPBaseFileSelectorForm::onDeleteClicked(cocos2d::Ref *owner) { LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); std::string content; if (_selectedFileIndex.size() == 1) { const FileInfo &info = CurrentDirList[*_selectedFileIndex.begin()]; content = info.FullPath; } else { content = localeMgr->GetText("ensure_item_count"); char tmp[64]; snprintf(tmp, 64, content.c_str(), _selectedFileIndex.size()); content = tmp; } if (TVPShowSimpleMessageBoxYesNo(content, localeMgr->GetText("ensure_to_delete_file")) == 0) { for (int idx : _selectedFileIndex) { TVPDeleteFile(CurrentDirList[idx].FullPath); } scheduleOnce([this](float) { ListDir(CurrentPath); }, 0, "refresh_path"); } } void TVPBaseFileSelectorForm::onSendToClicked(cocos2d::Ref *owner) { if (_selectedFileIndex.size() != 1) return; FileInfo &info = CurrentDirList[*_selectedFileIndex.begin()]; TVPSendToOtherApp(info.FullPath); clearFileMenu(); } void TVPBaseFileSelectorForm::onBtnRenameClicked(cocos2d::Ref *owner) { if (_selectedFileIndex.size() != 1) return; FileInfo &info = CurrentDirList[*_selectedFileIndex.begin()]; ttstr name = info.NameForDisplay.c_str(); std::vector btns; btns.emplace_back("OK"); btns.emplace_back("Cancel"); if (TVPShowSimpleInputBox(name, "Input new name", "", btns) == 0) { ttstr newname = TVPExtractStoragePath(info.FullPath); newname += name; std::string strNewName = newname.AsNarrowStdString(); TVPRenameFile(info.FullPath, strNewName); info.FullPath = strNewName; info.NameForDisplay = name.AsNarrowStdString(); ReloadTableViewAndKeepPos(FileList); } clearFileMenu(); } void TVPBaseFileSelectorForm::updateFileMenu() { ReloadTableViewAndKeepPos(FileList); if (_selectedFileIndex.empty() && _clipboardForFileManager.empty()) { // close menu if (_fileOperateMenu->isVisible()) { _fileOperateMenu->setVisible(false); // _fileOperateMenu->setAnchorPoint(Vec2(0, 0)); } return; } _fileOperateMenulist->removeAllChildrenWithCleanup(false); _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_unselect.get()); if (!_clipboardForFileManager.empty() && _clipboardPath != CurrentPath) { _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_paste.get()); } if (_selectedFileIndex.size() == 1) { if (_fileOperateCell_view) _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_view.get()); FileInfo &info = CurrentDirList[*_selectedFileIndex.begin()]; if (!info.IsDir) _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_unpack.get()); _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_rename.get()); #if CC_PLATFORM_IOS == CC_TARGET_PLATFORM // TODO implement other platform _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_sendto.get()); #endif } if (!_selectedFileIndex.empty()) { _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_copy.get()); _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_cut.get()); _fileOperateMenulist->pushBackCustomItem(_fileOperateCell_delete.get()); } } void TVPBaseFileSelectorForm::clearFileMenu() { _selectedFileIndex.clear(); _clipboardForFileManager.clear(); updateFileMenu(); } void TVPBaseFileSelectorForm::_onCellClicked(int idx) { if (_selectedFileIndex.empty()) return onCellClicked(idx); auto it = _selectedFileIndex.find(idx); if (it == _selectedFileIndex.end()) { _selectedFileIndex.insert(idx); } else { _selectedFileIndex.erase(idx); } updateFileMenu(); } bool TVPBaseFileSelectorForm::FileInfo::operator<(const FileInfo &rhs) const { if (IsDir != rhs.IsDir) return IsDir > rhs.IsDir; return NameForCompare < rhs.NameForCompare; } TVPListForm * TVPListForm::create(const std::vector &cells) { TVPListForm *ret = new TVPListForm; ret->initFromInfo(cells); ret->autorelease(); return ret; } void TVPListForm::initFromInfo(const std::vector &cells) { init(); float scale = TVPMainScene::GetInstance()->getUIScale(); cocos2d::Size sceneSize = TVPMainScene::GetInstance()->getUINodeSize() / scale; setScale(scale); setContentSize(sceneSize); CSBReader reader; _root = reader.Load("ui/ListView.csb"); ListView* listview = dynamic_cast(reader.findController("list")); float height = 10; for (Widget* cell : cells) { height += cell->getContentSize().height; } _root->setAnchorPoint(Size(0.5, 0.5)); _root->setPosition(sceneSize / 2); sceneSize.width *= 0.8f; sceneSize.height *= 0.8f; if (height < sceneSize.height * scale) { sceneSize.height = height; } _root->setContentSize(sceneSize); ui::Helper::doLayout(_root); float width = listview->getContentSize().width; int i=0; for (Widget* cell : cells) { Size size = cell->getContentSize(); size.width = width; cell->setContentSize(size); ui::Helper::doLayout(cell); listview->pushBackCustomItem(cell); } if(!listview->getItems().empty()) { if (listview->getItems().back()->getBottomBoundary() < 0) { listview->setClippingEnabled(true); } else { listview->setBounceEnabled(false); } } addChild(_root); // __android_log_print(ANDROID_LOG_INFO, "## krkr2yuri", "after initFromInfo"); } void TVPListForm::show() { TVPMainScene::setMaskLayTouchBegain(std::bind(&TVPListForm::onMaskTouchBegan, this, std::placeholders::_1, std::placeholders::_2)); TVPMainScene::GetInstance()->pushUIForm(this, TVPMainScene::eEnterFromBottom); } bool TVPListForm::onMaskTouchBegan(cocos2d::Touch *t, cocos2d::Event *) { Rect rc; rc.size = getContentSize(); if (rc.containsPoint(convertTouchToNodeSpace(t))) { TVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveToBottom); return true; } return false; } TVPListForm::~TVPListForm() { if (_listform == this) _listform = nullptr; } int TVPDrawSceneOnce(int interval); void TVPProcessInputEvents(); std::string TVPShowFileSelector(const std::string &title, const std::string &initfilename, std::string initdir, bool issave) { if (initdir.empty()) { ttstr dir = TVPGetAppPath(); TVPGetLocalName(dir); initdir = dir.AsStdString(); } std::string _fileSelectorResult; TVPFileSelectorForm* _fileSelector = TVPFileSelectorForm::create(initfilename, initdir, issave); _fileSelector->setOnClose([&](const std::string &result) { _fileSelectorResult = result; _fileSelector = nullptr; }); TVPMainScene::GetInstance()->pushUIForm(_fileSelector); Director* director = Director::getInstance(); while (_fileSelector) { TVPProcessInputEvents(); int remain = TVPDrawSceneOnce(30); // 30 fps if (remain > 0) { std::this_thread::sleep_for(std::chrono::milliseconds(remain)); } } return _fileSelectorResult; } const char * const FileName_NaviBar = "ui/NaviBar.csb"; const char * const FileName_Body = "ui/TableView.csb"; const char * const FileName_BottomBar = "ui/BottomBarTextInput.csb"; TVPFileSelectorForm * TVPFileSelectorForm::create(const std::string &initfilename, const std::string &initdir, bool issave) { TVPFileSelectorForm *ret = new TVPFileSelectorForm; ret->autorelease(); ret->initFromPath(initfilename, initdir, issave); return ret; } void TVPFileSelectorForm::initFromPath(const std::string &initfilename, const std::string &initdir, bool issave) { _isSaveMode = issave; initFromFile(FileName_NaviBar, FileName_Body, FileName_BottomBar); _input->setString(initfilename); ListDir(initdir); // getCurrentDir() } void TVPFileSelectorForm::bindFooterController(const NodeMap &allNodes) { _buttonOK = static_cast(allNodes.findController("ok")); _buttonCancel = static_cast(allNodes.findController("cancel")); _input = static_cast(allNodes.findController("input")); LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); localeMgr->initText(_buttonOK, "ok"); localeMgr->initText(_buttonCancel, "cancel"); _buttonOK->addClickEventListener([this](Ref*){ _result = _input->getString(); if (!_result.empty()) { _result = CurrentPath + "/" + _result; bool fileExist = FileUtils::getInstance()->isFileExist(_result); if (_isSaveMode) { if (fileExist) { LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); TVPMessageBoxForm::showYesNo(localeMgr->GetText("ensure_to_override_file"), _result, [this](int result) { if (result == 0) { // yes close(); } }); } else { close(); } } else { // read mode if (fileExist) { close(); } } } }); _buttonCancel->addClickEventListener([this](Ref*){ _result.clear(); close(); }); } void TVPFileSelectorForm::onCellClicked(int idx) { FileInfo info = CurrentDirList[idx]; TVPBaseFileSelectorForm::onCellClicked(idx); if (info.IsDir) { } else { _input->setString(info.NameForDisplay); } } void TVPFileSelectorForm::close() { if (_funcOnClose) _funcOnClose(_result); TVPMainScene::GetInstance()->popUIForm(this); } void TVPBaseFileSelectorForm::FileItemCellImpl::initFromFile(const char * filename, float width) { CSBReader reader; _root = reader.Load(filename); addChild(_root); OrigCellModelSize = _root->getContentSize(); OrigCellModelSize.width = width; _root->setContentSize(OrigCellModelSize); setContentSize(OrigCellModelSize); DirIcon = reader.findController(str_diricon); SelectBox = reader.findController(str_select); //SelectBox->setTouchEnabled(false); FileNameNode = static_cast(reader.findController(str_filename)); if (DirIcon && FileNameNode) { CellTextAreaSize = DirIcon->getContentSize(); CellTextAreaSize.width = OrigCellModelSize.width - CellTextAreaSize.width; CellTextAreaSize.height = 0; OrigCellTextSize = FileNameNode->getContentSize(); #if CC_PLATFORM_WIN32 == CC_TARGET_PLATFORM FileNameNode->setFontName("SIMHEI.ttf"); #endif } static const std::string str_highlight("highlight"); Widget *HighLight = static_cast(reader.findController(str_highlight)); if (HighLight) { HighLight->addClickEventListener(std::bind(&FileItemCellImpl::onClicked, this, std::placeholders::_1)); HighLight->addTouchEventListener([this](Ref* p, Widget::TouchEventType ev){ Widget* sender = static_cast(p); switch (ev) { case Widget::TouchEventType::BEGAN: sender->scheduleOnce([this, sender](float){ if (sender->isHighlighted()) { sender->scheduleOnce([this, sender](float){ _owner->onLongPress(); sender->setHighlighted(false); // sender->interceptTouchEvent(TouchEventType::CANCELED, sender, touch); }, 0, "delay_call"); } }, 1.0f, str_long_press); break; // ## fix scole bug case Widget::TouchEventType::MOVED: { auto diff = sender->getTouchMovePosition() - sender->getTouchBeganPosition(); if (abs(diff.x) > 5 and abs(diff.y) > 5) { sender->unschedule(str_long_press); } break; } case Widget::TouchEventType::CANCELED: sender->unschedule(str_long_press); break; } }); HighLight->setSwallowTouches(false); } BgOdd = reader.findController("bg_odd", false); BgEven = reader.findController("bg_even", false); } void TVPBaseFileSelectorForm::FileItemCellImpl::setInfo(int idx, const FileInfo &info, bool selected, bool showSelect) { if (FileNameNode) { FileNameNode->ignoreContentAdaptWithSize(true); FileNameNode->setTextAreaSize(CellTextAreaSize); FileNameNode->setString(info.NameForDisplay); Size size(OrigCellModelSize); size.height += FileNameNode->getContentSize().height - OrigCellTextSize.height; _root->setContentSize(size); setContentSize(size); FileNameNode->ignoreContentAdaptWithSize(false); } if (DirIcon) DirIcon->setVisible(info.IsDir && !showSelect); SelectBox->setVisible(showSelect); if (showSelect) SelectBox->setSelected(selected); ui::Helper::doLayout(_root); _set = true; if (BgOdd) BgOdd->setVisible((idx + 1) & 1); if (BgEven) BgEven->setVisible(idx & 1); } void TVPBaseFileSelectorForm::FileItemCellImpl::onClicked(cocos2d::Ref* p) { Widget* sender = static_cast(p); if (sender->isScheduled(str_long_press)) { sender->unschedule(str_long_press); _owner->onClicked(); } } ================================================ FILE: src/core/environ/ui/FileSelectorForm.h ================================================ #pragma once #include "BaseForm.h" #include "GUI/CCScrollView/CCTableView.h" #include "base/CCRefPtr.h" class TVPListForm : public cocos2d::Node { public: virtual ~TVPListForm();; static TVPListForm * create(const std::vector &cells); void initFromInfo(const std::vector &cells); void show(); // for background fading void close(); private: bool onMaskTouchBegan(cocos2d::Touch *t, cocos2d::Event *); cocos2d::Node *_root; }; class TVPFileOperateMenu; class TVPBaseFileSelectorForm : public iTVPBaseForm, public cocos2d::extension::TableViewDataSource { public: TVPBaseFileSelectorForm(); virtual ~TVPBaseFileSelectorForm(); virtual cocos2d::Size tableCellSizeForIndex(cocos2d::extension::TableView *table, ssize_t idx) override; virtual cocos2d::extension::TableViewCell* tableCellAtIndex(cocos2d::extension::TableView *table, ssize_t idx) override; virtual ssize_t numberOfCellsInTableView(cocos2d::extension::TableView *table) override; virtual void onCellClicked(int idx); virtual void onCellLongPress(int idx); virtual void rearrangeLayout() override; static std::pair PathSplit(const std::string &path); protected: virtual void bindBodyController(const NodeMap &allNodes) override; virtual void bindHeaderController(const NodeMap &allNodes) override; void ListDir(std::string path); virtual void getShortCutDirList(std::vector &pathlist); void onCellItemClicked(cocos2d::Ref *owner); void onTitleClicked(cocos2d::Ref *owner); void onBackClicked(cocos2d::Ref *owner); void _onCellClicked(int idx); cocos2d::extension::TableView *FileList; cocos2d::ui::Button *_title; cocos2d::Node *_fileOperateMenuNode = nullptr; cocos2d::Node *_fileOperateMenu = nullptr; cocos2d::ui::ListView *_fileOperateMenulist; cocos2d::RefPtr _fileOperateCell_unselect, _fileOperateCell_view, _fileOperateCell_copy, _fileOperateCell_cut, _fileOperateCell_paste, _fileOperateCell_unpack, _fileOperateCell_repack, // TODO _fileOperateCell_delete, _fileOperateCell_rename, _fileOperateCell_sendto; std::vector _clipboardForFileManager; std::string _clipboardPath; bool _clipboardForMoving = false; std::set _selectedFileIndex; void onUnselectClicked(cocos2d::Ref *owner); void onViewClicked(cocos2d::Ref *owner); void onCopyClicked(cocos2d::Ref *owner); void onCutClicked(cocos2d::Ref *owner); void onPasteClicked(cocos2d::Ref *owner); void onUnpackClicked(cocos2d::Ref *owner); void onDeleteClicked(cocos2d::Ref *owner); void onSendToClicked(cocos2d::Ref *owner); void onBtnRenameClicked(cocos2d::Ref *owner); void updateFileMenu(); void clearFileMenu(); struct FileInfo { std::string FullPath; std::string NameForDisplay; std::string NameForCompare; bool IsDir; cocos2d::Size CellSize; bool operator < (const FileInfo &rhs) const; }; int RootPathLen = 1; // '/' std::vector CurrentDirList; std::string ParentPath, CurrentPath; class FileItemCell; class FileItemCellImpl : public TTouchEventRouter { public: FileItemCellImpl() : _set(false), _owner(nullptr) {} static FileItemCellImpl *create(const char * filename, float width) { FileItemCellImpl* ret = new FileItemCellImpl(); ret->autorelease(); ret->init(); ret->initFromFile(filename, width); return ret; } void initFromFile(const char * filename, float width); void setInfo(int idx, const FileInfo &info, bool selected, bool showSelect); void reset() { _set = false; } bool isSet() { return _set; } void setOwner(FileItemCell* owner) { _owner = owner; } private: void onClicked(cocos2d::Ref*); bool _set; cocos2d::Size OrigCellModelSize, CellTextAreaSize, OrigCellTextSize; cocos2d::ui::Text *FileNameNode; cocos2d::Node *DirIcon, *_root, *BgOdd, *BgEven; cocos2d::ui::CheckBox *SelectBox; FileItemCell *_owner; }; cocos2d::RefPtr CellTemplateForSize; FileItemCellImpl* FetchCell(FileItemCellImpl* CellModel, cocos2d::extension::TableView *table, ssize_t idx); class FileItemCell : public cocos2d::extension::TableViewCell { typedef cocos2d::extension::TableViewCell inherit; public: FileItemCell(TVPBaseFileSelectorForm *owner) : _owner(owner), _impl(nullptr) {} static FileItemCell *create(TVPBaseFileSelectorForm *owner) { FileItemCell *ret = new FileItemCell(owner); ret->init(); ret->autorelease(); return ret; } // retained FileItemCellImpl* detach() { FileItemCellImpl *ret = _impl; if (ret) { _impl = nullptr; ret->retain(); ret->removeFromParentAndCleanup(false); ret->reset(); } return ret; } // release void attach(FileItemCellImpl *impl) { _impl = impl; addChild(impl); setContentSize(impl->getContentSize()); impl->setOwner(this); impl->release(); } void onClicked() { _owner->_onCellClicked(getIdx()); } void onLongPress() { _owner->onCellLongPress(getIdx()); } private: FileItemCellImpl *_impl; TVPBaseFileSelectorForm *_owner; }; }; class TVPFileSelectorForm : public TVPBaseFileSelectorForm { typedef TVPBaseFileSelectorForm inherit; public: static TVPFileSelectorForm *create(const std::string &initfilename, const std::string &initdir, bool issave); void initFromPath(const std::string &initfilename, const std::string &initdir, bool issave); void setOnClose(const std::function &func) { _funcOnClose = func; } protected: virtual void bindFooterController(const NodeMap &allNodes) override; virtual void onCellClicked(int idx) override; void close(); cocos2d::ui::Button *_buttonOK, *_buttonCancel; cocos2d::ui::TextField *_input; std::function _funcOnClose; std::string _result; bool _isSaveMode; }; ================================================ FILE: src/core/environ/ui/GameMainMenu.cpp ================================================ #include "GameMainMenu.h" #include "cocos2d/MainScene.h" #include "Application.h" #include "WindowIntf.h" #include "ui/UIHelper.h" #include "base/CCEventDispatcher.h" #include "base/CCEventListenerTouch.h" #include "2d/CCActionInterval.h" #include "TickCount.h" #include "MenuItemImpl.h" #include "InGameMenuForm.h" #include "base/CCDirector.h" #include "platform/CCGLView.h" #include "Platform.h" using namespace cocos2d; using namespace cocos2d::ui; const float _shrinkSpd = 700; // px/sec const float _expandSpd = 700; // px/sec const float _handlerFadeInTime = 0.15f; const float _handlerFadeOutTime = 0.35f; TVPGameMainMenu::TVPGameMainMenu(GLubyte opa) { _shrinked = false; _hitted = false; _handler_inactive_opacity = opa; } TVPGameMainMenu * TVPGameMainMenu::create(GLubyte opa) { TVPGameMainMenu *ret = new TVPGameMainMenu(opa); ret->init(); ret->autorelease(); return ret; } iTJSDispatch2* TVPGetMenuDispatch(tTVInteger hWnd); tTJSNI_Window *TVPGetActiveWindow(); bool TVPGameMainMenu::init() { bool ret = Node::init(); CSBReader reader; _root = reader.Load("ui/GameMenu.csb"); Size size = TVPMainScene::GetInstance()->getGameNodeSize(); float scale; if (size.width > size.height) { scale = size.height / 720; } else { scale = size.width / 720; } setScale(scale); size.width /= scale; size.height = _root->getContentSize().height; _root->setContentSize(size); ui::Helper::doLayout(_root); addChild(_root); _handler = reader.findController("handler"); //_handler_inactive_opacity = _handler->getOpacity(); _eventDispatcher->removeEventListenersForTarget(_handler); EventListenerTouchOneByOne *listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(TVPGameMainMenu::onHandlerTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(TVPGameMainMenu::onHandlerTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(TVPGameMainMenu::onHandlerTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(TVPGameMainMenu::onHandlerTouchCancelled, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, _handler); listener = EventListenerTouchOneByOne::create(); listener->setSwallowTouches(true); listener->onTouchBegan = CC_CALLBACK_2(TVPGameMainMenu::onBackgroundTouchBegan, this); listener->onTouchMoved = CC_CALLBACK_2(TVPGameMainMenu::onBackgroundTouchMoved, this); listener->onTouchEnded = CC_CALLBACK_2(TVPGameMainMenu::onBackgroundTouchEnded, this); listener->onTouchCancelled = CC_CALLBACK_2(TVPGameMainMenu::onBackgroundTouchCancelled, this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, _root); reader.findWidget("btn_gamemenu")->addClickEventListener([this](Ref*){ iTJSDispatch2 *menuobj = TVPGetMenuDispatch((tjs_intptr_t)TVPGetActiveWindow()); if (!menuobj) return; tTJSNI_MenuItem *menu; menuobj->NativeInstanceSupport(TJS_NIS_GETINSTANCE, tTJSNC_MenuItem::ClassID, (iTJSNativeInstance**)&menu); if (!menu->GetChildren().empty()) TVPMainScene::GetInstance()->pushUIForm(TVPInGameMenuForm::create("GameMenu", menu)); shrink(); }); reader.findWidget("btn_window")->addClickEventListener([this](Ref*){ TVPMainScene::GetInstance()->showWindowManagerOverlay(true); shrink(); }); _icon_touch = reader.findController("icon_touch"); _icon_mouse = reader.findController("icon_mouse"); setMouseIcon(true); reader.findWidget("btn_mousemode")->addClickEventListener([this](Ref*){ TVPMainScene::GetInstance()->toggleVirtualMouseCursor(); setMouseIcon(!TVPMainScene::GetInstance()->isVirtualMouseMode()); shrink(); }); reader.findWidget("btn_keyboard")->addClickEventListener([this](Ref*){ Size screenSize = cocos2d::Director::getInstance()->getOpenGLView()->getFrameSize(); #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID TVPShowIME(0, 0, screenSize.width, screenSize.height); #else TVPMainScene::GetInstance()->attachWithIME(); #endif shrink(); }); reader.findWidget("btn_exit")->addClickEventListener([this](Ref*){ Application->PostUserMessage([](){ TVPGetActiveWindow()->Close(); }); shrink(); }); return ret; } void TVPGameMainMenu::setMouseIcon(bool bMouse) { if (_icon_mouse) _icon_mouse->setVisible(bMouse); if (_icon_touch) _icon_touch->setVisible(!bMouse); } bool TVPGameMainMenu::onHandlerTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) { _hitted = false; _touchBeganPosition = _handler->convertToNodeSpace(touch->getLocation()); Rect bb; bb.size = _handler->getContentSize(); _hitted = bb.containsPoint(_touchBeganPosition); if (_hitted) { _root->stopAllActions(); _handler->stopAllActions(); _handler->runAction(FadeIn::create(_handlerFadeInTime)); _draggingY = false; _draggingX = false; _touchBeganTime = TVPGetTickCount(); } return _hitted; } void TVPGameMainMenu::onHandlerTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) { Vec2 nsp = _handler->convertToNodeSpace(touch->getLocation()); Vec2 movDist = nsp - _touchBeganPosition; if (!_draggingY && std::abs(movDist.y) > 1) { _draggingY = true; } if (!_draggingX && std::abs(movDist.x) > 1) { _draggingX = true; } _handler->setPositionX(_handler->getPositionX() + movDist.x); const Vec2 &pos = _handler->getPosition(); const Size &size = _handler->getContentSize(); const Vec2 &anchor = _handler->getAnchorPointInPoints(); const Size &rootsize = _root->getContentSize(); float handlerLeftBoundary = pos.x - anchor.x; float handlerRightBoundary = handlerLeftBoundary + size.width; if (handlerLeftBoundary < 0) { _handler->setPositionX(anchor.x); } else { if (handlerRightBoundary > rootsize.width) { _handler->setPositionX(rootsize.width - size.width + anchor.x); } } float newPosY = _root->getPositionY() + movDist.y; if (newPosY < -rootsize.height) newPosY = -rootsize.height; else if (newPosY > 0) { float t = rootsize.height / 2; newPosY = (1 - 1 / (newPosY / t + 1)) * t; } _root->setPositionY(newPosY); } void TVPGameMainMenu::onHandlerTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) { _hitted = false; Vec2 nsp = _handler->convertToNodeSpace(touch->getLocation()); bool isClick = TVPGetTickCount() - _touchBeganTime < 500; bool doExpand = false; if (isClick && !_draggingY) { doExpand = _shrinked ^ _draggingX; } else { const Size &rootsize = _root->getContentSize(); if (_shrinked) { doExpand = _root->getPositionY() > -rootsize.height * 0.75f; } else { doExpand = _root->getPositionY() > -rootsize.height * 0.25f; } } if (doExpand) { expand(); } else { shrink(); } } void TVPGameMainMenu::onHandlerTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) { onHandlerTouchEnded(touch, unusedEvent); } void TVPGameMainMenu::shrink() { if (_hitted) return; _shrinked = true; float h = _root->getContentSize().height * _root->getScaleY(); float topBoundary = _root->getPosition().y + h; float duration = topBoundary / _shrinkSpd; _root->stopAllActions(); _root->runAction(MoveTo::create(duration, Vec2(0, -h))); _handler->runAction(Sequence::createWithTwoActions(DelayTime::create(2), FadeTo::create(_handlerFadeOutTime, _handler_inactive_opacity))); } void TVPGameMainMenu::shrinkWithTime(float dur) { _shrinked = true; float h = _root->getContentSize().height * _root->getScaleY(); float topBoundary = _root->getPosition().y + h; float duration = topBoundary / _shrinkSpd; _handler->setOpacity(255); _root->runAction(Sequence::createWithTwoActions(DelayTime::create(dur), MoveTo::create(duration, Vec2(0, -h)))); _handler->runAction(Sequence::createWithTwoActions(DelayTime::create(2 + dur), FadeTo::create(_handlerFadeOutTime, _handler_inactive_opacity))); } void TVPGameMainMenu::expand() { if (_hitted) return; _shrinked = false; float bottomBoundary = _root->getPosition().y; float duration = std::abs(bottomBoundary) / _expandSpd; _root->stopAllActions(); _root->runAction(MoveTo::create(duration, Vec2(0, 0))); _handler->runAction(FadeIn::create(_handlerFadeInTime)); } bool TVPGameMainMenu::onBackgroundTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) { if (!_shrinked) { shrink(); return true; } return false; } void TVPGameMainMenu::onBackgroundTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) { } void TVPGameMainMenu::onBackgroundTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) { } void TVPGameMainMenu::onBackgroundTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unusedEvent) { } void TVPGameMainMenu::toggle() { if (_hitted) return; // in touching if (_shrinked) expand(); else shrink(); } bool TVPGameMainMenu::isShrinked() { return _shrinked; } ================================================ FILE: src/core/environ/ui/GameMainMenu.h ================================================ #pragma once #include "BaseForm.h" class TVPGameMainMenu : public cocos2d::Node { public: TVPGameMainMenu(GLubyte opa); static TVPGameMainMenu *create(GLubyte opa); virtual bool init() override; void setMouseIcon(bool bMouse); void shrink(); void expand(); void toggle(); void shrinkWithTime(float dur); bool isShrinked(); private: bool onHandlerTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unusedEvent); void onHandlerTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unusedEvent); void onHandlerTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unusedEvent); void onHandlerTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unusedEvent); bool onBackgroundTouchBegan(cocos2d::Touch *touch, cocos2d::Event *unusedEvent); void onBackgroundTouchMoved(cocos2d::Touch *touch, cocos2d::Event *unusedEvent); void onBackgroundTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unusedEvent); void onBackgroundTouchCancelled(cocos2d::Touch *touch, cocos2d::Event *unusedEvent); GLubyte _handler_inactive_opacity; bool _hitted; bool _shrinked; bool _draggingX, _draggingY; cocos2d::Node *_root; cocos2d::Node *_handler; cocos2d::Node *_icon_touch; cocos2d::Node *_icon_mouse; cocos2d::Vec2 _touchBeganPosition; cocos2d::Vec2 _touchMovePosition; cocos2d::Vec2 _touchEndPosition; unsigned int _touchBeganTime; }; ================================================ FILE: src/core/environ/ui/GlobalPreferenceForm.cpp ================================================ #include "GlobalPreferenceForm.h" #include "ConfigManager/LocaleConfigManager.h" #include "ui/UIButton.h" #include "cocos2d/MainScene.h" #include "ui/UIListView.h" #include "ConfigManager/GlobalConfigManager.h" #include "platform/CCFileUtils.h" #include "Platform.h" using namespace cocos2d; using namespace cocos2d::ui; #define GLOBAL_PREFERENCE const char * const FileName_NaviBar = "ui/NaviBar.csb"; const char * const FileName_Body = "ui/ListView.csb"; static iSysConfigManager* GetConfigManager() { return GlobalConfigManager::GetInstance(); } #include "PreferenceConfig.h" TVPGlobalPreferenceForm * TVPGlobalPreferenceForm::create(const tPreferenceScreen *config) { Initialize(); if (!config) config = &RootPreference; TVPGlobalPreferenceForm *ret = new TVPGlobalPreferenceForm(); ret->autorelease(); ret->initFromFile(FileName_NaviBar, FileName_Body, nullptr); PrefListSize = ret->PrefList->getContentSize(); ret->initPref(config); ret->setOnExitCallback(std::bind(&GlobalConfigManager::SaveToFile, GlobalConfigManager::GetInstance())); return ret; } static void WalkConfig(tPreferenceScreen* pref) { for (iTVPPreferenceInfo* info : pref->Preferences) { info->InitDefaultConfig(); tPreferenceScreen* subpref = info->GetSubScreenInfo(); if (subpref) { WalkConfig(subpref); } } } void TVPGlobalPreferenceForm::Initialize() { static bool Inited = false; if (!Inited) { Inited = true; if (!GlobalConfigManager::GetInstance()->IsValueExist("GL_EXT_shader_framebuffer_fetch")) { // disable GL_EXT_shader_framebuffer_fetch normally for adreno GPU if (strstr((const char*)glGetString(GL_RENDERER), "Adreno")) { GlobalConfigManager::GetInstance()->SetValueInt("GL_EXT_shader_framebuffer_fetch", 0); } } initAllConfig(); WalkConfig(&RootPreference); WalkConfig(&SoftRendererOptPreference); WalkConfig(&OpenglOptPreference); } } ================================================ FILE: src/core/environ/ui/GlobalPreferenceForm.h ================================================ #pragma once #include "PreferenceForm.h" class TVPGlobalPreferenceForm : public TVPPreferenceForm { public: static TVPGlobalPreferenceForm *create(const tPreferenceScreen *config = nullptr); static void Initialize(); }; ================================================ FILE: src/core/environ/ui/InGameMenuForm.cpp ================================================ #include "InGameMenuForm.h" #include "cocos2d/MainScene.h" #include "ui/UIButton.h" #include "ui/UIListView.h" #include "ui/UIText.h" #include "MenuItemImpl.h" #include "ui/UIHelper.h" #include "tjsGlobalStringMap.h" using namespace cocos2d; using namespace cocos2d::ui; const char * const FileName_NaviBar = "ui/NaviBar.csb"; const char * const FileName_Body = "ui/ListView.csb"; TVPInGameMenuForm * TVPInGameMenuForm::create(const std::string& title, tTJSNI_MenuItem *item) { TVPInGameMenuForm *ret = new TVPInGameMenuForm; ret->autorelease(); ret->initFromFile(FileName_NaviBar, FileName_Body, nullptr); ret->initMenu(title, item); return ret; } void TVPInGameMenuForm::bindBodyController(const NodeMap &allNodes) { _list = static_cast(allNodes.findController("list")); if (NaviBar.Left) { NaviBar.Left->addClickEventListener([this](cocos2d::Ref*){ TVPMainScene::GetInstance()->popUIForm(this); }); } } void TVPInGameMenuForm::bindHeaderController(const NodeMap &allNodes) { _title = static_cast(allNodes.findController("title")); if (_title) _title->setEnabled(false); } void TVPInGameMenuForm::initMenu(const std::string& title, tTJSNI_MenuItem *item) { _list->removeAllItems(); if (_title) { if (title.empty()) { ttstr caption; item->GetCaption(caption); _title->setTitleText(caption.AsStdString()); } else { _title->setTitleText(title); } } int count = item->GetChildren().size(); int idx = 0; ttstr seperator = TJS::TJSMapGlobalStringMap(TJS_W("-")); for (int i = 0; i < count; ++i) { tTJSNI_MenuItem *subitem = static_cast(item->GetChildren().at(i)); ttstr caption; subitem->GetCaption(caption); if (caption.IsEmpty() || caption == TJS_W("+")) continue; _list->pushBackCustomItem(createMenuItem(idx, subitem, caption.AsStdString())); if(caption != seperator) ++idx; } } cocos2d::ui::Widget * TVPInGameMenuForm::createMenuItem(int idx, tTJSNI_MenuItem *item, const std::string &caption) { iPreferenceItem *ret = nullptr; const Size &size = _list->getContentSize(); if (!item->GetChildren().empty()) { ret = CreatePreferenceItem(idx, size, caption); ret->addClickEventListener([=](Ref*){ TVPMainScene::GetInstance()->pushUIForm(create(caption, item)); }); } else if (item->GetGroup() > 0 || item->GetRadio()) { auto getter = [=]()->bool{ return item->GetChecked(); }; auto setter = [=](bool b){ item->OnClick(); TVPMainScene::GetInstance()->popAllUIForm(); }; ret = CreatePreferenceItem(idx, size, caption, [=](tPreferenceItemCheckBox* item) { item->_getter = getter; item->_setter = setter; }); } else if (item->GetChecked()) { auto getter = [=]()->bool{ return item->GetChecked(); }; auto setter = [=](bool b){ item->OnClick(); }; ret = CreatePreferenceItem(idx, size, caption, [=](tPreferenceItemCheckBox* item) { item->_getter = getter; item->_setter = setter; }); } else if(caption == "-") { CSBReader reader; Widget * root = static_cast(reader.Load("ui/comctrl/SeperateItem.csb")); Size rootsize = root->getContentSize(); rootsize.width = size.width; root->setContentSize(rootsize); ui::Helper::doLayout(root); return root; } else { ret = CreatePreferenceItem(idx, size, caption); ret->addClickEventListener([=](Ref*){ TVPMainScene::GetInstance()->scheduleOnce( std::bind(&TVPMainScene::popAllUIForm, TVPMainScene::GetInstance()), 0, "close_menu"); item->OnClick(); }); ret->setTouchEnabled(true); } return ret; } void TVPShowPopMenu(tTJSNI_MenuItem* menu) { TVPMainScene::GetInstance()->pushUIForm(TVPInGameMenuForm::create(std::string(), menu)); } ================================================ FILE: src/core/environ/ui/InGameMenuForm.h ================================================ #pragma once #include "PreferenceForm.h" class tTJSNI_MenuItem; class TVPInGameMenuForm : public iTVPBaseForm { public: static TVPInGameMenuForm *create(const std::string& title, tTJSNI_MenuItem *item); virtual void bindBodyController(const NodeMap &allNodes); virtual void bindHeaderController(const NodeMap &allNodes); void initMenu(const std::string& title, tTJSNI_MenuItem *item); private: cocos2d::ui::Widget *createMenuItem(int idx, tTJSNI_MenuItem *item, const std::string &caption); cocos2d::ui::ListView *_list; cocos2d::ui::Button *_title; }; ================================================ FILE: src/core/environ/ui/IndividualPreferenceForm.cpp ================================================ #include "IndividualPreferenceForm.h" #include "ConfigManager/LocaleConfigManager.h" #include "ui/UIButton.h" #include "cocos2d/MainScene.h" #include "ui/UIListView.h" #include "platform/CCFileUtils.h" #include "ConfigManager/IndividualConfigManager.h" #include "Platform.h" using namespace cocos2d; using namespace cocos2d::ui; #define INDIVIDUAL_PREFERENCE const char * const FileName_NaviBar = "ui/NaviBar.csb"; const char * const FileName_Body = "ui/ListView.csb"; #define TVPGlobalPreferenceForm IndividualPreferenceForm static iSysConfigManager* GetConfigManager() { return IndividualConfigManager::GetInstance(); } #include "PreferenceConfig.h" #undef TVPGlobalPreferenceForm static void initInividualConfig() { if (!RootPreference.Preferences.empty()) return; initAllConfig(); RootPreference.Title = "preference_title_individual"; } IndividualPreferenceForm * IndividualPreferenceForm::create(const tPreferenceScreen *config) { initInividualConfig(); if (!config) config = &RootPreference; IndividualPreferenceForm *ret = new IndividualPreferenceForm(); ret->autorelease(); ret->initFromFile(FileName_NaviBar, FileName_Body, nullptr); PrefListSize = ret->PrefList->getContentSize(); ret->initPref(config); ret->setOnExitCallback(std::bind(&IndividualConfigManager::SaveToFile, IndividualConfigManager::GetInstance())); return ret; } ================================================ FILE: src/core/environ/ui/IndividualPreferenceForm.h ================================================ #pragma once #include "PreferenceForm.h" class IndividualPreferenceForm : public TVPPreferenceForm { public: static IndividualPreferenceForm *create(const tPreferenceScreen *config = nullptr); }; ================================================ FILE: src/core/environ/ui/MainFileSelectorForm.cpp ================================================ #include "MainFileSelectorForm.h" #include "cocos2d.h" #include "cocostudio/CocoLoader.h" #include "cocostudio/CCSSceneReader.h" #include "Application.h" #include "Platform.h" #include "cocostudio/ActionTimeline/CCActionTimeline.h" #include "ui/UIText.h" #include "ui/UIHelper.h" #include "ui/UIButton.h" #include "ui/UIListView.h" #include "cocos2d/MainScene.h" #include "ConfigManager/LocaleConfigManager.h" #include "ConfigManager/IndividualConfigManager.h" #include "GlobalPreferenceForm.h" #include "IndividualPreferenceForm.h" #include "MessageBox.h" #include "SimpleMediaFilePlayer.h" #include "tinyxml2/tinyxml2.h" #include "StorageImpl.h" #include "TipsHelpForm.h" #include "XP3RepackForm.h" #include "cocos2d/CustomFileUtils.h" using namespace cocos2d; using namespace cocos2d::ui; const float UI_ACTION_DUR = 0.3f; const char * const FileName_NaviBar = "ui/NaviBarWithMenu.csb"; const char * const FileName_Body = "ui/TableView.csb"; //const char * const FileName_BottomBar = "ui/BottomBar.csb"; //const char * const FileName_BtnPref = "ui/button/Pref.csb"; const char * const FileName_RecentPathListXML = "recentpath.xml"; bool TVPIsFirstLaunch = false; std::deque _HistoryPath; static void _AskExit() { if (TVPShowSimpleMessageBoxYesNo( LocaleConfigManager::GetInstance()->GetText("sure_to_exit"), "Kirikiroid2") == 0) TVPExitApplication(0); } bool TVPCheckIsVideoFile(const char *uri); static std::string _GetHistoryXMLPath() { return TVPGetInternalPreferencePath() + FileName_RecentPathListXML; } static void _LoadHistory() { std::string xmlpath = _GetHistoryXMLPath(); tinyxml2::XMLDocument doc; if (!doc.LoadFile(xmlpath.c_str())) { tinyxml2::XMLElement *rootElement = doc.RootElement(); if (rootElement) { for (tinyxml2::XMLElement *item = rootElement->FirstChildElement("Item"); item; item = item->NextSiblingElement("Item")) { const char *path = item->Attribute("Path"); if (path) { _HistoryPath.emplace_back(path); } } } } else { TVPIsFirstLaunch = true; } } static void _SaveHistory() { std::string xmlpath = _GetHistoryXMLPath(); if (_HistoryPath.empty() && !FileUtils::getInstance()->isFileExist(xmlpath)) return; tinyxml2::XMLDocument doc; doc.LinkEndChild(doc.NewDeclaration()); tinyxml2::XMLElement *rootElement = doc.NewElement("RecentPathList"); for (const std::string& path : _HistoryPath) { tinyxml2::XMLElement *item = doc.NewElement("Item"); item->SetAttribute("Path", path.c_str()); rootElement->LinkEndChild(item); } doc.LinkEndChild(rootElement); doc.SaveFile(xmlpath.c_str()); } static void _RemoveHistory(const std::string &path) { auto it = std::find(_HistoryPath.begin(), _HistoryPath.end(), path); if (it != _HistoryPath.end()) { _HistoryPath.erase(it); _SaveHistory(); } } static void _AddHistory(const std::string &path) { if (!_HistoryPath.empty() && _HistoryPath.front() == path) return; _RemoveHistory(path); _HistoryPath.emplace_front(path); _SaveHistory(); } static bool _CheckGameFolder(const std::string &path) { bool isValidGameFolder = false; std::vector subFolders; TVPListDir(path, [&](const std::string &name, int mask) { if (isValidGameFolder || name.empty() || name.front() == '.') return; if (mask & S_IFREG) { std::string lowername = name; std::transform(lowername.begin(), lowername.end(), lowername.begin(), [](int c)->int { if (c <= 'Z' && c >= 'A') return c - ('A' - 'a'); return c; }); size_t pos = lowername.rfind('.'); if (pos == lowername.npos) return; if (lowername.substr(pos) == ".xp3") { isValidGameFolder = true; } } else if (mask & S_IFDIR) { subFolders.emplace_back(path + "/" + name); } }); while (!isValidGameFolder) { if (subFolders.empty()) break; isValidGameFolder = _CheckGameFolder(subFolders.back()); subFolders.pop_back(); } return isValidGameFolder; } TVPMainFileSelectorForm::TVPMainFileSelectorForm() { _menu = nullptr; } void TVPMainFileSelectorForm::onEnter() { inherit::onEnter(); if (_historyList) { _historyList->doLayout(); auto & allcell = _historyList->getItems(); for (Widget* cell : allcell) { static_cast(cell)->rearrangeLayout(); } } } void TVPMainFileSelectorForm::bindBodyController(const NodeMap &allNodes) { TVPBaseFileSelectorForm::bindBodyController(allNodes); if (NaviBar.Right) { NaviBar.Right->addClickEventListener(std::bind(&TVPMainFileSelectorForm::showMenu, this, std::placeholders::_1)); } } extern "C" void TVPGL_ASM_Test(); void TVPMainFileSelectorForm::show() { #ifdef _DEBUG TVPGL_ASM_Test(); #endif ListHistory(); // filter history data bool first = true; std::string lastpath; if (!_HistoryPath.empty()) lastpath = _HistoryPath.front(); while (first || (lastpath.size() > RootPathLen && !FileUtils::getInstance()->isDirectoryExist(lastpath))) { first = false; std::pair split_path = PathSplit(lastpath); if (split_path.second.empty()) { lastpath.clear(); break; } lastpath = split_path.first; } if (lastpath.size() <= RootPathLen) { lastpath = TVPGetDriverPath()[0]; } ListDir(lastpath); // getCurrentDir() // TODO show usage } static const std::string str_startup_tjs("startup.tjs"); bool TVPMainFileSelectorForm::CheckDir(const std::string &path) { for (const FileInfo &info : CurrentDirList) { if (info.NameForCompare == str_startup_tjs) return true; } return false; } int TVPCheckArchive(const ttstr &localname); void TVPMainFileSelectorForm::onCellClicked(int idx) { FileInfo info = CurrentDirList[idx]; TVPBaseFileSelectorForm::onCellClicked(idx); int archiveType; if (info.IsDir) { if (CheckDir(info.FullPath)) { startup(info.FullPath); } } else if ((archiveType = TVPCheckArchive(info.FullPath.c_str())) == 1) { startup(info.FullPath); } else if (archiveType == 0 && TVPCheckIsVideoFile(info.FullPath.c_str())) { SimpleMediaFilePlayer *player = SimpleMediaFilePlayer::create(); TVPMainScene::GetInstance()->addChild(player, 10);// pushUIForm(player); player->PlayFile(info.FullPath.c_str()); } else if (archiveType && FileUtils::getInstance()->getFileExtension(info.NameForCompare) == ".skin") { // maybe skin if (TVPSkinManager::Check(info.FullPath)) { std::vector btns; btns.emplace_back("Direct Use"); btns.emplace_back("Install"); btns.emplace_back("Cancel"); switch (TVPShowSimpleMessageBox("Install or direct use it ? (restart needed)", "Skin found", btns)) { case 0: // direct use TVPSkinManager::Use(info.FullPath); TVPShowSimpleMessageBox("Active after restart.", "Skin"); break; case 1: // install TVPSkinManager::InstallAndUse(info.FullPath); TVPShowSimpleMessageBox("Active after restart.", "Skin"); break; default: break; } } } } void TVPMainFileSelectorForm::getShortCutDirList(std::vector &pathlist) { if (!_lastpath.empty()) { pathlist.emplace_back(_lastpath); } TVPBaseFileSelectorForm::getShortCutDirList(pathlist); } TVPMainFileSelectorForm * TVPMainFileSelectorForm::create() { TVPMainFileSelectorForm *ret = new TVPMainFileSelectorForm(); ret->autorelease(); ret->initFromFile(); ret->show(); return ret; } void TVPMainFileSelectorForm::initFromFile() { _LoadHistory(); // if (!_HistoryPath.empty()) { CSBReader reader; Node *root = reader.Load("ui/MainFileSelector.csb"); _fileList = reader.findController("fileList"); _historyList = static_cast(reader.findController("recentList")); // TODO new node _fileOperateMenuNode = _historyList; LocaleConfigManager::GetInstance()->initText(static_cast(reader.findController("recentTitle", false))); addChild(root); Size sceneSize = TVPMainScene::GetInstance()->getUINodeSize(); setContentSize(sceneSize); root->setContentSize(sceneSize); ui::Helper::doLayout(root); } inherit::initFromFile(FileName_NaviBar, FileName_Body, nullptr/*FileName_BottomBar*/, _fileList); } // std::string _getLastPathFilePath() { // return TVPGetInternalPreferencePath() + "lastpath.txt"; // } void TVPMainFileSelectorForm::startup(const std::string &path) { if (TVPIsFirstLaunch) { TVPTipsHelpForm::show()->setOnExitCallback([this, path](){ scheduleOnce([this, path](float) {doStartup(path); }, 0, "startup"); }); } else { doStartup(path); } } void TVPMainFileSelectorForm::doStartup(const std::string &path) { if (TVPMainScene::GetInstance()->startupFrom(path)) { if (GlobalConfigManager::GetInstance()->GetValue("remember_last_path", true)) { _AddHistory(path); } } } std::string TVPGetOpenGLInfo(); void TVPOpenPatchLibUrl(); void TVPMainFileSelectorForm::showMenu(Ref*) { if (!_menu) { Size uiSize = getContentSize(); CSBReader reader; _menu = reader.Load("ui/MenuList.csb"); _menu->setAnchorPoint(Vec2::ZERO); _menu->setPosition(Vec2(uiSize.width, 0)); _mask = LayerColor::create(Color4B::BLACK, uiSize.width, uiSize.height); _mask->setOpacity(0); _touchHideMenu = ui::Widget::create(); _touchHideMenu->setAnchorPoint(Vec2::ZERO); _touchHideMenu->setContentSize(uiSize); _touchHideMenu->addClickEventListener([this](Ref*) { if (isMenuShowed()) hideMenu(nullptr); }); _mask->addChild(_touchHideMenu); addChild(_mask); addChild(_menu); if (uiSize.width > uiSize.height) { uiSize.width /= 3; } else { uiSize.width *= 0.6f; } Size menuSize = _menu->getContentSize(); float scale = uiSize.width / menuSize.width; menuSize.height = uiSize.height / scale; _menu->setScale(scale); _menu->setContentSize(menuSize); ui::Helper::doLayout(_menu); newLocalPref = reader.findController("newLocalPref"); localPref = reader.findController("localPref"); sizeNewLocalPref = newLocalPref->getContentSize(); sizeLocalPref = localPref->getContentSize(); _menuList = dynamic_cast(reader.findController("menulist")); // captions LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); localeMgr->initText(reader.findController("titleRotate")); localeMgr->initText(reader.findController("titleGlobalPref")); localeMgr->initText(reader.findController("titleNewLocalPref")); localeMgr->initText(reader.findController("titleLocalPref")); localeMgr->initText(reader.findController("titleHelp")); localeMgr->initText(reader.findController("titleAbout")); localeMgr->initText(reader.findController("titleExit")); localeMgr->initText(reader.findController("titleRepack")); localeMgr->initText(reader.findController("titleNewFolder")); // button events reader.findWidget("btnRotate")->addClickEventListener([](Ref*) { TVPMainScene::GetInstance()->pushUIForm(TVPGlobalPreferenceForm::create()); }); reader.findWidget("btnGlobalPref")->addClickEventListener([](Ref*) { TVPMainScene::GetInstance()->pushUIForm(TVPGlobalPreferenceForm::create()); }); reader.findWidget("btnNewLocalPref")->addClickEventListener([this](Ref*) { if (IndividualConfigManager::GetInstance()->CreatePreferenceAt(CurrentPath)) { TVPMainScene::GetInstance()->pushUIForm(IndividualPreferenceForm::create()); hideMenu(nullptr); } }); reader.findWidget("btnLocalPref")->addClickEventListener([this](Ref*) { onShowPreferenceConfigAt(CurrentPath); }); reader.findWidget("btnHelp")->addClickEventListener([this](Ref*) { TVPTipsHelpForm::show(); }); bool showSimpleAbout = false; if(showSimpleAbout) { reader.findWidget("btnAbout")->addClickEventListener([](Ref*) { std::string versionText = "Version "; versionText += TVPGetPackageVersionString(); std::string btnText = LocaleConfigManager::GetInstance()->GetText("ok"); const char *pszBtnText = btnText.c_str(); std::string strCaption = LocaleConfigManager::GetInstance()->GetText("menu_about"); const char *caption = strCaption.c_str(); TVPShowSimpleMessageBox(versionText.c_str(), caption, 1, &pszBtnText); }); reader.findWidget("btnExit")->addClickEventListener([](Ref*) { if (TVPShowSimpleMessageBoxYesNo( LocaleConfigManager::GetInstance()->GetText("sure_to_exit"), "XP3Player") == 0) TVPExitApplication(0); }); } else { reader.findWidget("btnAbout")->addClickEventListener([](Ref*) { std::string versionText = "Version "; versionText += TVPGetPackageVersionString(); versionText += "\n"; versionText += LocaleConfigManager::GetInstance()->GetText("about_content"); const char * pszBtnText[] = { LocaleConfigManager::GetInstance()->GetText("ok").c_str(), LocaleConfigManager::GetInstance()->GetText("browse_patch_lib").c_str(), LocaleConfigManager::GetInstance()->GetText("device_info").c_str(), }; std::string strCaption = LocaleConfigManager::GetInstance()->GetText("menu_about"); int n = TVPShowSimpleMessageBox(versionText.c_str(), strCaption.c_str(), sizeof(pszBtnText) / sizeof(pszBtnText[0]), pszBtnText); switch (n) { case 1: TVPOpenPatchLibUrl(); break; case 2: cocos2d::Director::getInstance()->getScheduler()->performFunctionInCocosThread([]{ std::string text = TVPGetOpenGLInfo(); const char *pOK = LocaleConfigManager::GetInstance()->GetText("ok").c_str(); TVPShowSimpleMessageBox(text.c_str(), LocaleConfigManager::GetInstance()->GetText("device_info").c_str(), 1, &pOK); }); break; } }); reader.findWidget("btnExit")->addClickEventListener([](Ref*) { _AskExit(); }); } // ## fix repack can not compile // reader.findWidget("btnRepack")->addClickEventListener([this](Ref*) { // TVPProcessXP3Repack(CurrentPath); // hideMenu(nullptr); // }); reader.findWidget("btnNewFolder")->addClickEventListener([this](Ref*) { ttstr name = TJS_W("New Folder"); std::vector btns; btns.emplace_back("OK"); btns.emplace_back("Cancel"); if (TVPShowSimpleInputBox(name, "Input name", "", btns) == 0) { ttstr newname(CurrentPath); newname += TJS_W("/"); newname += name; if (!TVPCreateFolders(newname)) { TVPShowSimpleMessageBox(TJS_W("Fail to create folder."), TJS_W("Error")); } else { ListDir(CurrentPath); } } hideMenu(nullptr); }); } const Size &uiSize = getContentSize(); const Vec2 &pos = _menu->getPosition(); const Size &size = _menu->getContentSize(); float w = size.width * _menu->getScale(); if (pos.x > uiSize.width - w / 10.0f) { if (IndividualConfigManager::CheckExistAt(CurrentPath)) { localPref->setVisible(true); localPref->setContentSize(sizeLocalPref); newLocalPref->setVisible(false); newLocalPref->setContentSize(Size::ZERO); } else { newLocalPref->setVisible(true); newLocalPref->setContentSize(sizeNewLocalPref); localPref->setVisible(false); localPref->setContentSize(Size::ZERO); } _menuList->requestDoLayout(); _mask->stopAllActions(); _mask->runAction(FadeTo::create(UI_ACTION_DUR, 128)); _menu->stopAllActions(); _menu->runAction(EaseQuadraticActionOut::create( MoveTo::create(UI_ACTION_DUR, Vec2(uiSize.width - w, pos.y)))); _touchHideMenu->setTouchEnabled(true); } } void TVPMainFileSelectorForm::hideMenu(cocos2d::Ref*) { if (!_menu) return; _mask->stopAllActions(); _mask->runAction(FadeOut::create(UI_ACTION_DUR)); _menu->stopAllActions(); _menu->runAction(EaseQuadraticActionOut::create( MoveTo::create(UI_ACTION_DUR, Vec2(getContentSize().width, _menu->getPositionY())))); _touchHideMenu->setTouchEnabled(false); } bool TVPMainFileSelectorForm::isMenuShowed() { if (!_menu) return false; const Vec2 &pos = _menu->getPosition(); const Size &size = _menu->getContentSize(); float w = size.width * _menu->getScale(); if (pos.x < getContentSize().width - w * 0.9f) { return true; } return false; } bool TVPMainFileSelectorForm::isMenuShrinked() { if (!_menu) return true; const Vec2 &pos = _menu->getPosition(); const Size &size = _menu->getContentSize(); float w = size.width * _menu->getScale(); if (pos.x > getContentSize().width - w / 10.0f) { return false; } return true; } void TVPMainFileSelectorForm::onShowPreferenceConfigAt(const std::string &path) { if (IndividualConfigManager::GetInstance()->UsePreferenceAt(path)) { TVPMainScene::GetInstance()->pushUIForm(IndividualPreferenceForm::create()); } } void TVPMainFileSelectorForm::ListHistory() { if (!_historyList) return; _historyList->removeAllChildren(); HistoryCell *nullcell = new HistoryCell(); nullcell->init(); Size cellsize = _historyList->getContentSize(); cellsize.height = 100; nullcell->setContentSize(cellsize); _historyList->pushBackCustomItem(nullcell); for (auto it = _HistoryPath.begin(); it != _HistoryPath.end();) { const std::string &fullpath = *it; HistoryCell *cell; if (TVPCheckExistentLocalFile(fullpath) || TVPCheckExistentLocalFolder(fullpath)) { std::pair split_path = PathSplit(fullpath); std::string lastname = split_path.second; std::string path = split_path.first; split_path = PathSplit(path); cell = HistoryCell::create(fullpath, split_path.first + "/", split_path.second, "/" + lastname); Widget::ccWidgetClickCallback funcConf; if (TVPCheckExistentLocalFile(path + "/Kirikiroid2Preference.xml")) funcConf = [this, path](Ref*){ onShowPreferenceConfigAt(path); }; cell->initFunction(std::bind(&TVPMainFileSelectorForm::RemoveHistoryCell, this, std::placeholders::_1, cell), [this, path](Ref*){ ListDir(path); }, funcConf, [this, fullpath](Ref*) { startup(fullpath); }); Size cellsize = cell->getContentSize(); cellsize.width = _historyList->getContentSize().width; cell->setContentSize(cellsize); _historyList->pushBackCustomItem(cell); ++it; } else { it = _HistoryPath.erase(it); continue; } } nullcell = new HistoryCell(); nullcell->init(); nullcell->setContentSize(cellsize); _historyList->pushBackCustomItem(nullcell); } void TVPMainFileSelectorForm::RemoveHistoryCell(cocos2d::Ref* btn, HistoryCell* cell) { static_cast(btn)->setEnabled(false); cell->runAction(Sequence::createWithTwoActions( EaseQuadraticActionOut::create(MoveBy::create(0.25, Vec2(-cell->getContentSize().width, 0))), CallFuncN::create([this](Node* p){ HistoryCell* cell = static_cast(p); ssize_t idx = _historyList->getIndex(cell); if (idx < 0) return; _historyList->removeItem(idx); }))); _RemoveHistory(cell->getFullpath()); _SaveHistory(); } void TVPMainFileSelectorForm::onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event) { if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK) { if (isMenuShowed()) { hideMenu(nullptr); } else { _AskExit(); } } else if (keyCode == EventKeyboard::KeyCode::KEY_MENU) { if (isMenuShrinked()) { showMenu(nullptr); } } else { inherit::onKeyPressed(keyCode, event); } } void TVPMainFileSelectorForm::HistoryCell::initInfo(const std::string &fullpath, const std::string &prefix, const std::string &pathname, const std::string &filename) { _fullpath = fullpath; CSBReader reader; _root = reader.Load("ui/RecentListItem.csb"); _scrollview = static_cast(reader.findController("scrollview")); _btn_delete = static_cast(reader.findController("btn_delete")); _btn_jump = static_cast(reader.findController("btn_jump")); _btn_conf = static_cast(reader.findController("btn_conf")); _btn_play = static_cast(reader.findController("btn_play")); _prefix = static_cast(reader.findController("prefix")); _path = static_cast(reader.findController("path")); _file = static_cast(reader.findController("file")); _panel_delete = reader.findController("panel_delete"); if (!_panel_delete) _panel_delete = _btn_delete; _scrollview->setScrollBarEnabled(false); _scrollview->setPropagateTouchEvents(true); _prefix->setString(prefix); _path->setString(pathname); _file->setString(filename); setContentSize(_root->getContentSize()); addChild(_root); } void TVPMainFileSelectorForm::HistoryCell::rearrangeLayout() { if (!_root) return; _root->setContentSize(this->getContentSize()); ui::Helper::doLayout(_root); Vec2 pt = Vec2::ZERO; pt.x = _file->getContentSize().width; Vec2 ptWorld = _file->convertToWorldSpace(pt); Size viewSize = _scrollview->getContentSize(); Node *container = _scrollview->getInnerContainer(); pt = container->convertToNodeSpace(ptWorld); float btnw = _panel_delete->getContentSize().width; float offsetx = 0; if (pt.x > viewSize.width) { float neww = pt.x; pt.y = 0; pt.x = _path->getContentSize().width; ptWorld = _path->convertToWorldSpace(pt); pt = container->convertToNodeSpace(ptWorld); if (pt.x > viewSize.width) { offsetx = viewSize.width - pt.x; } viewSize.width = neww; } _panel_delete->setPositionX(viewSize.width + btnw); viewSize.width += btnw + btnw; _scrollview->setInnerContainerSize(viewSize); container->setPosition(offsetx, 0); } void TVPMainFileSelectorForm::HistoryCell::initFunction(const ccWidgetClickCallback &funcDel, const ccWidgetClickCallback &funcJump, const ccWidgetClickCallback &funcConf, const ccWidgetClickCallback &funcPlay) { _btn_delete->addClickEventListener(funcDel); _btn_play->addClickEventListener(funcPlay); if (funcConf) _btn_conf->addClickEventListener(funcConf); else _btn_conf->setVisible(false); _btn_jump->addClickEventListener(funcJump); } void TVPMainFileSelectorForm::HistoryCell::onSizeChanged() { } ================================================ FILE: src/core/environ/ui/MainFileSelectorForm.h ================================================ #pragma once #include "FileSelectorForm.h" namespace cocos2d { class LayerColor; } class TVPMainFileSelectorForm : public TVPBaseFileSelectorForm { typedef TVPBaseFileSelectorForm inherit; public: virtual void bindBodyController(const NodeMap &allNodes) override; void show(); static TVPMainFileSelectorForm *create(); void initFromFile(); virtual void onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event); protected: TVPMainFileSelectorForm(); virtual void onEnter() override; bool CheckDir(const std::string &path); virtual void onCellClicked(int idx) override; virtual void getShortCutDirList(std::vector &pathlist) override; void startup(const std::string &path); void doStartup(const std::string &path); void showMenu(cocos2d::Ref*); void hideMenu(cocos2d::Ref*); bool isMenuShowed(); bool isMenuShrinked(); void onShowPreferenceConfigAt(const std::string &path); void ListHistory(); class HistoryCell : public cocos2d::ui::Widget { public: static HistoryCell *create(const std::string &fullpath, const std::string &prefix, const std::string &pathname, const std::string &filename) { HistoryCell* ret = new HistoryCell(); ret->autorelease(); ret->init(); ret->initInfo(fullpath, prefix, pathname, filename); return ret; } void initInfo(const std::string &fullpath, const std::string &prefix, const std::string &pathname, const std::string &filename); void initFunction(const ccWidgetClickCallback &funcDel, const ccWidgetClickCallback &funcJump, const ccWidgetClickCallback &funcConf, const ccWidgetClickCallback &funcPlay); void rearrangeLayout(); const std::string &getFullpath() { return _fullpath; } private: virtual void onSizeChanged() override; cocos2d::ui::ScrollView *_scrollview; cocos2d::ui::Widget *_btn_delete, *_btn_jump, *_btn_conf, *_btn_play; cocos2d::ui::Text* _prefix, *_path, *_file; cocos2d::Node *_panel_delete, *_root = nullptr; std::string _fullpath; }; void RemoveHistoryCell(cocos2d::Ref*, HistoryCell* cell); std::string _lastpath; cocos2d::ui::Widget *_touchHideMenu; cocos2d::ui::ListView *_menuList, *_historyList = nullptr; cocos2d::LayerColor* _mask; cocos2d::Node *_menu, *_fileList = nullptr; cocos2d::Node *newLocalPref, *localPref; cocos2d::Size sizeNewLocalPref, sizeLocalPref; }; ================================================ FILE: src/core/environ/ui/MessageBox.cpp ================================================ #include "MessageBox.h" #include "cocos2d/MainScene.h" #include "ui/UIButton.h" #include "ui/UIText.h" #include "ui/UIScrollView.h" #include "ui/UIHelper.h" #include "ui/UILoadingBar.h" #include "2d/CCLabel.h" #include "ConfigManager/LocaleConfigManager.h" using namespace cocos2d; using namespace cocos2d::ui; void TVPMessageBoxForm::show(const std::string &caption, const std::string &text, int nBtns, const std::string *btnText, const std::function &callback) { TVPMessageBoxForm *ret = new TVPMessageBoxForm; ret->autorelease(); ret->init(caption, text, nBtns, btnText, callback); TVPMainScene::GetInstance()->pushUIForm(ret, TVPMainScene::eEnterAniNone); } void TVPMessageBoxForm::showYesNo(const std::string &caption, const std::string &text, const std::function &callback) { LocaleConfigManager *mgr = LocaleConfigManager::GetInstance(); std::string btns[2] = { mgr->GetText("msgbox_yes"), mgr->GetText("msgbox_no") }; return show(caption, text, 2, btns, callback); } void TVPMessageBoxForm::init(const std::string &caption, const std::string &text, int nBtns, const std::string *btnText, const std::function &callback) { _callback = callback; initFromFile(nullptr, "ui/MessageBox.csb", nullptr); if (_title) _title->setString(caption); if (_textContent) { _textContent->setString(""); _textContent->ignoreContentAdaptWithSize(true); _textContent->setString(text); const Size &textSize = _textContent->getContentSize(); const Size &viewSize = _textContainer->getInnerContainerSize(); if (textSize.height > viewSize.height) { _textContainer->setInnerContainerSize(textSize); _textContent->setPosition(Vec2(0, textSize.height)); } } _btnModel->retain(); _btnModel->removeFromParentAndCleanup(false); std::vector btns; float totalWidth = 0; Size origsize = _btnModel->getContentSize(); Size btnSize = _btnBody->getContentSize(); for (int i = 0; i < nBtns; ++i) { _btnBody->setTitleText(btnText[i]); Size textSize = _btnBody->getTitleRenderer()->getContentSize(); float fontSize = _btnBody->getTitleFontSize(); textSize.width += fontSize; _btnBody->addClickEventListener([this, i](Ref* node) { retain(); TVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveAniNone); if (_callback) _callback(i); release(); }); Size size = _btnModel->getContentSize(); if (btnSize.width < textSize.width) { Size size = origsize; size.width += textSize.width - btnSize.width; _btnModel->setContentSize(size); ui::Helper::doLayout(_btnModel); } else if (size.width != origsize.width) { _btnModel->setContentSize(origsize); ui::Helper::doLayout(_btnModel); } Widget *btn = _btnModel->clone(); totalWidth += btn->getContentSize().width; btns.emplace_back(btn); _btnList->addChild(btn); btn->setTag(i); } float gap = _btnList->getContentSize().width - totalWidth; if (gap < 0) { gap /= nBtns + 1; } else { gap /= nBtns + 1; } float x = gap; for (Widget *btn : btns) { Vec2 pos = btn->getPosition(); pos.x = x; btn->setPosition(pos); x += btn->getContentSize().width + gap; } _btnModel->release(); _btnModel = nullptr; } void TVPMessageBoxForm::bindBodyController(const NodeMap &allNodes) { _title = dynamic_cast(allNodes.findController("title")); _textContent = dynamic_cast(allNodes.findController("content")); _textContainer = dynamic_cast(allNodes.findController("text")); _btnBody = dynamic_cast(allNodes.findController("btnBody")); _btnModel = allNodes.findWidget("btn"); _btnList = _btnModel->getParent(); } void TVPMessageBoxForm::onKeyPressed(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event) { if (keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK) { TVPMainScene::GetInstance()->popUIForm(this, TVPMainScene::eLeaveAniNone); } } TVPSimpleProgressForm* TVPSimpleProgressForm::create() { TVPSimpleProgressForm* form = new TVPSimpleProgressForm; form->autorelease(); form->initFromFile("ui/ProgressBox.csb"); return form; } void TVPSimpleProgressForm::initButtons(const std::vector > > &vec) { Size btnSize = _btnCell->getContentSize(); float totalWidth = 0; float containerWidth = _btnContainer->getContentSize().width; float edge = _btnCell->getPosition().x; containerWidth -= edge * 2; std::vector buttons; float btnEdge = btnSize.width - _btnButton->getTitleRenderer()->getContentSize().width; for (const auto &it : vec) { _btnButton->setTitleText(it.first); _btnButton->addClickEventListener(it.second); btnSize.width = _btnButton->getTitleRenderer()->getContentSize().width + btnEdge; _btnCell->setContentSize(btnSize); ui::Helper::doLayout(_btnCell); totalWidth += btnSize.width; Widget *btn = _btnCell->clone(); buttons.push_back(btn); _btnContainer->addChild(btn); } float x = edge; float gap = (containerWidth - totalWidth) / buttons.size(); for (Node *btn : buttons) { btn->setPositionX(x); x += btn->getContentSize().width; } } void TVPSimpleProgressForm::setTitle(const std::string &text) { _textTitle->setString(text); } void TVPSimpleProgressForm::setContent(const std::string &text) { _textContent->setString(text); } void TVPSimpleProgressForm::setPercentWithText(float percent) { _progressBar[0]->setPercent(percent); char tmp[16]; sprintf(tmp, "%2.2f%%", percent); _textProgress[0]->setString(tmp); } void TVPSimpleProgressForm::setPercentWithText2(float percent) { _progressBar[1]->setPercent(percent); char tmp[16]; sprintf(tmp, "%2.2f%%", percent); _textProgress[1]->setString(tmp); } void TVPSimpleProgressForm::setPercentOnly(float percent) { _progressBar[0]->setPercent(percent * 100); } void TVPSimpleProgressForm::setPercentOnly2(float percent) { _progressBar[1]->setPercent(percent * 100); } void TVPSimpleProgressForm::setPercentText(const std::string &text) { _textProgress[0]->setString(text); } void TVPSimpleProgressForm::setPercentText2(const std::string &text) { _textProgress[1]->setString(text); } void TVPSimpleProgressForm::setProgress2Visible(bool visible) { // TODO } void TVPSimpleProgressForm::bindBodyController(const NodeMap &allNodes) { LocaleConfigManager *localeMgr = LocaleConfigManager::GetInstance(); _progressBar[0] = allNodes.findController("progrss_1"); _progressBar[1] = allNodes.findController("progrss_2"); _textProgress[0] = allNodes.findController("progress_text_1"); _textProgress[1] = allNodes.findController("progress_text_2"); _textContent = allNodes.findController("text"); _textTitle = allNodes.findController("title"); _btnContainer = allNodes.findController("btnList"); _btnCell = allNodes.findWidget("btnCell"); _btnButton = allNodes.findController