//--------------------------------------------------------------------------- // 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; }
//--------------------------------------------------------------------------- void TVPGetRandomBits128(void *dest) { // retrieve random bits // add some noise tjs_uint8 buf[16]; TVPPushEnvironNoise(buf, 16); // dare to use uninitialized buffer TVPPushEnvironNoise(&TVPRandomSeedPoolPos, sizeof(TVPRandomSeedPoolPos)); // make 128bit hash of TVPRandomSeedPool, using MD5 message digest md5_state_t state; md5_init(&state); md5_append(&state, TVPRandomSeedPool, 0x1000); md5_finish(&state, buf); memcpy(dest, buf, 16); // push hash itself TVPPushEnvironNoise(buf, 16); }
//--------------------------------------------------------------------------- static void TVPInitRandomGenerator() { // initialize random generator 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); }
//--------------------------------------------------------------------------- void __fastcall TTVPMainForm::SystemWatchTimerTimer(TObject *Sender) { if(TVPTerminated) { // this will ensure terminating the application. // the WM_QUIT message disappears in some unknown situations... ::PostMessage(TVPMainForm->Handle, WM_USER+0x31/*dummy msg*/, 0, 0); Application->Terminate(); ::PostMessage(TVPMainForm->Handle, WM_USER+0x31/*dummy msg*/, 0, 0); } // call events DWORD tick = GetTickCount(); // push environ noise TVPPushEnvironNoise(&tick, sizeof(tick)); TVPPushEnvironNoise(&LastCompactedTick, sizeof(LastCompactedTick)); TVPPushEnvironNoise(&LastShowModalWindowSentTick, sizeof(LastShowModalWindowSentTick)); TVPPushEnvironNoise(&MixedIdleTick, sizeof(MixedIdleTick)); POINT pt; GetCursorPos(&pt); TVPPushEnvironNoise(&pt, sizeof(pt)); // CPU clock monitoring { static bool clock_rough_printed = false; if(!clock_rough_printed && TVPCPUClockAccuracy == ccaRough) { tjs_char msg[80]; TJS_sprintf(msg, TJS_W("(info) CPU clock (roughly) : %dMHz"), (int)TVPCPUClock); TVPAddImportantLog(msg); clock_rough_printed = true; } static bool clock_printed = false; if(!clock_printed && TVPCPUClockAccuracy == ccaAccurate) { tjs_char msg[80]; TJS_sprintf(msg, TJS_W("(info) CPU clock : %.1fMHz"), (float)TVPCPUClock); TVPAddImportantLog(msg); clock_printed = true; } } // check status and deliver events DeliverEvents(); // call TickBeat tjs_int count = TVPGetWindowCount(); for(tjs_int i = 0; i<count; i++) { tTJSNI_Window *win = TVPGetWindowListAt(i); win->TickBeat(); } if(!ContinuousEventCalling && tick - LastCompactedTick > 4000) { // idle state over 4 sec. LastCompactedTick = tick; // fire compact event TVPDeliverCompactEvent(TVP_COMPACT_LEVEL_IDLE); } if(!ContinuousEventCalling && tick > LastRehashedTick + 1500) { // TJS2 object rehash LastRehashedTick = tick; TJSDoRehash(); } if(LastCloseClickedTick && tick - LastCloseClickedTick > 3100) { // display force suicide confirmation form if(TVPHaltWarnForm) { TVPHaltWarnForm->Visible = true; } else { TVPHaltWarnForm = new TTVPHaltWarnForm(Application); TVPHaltWarnForm->Visible = true; } } // ensure modal window visible if(tick > LastShowModalWindowSentTick + 4100) { // ::PostMessage(Handle, WM_USER+0x32, 0, 0); // This is currently disabled because IME composition window // hides behind the window which is bringed top by the // window-rearrangement. LastShowModalWindowSentTick = tick; } }
void TVPBeforeSystemInit() { RegisterDllLoadHook(); // register DLL delayed import hook to support _inmm.dll TVPInitProgramArgumentsAndDataPath(false); // ensure command line #ifdef TVP_REPORT_HW_EXCEPTION __dee_hacked_set_getExceptionObjectHook(TVP__dee_hacked_getExceptionObjectHook); // register hook function for hardware exceptions #endif Application->HintHidePause = 24*60*60*1000; // not to hide tool tip hint immediately Application->ShowHint = false; Application->ShowHint = true; // to ensure assigning new HintWindow Class defined in HintWindow.cpp // randomize TVPInitRandomGenerator(); // memory usage { MEMORYSTATUS status; status.dwLength = sizeof(status); GlobalMemoryStatus(&status); TVPPushEnvironNoise(&status, sizeof(status)); TVPTotalPhysMemory = status.dwTotalPhys; TVPAddImportantLog(TJS_W("(info) Total physical memory : ") + ttstr((int)TVPTotalPhysMemory) ); 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*1024) { // 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; } } char 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 { 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 strncpy(buf, _argv[i], MAX_PATH-1); buf[MAX_PATH-1] = '\0'; if(DirectoryExists(buf)) // is directory? strcat(buf, "\\"); 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) { char path[MAX_PATH]; char *dum = 0; GetFullPathName(buf, MAX_PATH-1, path, &dum); strcpy(buf, path); TVPProjectDirSelected = false; bufset = true; } nosel = true; forcesel = true; } // check "content-data" directory if(!forcedataxp3 && !nosel) { char tmp[MAX_PATH]; strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ParamStr(0))).c_str()); strcat(tmp, "content-data"); if(DirectoryExists(tmp)) { strcat(tmp, "\\"); strcpy(buf, tmp); TVPProjectDirSelected = true; bufset = true; nosel = true; } } // check "data.xp3" archive if(!nosel) { char tmp[MAX_PATH]; strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ParamStr(0))).c_str()); strcat(tmp, "data.xp3"); if(FileExists(tmp)) { strcpy(buf, tmp); TVPProjectDirSelected = true; bufset = true; nosel = true; } } // check "data.exe" archive if(!nosel) { char tmp[MAX_PATH]; strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ParamStr(0))).c_str()); strcat(tmp, "data.exe"); if(FileExists(tmp)) { strcpy(buf, tmp); TVPProjectDirSelected = true; bufset = true; nosel = true; } } // check self combined xpk archive if(!nosel) { if(TVPIsXP3Archive(TVPNormalizeStorageName(ParamStr(0)))) { strcpy(buf, ParamStr(0).c_str()); TVPProjectDirSelected = true; bufset = true; nosel = true; } } // check "data" directory if(!forcedataxp3 && !nosel) { char tmp[MAX_PATH]; strcpy(tmp, IncludeTrailingBackslash(ExtractFileDir(ParamStr(0))).c_str()); strcat(tmp, "data"); if(DirectoryExists(tmp)) { strcat(tmp, "\\"); 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("Aborted"); strcpy(buf, ExtractFileDir(ParamStr(0)).c_str()); int curdirlen = strlen(buf); if(buf[curdirlen-1] != '\\') buf[curdirlen] = '\\', buf[curdirlen+1] = 0; } if(!forcedataxp3 && (!nosel || forcesel)) { // load krdevui.dll ( TVP[KiRikiri] Development User Interface ) HMODULE krdevui = LoadLibrary("krdevui.dll"); if(!krdevui) { AnsiString toolspath = (IncludeTrailingBackslash( ExtractFilePath(ParamStr(0))) + "tools\\krdevui.dll"); krdevui = LoadLibrary(toolspath.c_str()); } if(!krdevui) { // cannot locate the dll throw Exception( ttstr(TVPCannnotLocateUIDLLForFolderSelection).AsAnsiString()); } typedef int PASCAL (*UIShowFolderSelectorForm_t)(void *reserved, char *buf); typedef void PASCAL (*UIGetVersion_t)(DWORD *hi, DWORD *low); UIShowFolderSelectorForm_t UIShowFolderSelectorForm; UIGetVersion_t UIGetVersion; UIShowFolderSelectorForm = (UIShowFolderSelectorForm_t)GetProcAddress(krdevui, "UIShowFolderSelectorForm"); UIGetVersion = (UIGetVersion_t)GetProcAddress(krdevui, "UIGetVersion"); if(!UIShowFolderSelectorForm || !UIGetVersion) { FreeLibrary(krdevui); throw Exception(ttstr(TVPInvalidUIDLL).AsAnsiString()); } DWORD h, l; UIGetVersion(&h, &l); if(h != TVP_NEED_UI_VERSION) { FreeLibrary(krdevui); throw Exception(ttstr(TVPInvalidUIDLL).AsAnsiString()); } int result = UIShowFolderSelectorForm(Application->Handle, buf); // FreeLibrary(krdevui); // FIXME: the library should be freed as soon as finishing to use it. if(result == mrAbort) { // display the main window } else if(result == mrCancel) { // cancel throw EAbort("Canceled"); } else if(result == mrOk) { // ok, prepare to execute the script TVPProjectDirSelected = true; } } // check project dir and store some environmental variables if(TVPProjectDirSelected) { Application->ShowMainForm=false; } tjs_int buflen = strlen(buf); if(buflen >= 1) { if(buf[buflen-1] != '\\') buf[buflen] = TVPArchiveDelimiter, buf[buflen+1] = 0; } TVPProjectDir = TVPNormalizeStorageName(buf); TVPSetCurrentDirectory(TVPProjectDir); TVPNativeProjectDir = buf; if(TVPProjectDirSelected) { TVPAddImportantLog(TJS_W("(info) Selected project directory : ") + TVPProjectDir); } }
//--------------------------------------------------------------------------- void TVPAfterSystemInit() { // ensure datapath directory TVPEnsureDataPathDirectory(); // check CPU type TVPDetectCPU(); // determine OS type OSVERSIONINFO osinfo; osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&osinfo); TVPPushEnvironNoise(&osinfo, sizeof(osinfo)); bool nt = osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT; TVPSystemIsBasedOnNT = nt; TVPAllocGraphicCacheOnHeap = false; // always false since beta 20 // determine maximum graphic cache limit tTJSVariant opt; tjs_int limitmb = -1; if(TVPGetCommandLine(TJS_W("-gclim"), &opt)) { ttstr str(opt); if(str == TJS_W("auto")) limitmb = -1; else limitmb = (tjs_int)opt; } 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 = int(TVPTotalPhysMemory / (1024*1024*10)); // cachemem = physmem / 10 TVPGraphicCacheSystemLimit *= 1024*1024; } else { TVPGraphicCacheSystemLimit = limitmb * 1024*1024; } if(TVPTotalPhysMemory <= 64*1024*1024) TVPSetFontCacheForLowMem(); // TVPGraphicCacheSystemLimit = 1*1024*1024; // DEBUG // check TVPGraphicSplitOperation option 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 TVPGL_IA32_Init(); // load HBeam cursor Screen->Cursors[1] = LoadCursor(HInstance, "HBEAM"); // timer precision UINT 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 = 1; if (TVPGetCommandLine(TJS_W("-drawthread"), &opt)) { ttstr str(opt); if (str == TJS_W("auto")) drawThreadNum = 0; else drawThreadNum = (tjs_int)opt; } TVPDrawThreadNum = drawThreadNum; 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)); }