Beispiel #1
27
void TrySkipPatch()
{
    //Check for arguments and write them in gStartupSettings
    ParseArgs(splitCmdArgsW(std::wstring(GetCommandLineW())));

    // If we have stdin/stdout, attach to the IPC server
    ipcServer.AttachStdinStdout();

    if (gStartupSettings.patch){
        PATCH(0x8BECF2).NOP_PAD_TO_SIZE<0x1B5>().Apply(); //nop out the loader code
        *(WORD*)(0xB25046) = -1; //set run to true

        PATCH(0x8BED00).CALL(&InitHook).Apply();
    }

    // Init freeimage:
    gFreeImgInit.init();

    // Insert callback for patching which must occur after the runtime has started
    // (0x8BEC61 is not quite as early as would be ideal for this, but it's convenient)
    PATCH(0x8BEC61).CALL(&LatePatch).Apply();

    //Load graphics from the HardcodedGraphicsManager
    HardcodedGraphicsManager::loadGraphics();

    // Either in root or in config folder. The config folder is recommended however.
    gGeneralConfig.setFilename(getLatestConfigFile(L"luna.ini"));
    gGeneralConfig.loadOrDefault();
    //game.ini reader
    GameConfiguration::runPatchByIni(INIReader(WStr2Str(getLatestConfigFile(L"game.ini"))));

    /************************************************************************/
    /* Simple ASM Source Patches                                            */
    /************************************************************************/
    fixup_TypeMismatch13();
    fixup_Credits();
    fixup_Mushbug();
    fixup_Veggibug();
    fixup_NativeFuncs();
    fixup_BGODepletion();

    /************************************************************************/
    /* Replaced Imports                                                     */
    /************************************************************************/
    IMP_vbaStrCmp = &replacement_VbaStrCmp;

    /************************************************************************/
    /* Set Hook                                                             */
    /************************************************************************/
    HookWnd = SetWindowsHookExA(WH_CALLWNDPROC, MsgHOOKProc, (HINSTANCE)NULL, GetCurrentThreadId());
    if (!HookWnd){
        DWORD errCode = GetLastError();
        std::string errCmd = "Failed to Hook";
        errCmd += "\nErr-Code: ";
        errCmd += std::to_string((long long)errCode);
        MessageBoxA(NULL, errCmd.c_str(), "Failed to Hook", NULL);
    }

    KeyHookWnd = SetWindowsHookExA(WH_KEYBOARD, KeyHOOKProc, (HINSTANCE)NULL, GetCurrentThreadId());
    if (!KeyHookWnd){
        DWORD errCode = GetLastError();
        std::string errCmd = "Failed to Hook";
        errCmd += "\nErr-Code: ";
        errCmd += std::to_string((long long)errCode);
        MessageBoxA(NULL, errCmd.c_str(), "Failed to Hook", NULL);
    }

    /************************************************************************/
    /* Source Code Function Patch                                           */
    /************************************************************************/
    PATCH(0x8D9446)
        .CALL(&OnLvlLoad)
        .NOP()
        .NOP()
        .Apply();

    PATCH(0x8CA23B)
        .CALL(&TestFunc)
        .NOP()
        .Apply();

    PATCH(0x92EC24)
        .CALL(&LevelHUDHook)
        .Apply();

    *(void**)0xB2F244 = (void*)&mciSendStringHookA;

    PATCH(0x8D6BB6).CALL(&forceTermination).Apply();

    PATCH(0x8C11D5).CALL(&LoadWorld).Apply();

    PATCH(0x8C16F7).CALL(&WorldLoop).Apply();

    PATCH(0x8C0E6D).CALL(&LoadIntro).Apply();

    PATCH(0x932353).CALL(&printLunaLuaVersion).Apply();

    PATCH(0x9090F5).CALL(&WorldRender).Apply();

    PATCH(0x9204E5).CALL(&NPCKillHook).Apply();
    PATCH(0x9B4E35).CALL(&NPCKillHook).Apply();
    PATCH(0xA0664E).CALL(&NPCKillHook).Apply();
    PATCH(0xA23278).CALL(&NPCKillHook).Apply();

    PATCH(0xAA4352)
        .CALL(&__vbaStrCmp_TriggerSMBXEventHook)
        .NOP()
        .Apply();

    PATCH(0x8C23CB)
        .CALL(&checkLevelShutdown)
        .NOP()
        .NOP()
        .Apply();

    PATCH(0xA755D2).CALL(&UpdateInputHook_Wrapper).Apply();


    PATCH(0x902D3D).CALL(&WorldOverlayHUDBitBltHook).Apply();
    PATCH(0x902DFC).CALL(&WorldOverlayHUDBitBltHook).Apply();
    PATCH(0x902EBB).CALL(&WorldOverlayHUDBitBltHook).Apply();
    PATCH(0x902F80).CALL(&WorldOverlayHUDBitBltHook).Apply();

    PATCH(0x908995).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9087A8).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9085BB).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9083CE).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x908115).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x907F28).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x907D3B).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x907B4E).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9077FD).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x907537).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9072B2).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x90702D).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x906DB2).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9055CE).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x905304).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9051A7).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x905055).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x904F24).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x908995).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x904D4F).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9062E0).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x906183).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x906031).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x905F00).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x905D29).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x905990).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9065DE).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x906973).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x90499A).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9046D0).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x904573).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x904421).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9042F0).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x90411B).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x906B31).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x903D66).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9063FF).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x903A9C).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x90393F).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9037ED).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9036BC).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9034E7).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9032E9).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x90323D).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x90319F).CALL(&WorldIconsHUDBitBltHook).Apply();
    PATCH(0x9030F2).CALL(&WorldIconsHUDBitBltHook).Apply();


    PATCH(0x9000B2).CALL(&WorldHUDIsOnCameraHook).Apply();
    PATCH(0x900235).CALL(&WorldHUDIsOnCameraHook).Apply();
    PATCH(0x9004B7).CALL(&WorldHUDIsOnCameraHook).Apply();
    PATCH(0x90068F).CALL(&WorldHUDIsOnCameraHook).Apply();

    PATCH(0x901439).CALL(&WorldHUDPrintTextController).Apply();
    PATCH(0x90266A).CALL(&WorldHUDPrintTextController).Apply();
    PATCH(0x907611).CALL(&WorldHUDPrintTextController).Apply();
    PATCH(0x9081E7).CALL(&WorldHUDPrintTextController).Apply();
    PATCH(0x908B03).CALL(&WorldHUDPrintTextController).Apply();
    PATCH(0x908A67).CALL(&WorldHUDPrintTextController).Apply();

    PATCH(0x909217).CALL(&GenerateScreenshotHook).Apply();
    PATCH(0x94D5E7).CALL(&GenerateScreenshotHook).Apply();

    PATCH(0x8C03DC).CALL(&InitLevelEnvironmentHook).Apply();
    PATCH(0x8C0A1A).CALL(&InitLevelEnvironmentHook).Apply();
    PATCH(0x8C1383).CALL(&InitLevelEnvironmentHook).Apply();
    PATCH(0x8C1953).CALL(&InitLevelEnvironmentHook).Apply();
    PATCH(0x8CE292).CALL(&InitLevelEnvironmentHook).Apply();
    PATCH(0x8E61BD).CALL(&InitLevelEnvironmentHook).Apply();
    PATCH(0x8FE8D4).CALL(&InitLevelEnvironmentHook).Apply();
    PATCH(0x987E94).CALL(&InitLevelEnvironmentHook).Apply();
    PATCH(0x9B7B2C).CALL(&InitLevelEnvironmentHook).Apply();
    PATCH(0xA02AD3).CALL(&InitLevelEnvironmentHook).Apply();


    // Graphics Bitblt hooks
    PATCH(0x8C137E).CALL(&LoadLocalGfxHook).Apply();
    PATCH(0x8D8BF1).CALL(&LoadLocalGfxHook).Apply();
    PATCH(0x8D9611).CALL(&LoadLocalGfxHook).Apply();
    PATCH(0x8DF52B).CALL(&LoadLocalGfxHook).Apply();
    PATCH(0x8DFF7C).CALL(&LoadLocalGfxHook).Apply();

    PATCH(0x8DEF73).CALL(&LoadLocalOverworldGfxHook).Apply();
    PATCH(0x8DF808).CALL(&LoadLocalOverworldGfxHook).Apply();

    //PATCH(0x4242D0).JMP(GET_RETADDR_TRACE_HOOK<&BitBltTraceHook>()).Apply();
    PATCH(0x4242D0).JMP(&BitBltHook).Apply();
    PATCH(0x424314).JMP(&StretchBltHook).Apply();

    PATCH(0x8E54EC)
        .CALL(&MessageBoxOpenHook)
        .NOP()
        .Apply();

    // Okay redigit, I know your debug values are in general pretty dumb, but right now they are awesome for easy patching! Thx mate!
    PATCH(0x90C856)
        .CALL(&CameraUpdateHook_Wrapper)
        .NOP()
        .NOP()
        .Apply();

    // Hook to fix 100% CPU when window is inactive
    PATCH(0x8E6FE1)
        .NOP()
        .CALL(&WindowInactiveHook)
        .Apply();

    // PATCH(0x96CC61).TRACE_CALL<&HardcodedGraphicsBitBltHook>().Apply();

    // Don't trust QPC as much on WinXP
    void* frameTimingHookPtr;
    void* frameTimingMaxFPSHookPtr;
    if (gIsWindowsVistaOrNewer) {
        frameTimingHookPtr = (void*)&FrameTimingHookQPC;
        frameTimingMaxFPSHookPtr = (void*)&FrameTimingMaxFPSHookQPC;
    }
    else {
        frameTimingHookPtr = (void*)&FrameTimingHook;
        frameTimingMaxFPSHookPtr = (void*)&FrameTimingMaxFPSHook;
    }

    // Hooks to fix 100% CPU during operation
    // These ones are normally not sensitive to the "max FPS" setting
    PATCH(0x8BFD4A).SAFE_CALL(frameTimingHookPtr).NOP_PAD_TO_SIZE<0x40>().Apply();
    PATCH(0x8C0488).SAFE_CALL(frameTimingHookPtr).NOP_PAD_TO_SIZE<0x40>().Apply();
    PATCH(0x8C0EE6).SAFE_CALL(frameTimingHookPtr).NOP_PAD_TO_SIZE<0x40>().Apply();

    // These ones are normally sensitive to the "max FPS" setting
    PATCH(0x8C15A7).SAFE_CALL(frameTimingMaxFPSHookPtr).NOP_PAD_TO_SIZE<0x4A>().Apply();
    PATCH(0x8C20FC).SAFE_CALL(frameTimingMaxFPSHookPtr).NOP_PAD_TO_SIZE<0x4A>().Apply();
    PATCH(0x8E2AED).SAFE_CALL(frameTimingMaxFPSHookPtr).NOP_PAD_TO_SIZE<0x4A>().Apply();
    PATCH(0x8E56ED).SAFE_CALL(frameTimingMaxFPSHookPtr).NOP_PAD_TO_SIZE<0x4A>().Apply();

    // Logging for NPC collisions
    //PATCH(0xA281B0).JMP(GET_RETADDR_TRACE_HOOK<&collideNPCLoggingHook>()).NOP().Apply();

    // Level and world render hooks
    PATCH(0x909290).JMP(RenderLevelHook).NOP().Apply();
    PATCH(0x8FEB10).JMP(RenderWorldHook).NOP().Apply();

    // Level rendering layering hooks

    //PATCH(0x90C856).NOP().NOP().CALL(GetRenderBelowPriorityHook<-95>()).Apply();
    //-100: Level Background
    PATCH(0x90F4FA).NOP().NOP().CALL(GetRenderBelowPriorityHook<-95>()).Apply();
    // -95: Furthest back BGOs
    PATCH(0x910433).NOP().NOP().CALL(GetRenderBelowPriorityHook<-90>()).Apply();
    // -90: Sizable Blocks
    PATCH(0x910E5D).NOP().NOP().CALL(GetRenderBelowPriorityHook<-85>()).Apply();
    // -85: Some more BGOs
    PATCH(0x911F19).NOP().NOP().CALL(GetRenderBelowPriorityHook<-80>()).Apply();
    // -80: Warp - Derived BGOs (locks on doors and stuff)
    PATCH(0x912748).NOP().NOP().CALL(GetRenderBelowPriorityHook<-75>()).Apply();
    // -75: Background NPCs (vines, piranah plants, diggable sand, mother brain, things in MB jars)
    PATCH(0x915316).NOP().NOP().CALL(GetRenderBelowPriorityHook<-70>()).Apply();
    // -70: Held NPCs
    PATCH(0x91D422).NOP().NOP().CALL(GetRenderBelowPriorityHook<-65>()).Apply();
    // -65: Normal Blocks
    PATCH(0x91DD44).NOP().NOP().CALL(GetRenderBelowPriorityHook<-60>()).Apply();
    // -60: Furthest Back Effects (doors, pressed p-switches, some other stuff)
    PATCH(0x91E1F2).NOP().NOP().CALL(GetRenderBelowPriorityHook<-55>()).Apply();
    // -55: Some NPCs (i.e. coins, clown car, chompy, herb, wood rocket, koopaling fire)
    PATCH(0x91F802).NOP().NOP().CALL(GetRenderBelowPriorityHook<-50>()).Apply();
    // -50: Some NPCs (ice blocks)
    PATCH(0x920040).NOP().NOP().CALL(GetRenderBelowPriorityHook<-45>()).Apply();
    // -45: Normal NPCs
    PATCH(0x922D00).NOP().NOP().CALL(GetRenderBelowPriorityHook<-40>()).Apply();
    // -40: Symbol above NPCs that want to chat (hardcoded-43/44)
    PATCH(0x923786).NOP().NOP().CALL(GetRenderBelowPriorityHook<-35>()).Apply();
    // -35: Player Mounts
    PATCH(0x927F21).NOP().NOP().CALL(GetRenderBelowPriorityHook<-30>()).Apply();
    // -30: Something else player mount related?
    PATCH(0x928EA5).NOP().NOP().CALL(GetRenderBelowPriorityHook<-25>()).Apply();
    // -25: Players
    PATCH(0x928F0A).NOP().NOP().CALL(GetRenderBelowPriorityHook<-20>()).Apply();
    // -20: Foreground BGOs
    PATCH(0x929F81).NOP().NOP().CALL(GetRenderBelowPriorityHook<-15>()).Apply();
    // -15: Foreground NPCs
    PATCH(0x92B428).NOP().NOP().CALL(GetRenderBelowPriorityHook<-10>()).Apply();
    // -10: Foreground Blocks
    PATCH(0x92BAC0).NOP().NOP().CALL(GetRenderBelowPriorityHook<-5>()).Apply();
    //  -5: Foreground Effects (all not at 0091DD90)
    // Handle Priority 5 from LevelHUDHook
    //   5: HUD
    PATCH(0x939977).NOP().NOP().CALL(GetRenderBelowPriorityHook<100>()).Apply();

    // Change Mode Hook
    // Runs when the game starts or the game mode changes.
    PATCH(0x8BF4E3).CALL(runtimeHookSmbxChangeModeHookRaw).NOP_PAD_TO_SIZE<10>().Apply();

    // Load level hook
    PATCH(0x8D8F40).JMP(runtimeHookLoadLevel).NOP_PAD_TO_SIZE<6>().Apply();

    // Close window hook
    PATCH(0x8BE3DA).CALL(runtimeHookCloseWindow).Apply();

    // Anti-Fullscreen hook
    PATCH(0x95429A).CALL(runtimeHookChangeResolution).Apply();
    PATCH(0xA98142).CALL(runtimeHookChangeResolution).Apply();
    PATCH(0xA98166).CALL(runtimeHookChangeResolution).Apply();
    PATCH(0x96ADD7).CALL(runtimeHookSmbxCheckWindowedRaw).NOP_PAD_TO_SIZE<8>().Apply();

    PATCH(0x9DB1D8).JMP(runtimeHookBlockBumpableRaw).NOP_PAD_TO_SIZE<6>().Apply();

    PATCH(0xA28FE3).JMP(runtimeHookNPCVulnerabilityRaw).Apply();

    PATCH(0x9A9D33).JMP(runtimeHookNPCSpinjumpSafeRaw).NOP_PAD_TO_SIZE<10>().Apply();

    PATCH(0xA75079).JMP(runtimeHookCheckInputRaw).NOP_PAD_TO_SIZE<7>().Apply();

    /************************************************************************/
    /* Import Table Patch                                                   */
    /************************************************************************/
    __vbaR4Var = (float(*)(VARIANTARG*))0x00401124;
    *(void**)0x00401124 = (void*)&vbaR4VarHook;
    rtcMsgBox = (int(__stdcall *)(VARIANTARG*, DWORD, DWORD, DWORD, DWORD))(*(void**)0x004010A8);
    *(void**)0x004010A8 = (void*)&rtcMsgBoxHook;
}
Beispiel #2
0
bool FreeImageData::loadFile(const std::wstring &filename)
{
    void* theFile;
    void* theMap;
    void* theAddress;
    theFile = CreateFileW(filename.c_str(), GENERIC_READ, 1, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (theFile == INVALID_HANDLE_VALUE)
        return false;

    DWORD size = GetFileSize(theFile, NULL);

    theMap = CreateFileMappingW(theFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if( theMap == NULL )
    {
        CloseHandle(theFile);
        return false;
    }
    theAddress = MapViewOfFile(theMap, FILE_MAP_READ, 0, 0, size);
    if(theAddress == NULL)
    {
        CloseHandle(theMap);
        CloseHandle(theFile);
        return false;
    }

    bool reply = loadMem((unsigned char*)theAddress, size, WStr2Str(filename));

    try{ UnmapViewOfFile(theAddress); } catch(void * /*e*/) {}
    try{ CloseHandle(theMap); } catch(void * /*e*/) {}
    try{ CloseHandle(theFile);} catch(void* /*e*/) {}

    return reply;
}
bool DirMan::DirMan_private::getListOfFolders(std::vector<std::string> &list, const std::vector<std::string> &suffix_filters)
{
    list.clear();
    HANDLE hFind;
    WIN32_FIND_DATAW data;

    hFind = FindFirstFileW((m_dirPathW + L"/*").c_str(), &data);
    if(hFind == INVALID_HANDLE_VALUE)
        return false;
    do
    {
        if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
        {
            if((wcscmp(data.cFileName, L"..") == 0) || (wcscmp(data.cFileName, L".") == 0))
                continue;
            std::string fileName = WStr2Str(data.cFileName);
            if(matchSuffixFilters(fileName, suffix_filters))
                list.push_back(fileName);
        }
    }
    while(FindNextFileW(hFind, &data));
    FindClose(hFind);

    return true;
}
luabind::object luabindResolveFile(std::string file, lua_State* L){
    std::vector<std::string> paths = {
        WStr2Str(getCustomFolderPath()),
        (std::string)GM_FULLDIR,
        WStr2Str(getModulePath()) + "\\LuaScriptsLib\\",
        WStr2Str(getModulePath()) + "\\"
    };



    for (std::string nextSearchPath : paths) {
        std::string nextEntry = nextSearchPath + file;
        DWORD objectAttributes = GetFileAttributesA(nextEntry.c_str());
        if(objectAttributes == INVALID_FILE_ATTRIBUTES)
            continue;
        if(objectAttributes & FILTER)
            return luabind::object(L, nextEntry);
    }

    return luabind::object();
}
void DirMan::DirMan_private::setPath(const std::string &dirPath)
{
    m_dirPathW = Str2WStr(dirPath);
    wchar_t fullPath[MAX_PATH];
    GetFullPathNameW(m_dirPathW.c_str(), MAX_PATH, fullPath, NULL);
    m_dirPathW = fullPath;
    //Force UNIX paths
    std::replace(m_dirPathW.begin(), m_dirPathW.end(), L'\\', L'/');
    m_dirPath = WStr2Str(m_dirPathW);
    delEnd(m_dirPathW, L'/');
    delEnd(m_dirPath, '/');
}
bool DirMan::DirMan_private::fetchListFromWalker(std::string &curPath, std::vector<std::string> &list)
{
    if(m_walkerState.digStack.empty())
        return false;

    list.clear();

    std::wstring path = m_walkerState.digStack.top();
    m_walkerState.digStack.pop();

    HANDLE hFind;
    WIN32_FIND_DATAW data;

    hFind = FindFirstFileW((path + L"/*").c_str(), &data);
    if(hFind == INVALID_HANDLE_VALUE)
        return true; //Can't read this directory. Continue
    do
    {
        if((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
        {
            if((wcscmp(data.cFileName, L"..") == 0) || (wcscmp(data.cFileName, L".") == 0))
                continue;

            m_walkerState.digStack.push(path + L"/" + data.cFileName);
        }
        else
        {
            std::string fileNameU = WStr2Str(data.cFileName);
            if(matchSuffixFilters(fileNameU, m_walkerState.suffix_filters))
                list.push_back(fileNameU);
        }
    }
    while(FindNextFileW(hFind, &data));

    FindClose(hFind);
    curPath = WStr2Str(path);

    return true;
}
Beispiel #7
0
std::string LuaProxy::Data::resolvePathFromSection()
{
	std::string levelName = WStr2Str(::Level::GetName());
	std::string episodePath = (std::string)GM_FULLDIR;
	std::string smbxPath = WStr2Str(getModulePath());
	std::string returnPath = "";
	switch (m_dataType)
	{
	case LuaProxy::Data::DATA_LEVEL:
		returnPath += episodePath;
		returnPath += removeExtension(levelName);
		returnPath += "\\";
		returnPath += "LuaData_";
		if (m_useSaveSlot)
			returnPath += "Save" + std::to_string(GM_CUR_SAVE_SLOT) + "_";
		returnPath += m_sectionName;
		returnPath += ".txt";
		break;
	case LuaProxy::Data::DATA_WORLD:
		returnPath += episodePath;
		returnPath += "LuaData_";
		if (m_useSaveSlot)
			returnPath += "Save" + std::to_string(GM_CUR_SAVE_SLOT) + "_";
		returnPath += m_sectionName;
		returnPath += ".txt";
		break;
	case LuaProxy::Data::DATA_GLOBAL:
	default:
		returnPath += smbxPath;
		returnPath += "\\worlds\\";
		returnPath += "LuaData_";
		if (m_useSaveSlot)
			returnPath += "Save" + std::to_string(GM_CUR_SAVE_SLOT) + "_";
		returnPath += m_sectionName;
		returnPath += ".txt";
		break;
	}
	return returnPath;
}
Beispiel #8
0
// TRY LOAD WORLD VARS
bool SavedVariableBank::TryLoadWorldVars() {
	if(Saves::GetCurSaveSlot() > 3)
		return false;
    std::wstring full_path = GetSaveFileFullPath(GetSaveFileName());

	ClearBank();

	// Try to open the file
    std::wfstream var_file(WStr2Str(full_path).c_str(), std::ios::in | std::ios::out);

	// If open failed, try to create empty file
	if(var_file.is_open() == false) {
        var_file.open(WStr2Str(full_path).c_str(), std::ios::out);
		var_file.flush();	
		var_file.close();
        var_file.open(WStr2Str(full_path).c_str(), std::ios::in | std::ios::out);;
	}

	// If create failed, get out
	if(var_file.is_open() == false)
		return false;

	// If size < 2 bytes, init new save file
	var_file.seekg(0, std::fstream::end);
	int cursize = (int)var_file.tellg();
	var_file.seekg(0, std::fstream::beg);

	if(cursize < 2) {
		InitSaveFile(&var_file);
		var_file.flush();		
		var_file.seekg(0, std::fstream::beg);
	}

	ReadFile(&var_file);
	
	var_file.flush();
	var_file.close();
	return true; 
}
Beispiel #9
0
// WRITE BANK
void SavedVariableBank::WriteBank() {
	if(Saves::GetCurSaveSlot() > 3)
		return;
    std::wstring full_path = GetSaveFileFullPath(GetSaveFileName());

    std::wfstream var_file(WStr2Str(full_path).c_str(), std::ios::out | std::ios::trunc);

	for(std::map<std::wstring, double>::iterator it = m_VarBank.begin(); it != m_VarBank.end(); ++it) {
		var_file << it->first << std::endl << it->second << std::endl;
	}

	var_file.flush();
	var_file.close();	
}
Beispiel #10
0
luabind::object LuaProxy::Misc::listFiles(const std::string& path, lua_State* L)
{
    luabind::object theList = luabind::newtable(L);
    std::string modulePath = path;
    if (!isAbsolutePath(path))
    {
        modulePath = WStr2Str(getModulePath());
        modulePath += "\\";
        modulePath += path;
    }
    std::vector<std::string> listedFiles = listFilesOfDir(modulePath);
    for (unsigned int i = 0; i < listedFiles.size(); ++i){
        theList[i + 1] = listedFiles[i];
    }
    return theList;

}
Beispiel #11
0
// CHECK SAVE DELETION
void SavedVariableBank::CheckSaveDeletion() {
	if(Saves::GetCurSaveSlot() > 3)
		return;
    std::wstring star_counter = SPECIAL_SAVE_STR;
	if(!VarExists(star_counter))
		SetVar(star_counter, GM_STAR_COUNT);		

	// Reset save slot detected? Reset the user save file too
	if(GM_STAR_COUNT < GetVar(SPECIAL_SAVE_STR)) {

		if(true) //DEBUG
			gLogger.Log(L"Deleting user save file - Star count: " + std::to_wstring((long long)GM_STAR_COUNT) + L" slot: " + std::to_wstring((long long)Saves::GetCurSaveSlot()), LOG_STD);

        std::wstring full_path = GetSaveFileFullPath(GetSaveFileName());
		ClearBank();
        std::wfstream var_file(WStr2Str(full_path).c_str(), std::ios::out);
		InitSaveFile(&var_file);
		var_file.flush();
		var_file.close();
	}
}
void ImageLoader::LoadHardcodedGfx(const std::unordered_map<std::wstring, ResourceFileInfo>* fileData, const std::unordered_map<std::wstring, ResourceFileInfo>* oldFileData)
{
    for (int idx1 = 1; idx1 <= HardcodedGraphicsItem::Size(); idx1++)
    {
        HardcodedGraphicsItem& hItemInfo = HardcodedGraphicsItem::Get(idx1);
        
        // No processing invalid or mask items here
        if ((hItemInfo.state != HardcodedGraphicsItem::HITEMSTATE_NORMAL) && (hItemInfo.state != HardcodedGraphicsItem::HITEMSTATE_ARRAY))
            continue;

        int minItem = hItemInfo.isArray() ? hItemInfo.minItem : -1;
        int maxItem = hItemInfo.isArray() ? hItemInfo.maxItem : -1;
        for (int idx2 = minItem; idx2 <= maxItem; idx2++)
        {
            if (hItemInfo.isArray() && !hItemInfo.isValidArrayIndex(idx2))
            {
                // If this index isn't valid, skip it
                continue;
            }
            HDC colorHDC = nullptr;
            HDC maskHDC = nullptr;
            hItemInfo.getHDC(idx2, &colorHDC, &maskHDC);

            if (colorHDC == nullptr)
            {
                // No such thing as mask-only graphics
                continue;
            }

            std::wstring hardcodedName = L"hardcoded-" + std::to_wstring(idx1);
            if (hItemInfo.isArray())
            {
                hardcodedName +=  L"-" + std::to_wstring(idx2);
            }

            // Make note of name to HDC mapping
            m_NameToHDC[WStr2Str(hardcodedName)] = (uintptr_t)colorHDC;

            ResourceFileInfo newMain, newMask;
            ResourceFileInfo oldMain, oldMask;
            getImageResource(hardcodedName, *fileData, newMain, newMask);
            if (oldFileData != nullptr)
            {
                getImageResource(hardcodedName, *oldFileData, oldMain, oldMask);
            }

            // If anything has changed, reload
            if ((oldFileData == nullptr) || (newMain != oldMain) || (newMask != oldMask))
            {
                std::shared_ptr<LunaImage> img = nullptr;
                std::shared_ptr<LunaImage> mask = nullptr;

                if (newMain.done)
                {
                    // If we found a file, load from it
                    img = LunaImage::fromFile(newMain.path.c_str(), &newMain);
                    mask = LunaImage::fromFile(newMask.path.c_str(), &newMask);
                }
                else
                {
                    // Otherwise, load from HDC
                    img = LunaImage::fromHDC(colorHDC);
                    mask = LunaImage::fromHDC(maskHDC);

                    // TODO: Consider special case for maskless hardcoded graphics from HDC, where black should be made transparent
                }

                if (img && mask)
                {
                    img->setMask(mask);
                }

                if (img)
                {
                    if (colorHDC != nullptr) ImageLoader::m_Gfx[(uintptr_t)colorHDC] = img;
                    if (maskHDC != nullptr)  ImageLoader::m_Gfx[(uintptr_t)maskHDC] = img;
                }
            }
        }
    }
}
void ImageLoaderCategory::updateLoadedImages(const std::unordered_map<std::wstring, ResourceFileInfo>* fileData, const std::unordered_map<std::wstring, ResourceFileInfo>* oldFileData)
{
    uint32_t firstIdx = m_Category.getFirstIdx();
    uint32_t lastIdx = m_Category.getLastIdx();

    std::wstring prefix = m_Category.getPrefix();
    for (uint32_t i = firstIdx; i <= lastIdx; i++)
    {
        std::wstring imageName = prefix + L"-" + std::to_wstring(i);
        ResourceFileInfo newMain, newMask;
        ResourceFileInfo oldMain, oldMask;
        getImageResource(imageName, *fileData, newMain, newMask);
        if (oldFileData != nullptr)
        {
            getImageResource(imageName, *oldFileData, oldMain, oldMask);
        }

        // If anything has changed, reload
        if ((oldFileData == nullptr) || (newMain != oldMain) || (newMask != oldMask))
        {
            uint32_t width = 0, height = 0;

            HDC mainImgHdc = nullptr;
            std::shared_ptr<LunaImage> mainImg = nullptr;
            if (m_Category.haveImagePtrArray())
            {
                // Make HDC if-needed
                mainImgHdc = m_Category.getImagePtr(i);
                if (mainImgHdc == nullptr)
                {
                    mainImgHdc = CreateCompatibleDC(NULL);
                    m_Category.setImagePtr(i, mainImgHdc);
                    ImageLoader::m_NameToHDC[WStr2Str(imageName)] = (uintptr_t)mainImgHdc;
                    ImageLoader::m_HDCToCategoryAndIndex[(uintptr_t)mainImgHdc] = std::pair<const SMBXImageCategory*, uint32_t>(&m_Category, i);
                }

                // Try to load image
                if (newMain.path.length() > 0)
                {
                    mainImg = LunaImage::fromFile(newMain.path.c_str(), &newMain);
                }

                // Assign image, note size
                ImageLoader::m_Gfx[(uintptr_t)mainImgHdc] = mainImg;
                if (mainImg)
                {
                    if (width < mainImg->getW()) width = mainImg->getW();
                    if (height < mainImg->getH()) height = mainImg->getH();
                }
            }
            else
            {
                // That's required...
                throw;
            }

            if (m_Category.haveMaskPtrArray() && mainImg)
            {
                // Match HDC to non-mask version
                m_Category.setMaskPtr(i, mainImgHdc);

                // Try to load image
                std::shared_ptr<LunaImage> maskImg = nullptr;
                if (newMask.path.length() > 0)
                {
                    maskImg = LunaImage::fromFile(newMask.path.c_str(), &newMask);
                }

                // Assign image, note size
                mainImg->setMask(maskImg);
                if (maskImg)
                {
                    if (width < maskImg->getW()) width = maskImg->getW();
                    if (height < maskImg->getH()) height = maskImg->getH();
                    mainImg->tryMaskToRGBA();
                }
            }

            m_Category.setWidth(i, (int16_t)min(width, 0x7FFF));
            m_Category.setHeight(i, (int16_t)min(height, 0x7FFF));
        }
    }
}
Beispiel #14
0
VOID
SetDefaultPLOTDM(
    HANDLE          hPrinter,
    PPLOTGPC        pPlotGPC,
    LPWSTR          pwDeviceName,
    PPLOTDEVMODE    pPlotDM,
    PFORMSIZE       pCurForm
    )

/*++

Routine Description:

    This function set the default devmode based on the current pPlotGPC

Arguments:

    hPrinter        - Handle to the printer

    pPlotGPC        - our loaded/verified GPC data.

    pwDeviceName    - the device name passed in

    pPlotDM         - Pointer to our ExtDevMode

    pCurForm        - Pointer to the FORMSIZE data structure which will be
                      updated if the pointer is not NULL, the final result of
                      the form size/imagable area selected by the user will
                      be written to here. the form name will be in
                      pPlotDM->dmFormName.

Return Value:

    VOID


Author:

    14-Dec-1993 Tue 20:21:48 updated  -by-  Daniel Chou (danielc)
        Update the dmScale based on maximum the device can support

    06-Dec-1993 Mon 12:49:52 updated  -by-  Daniel Chou (danielc)
        make sure we turn off the DM_xxx bits if one of those is not valid or
        supported in current plotter

    16-Nov-1993 Tue 13:49:27 created  -by-  Daniel Chou (danielc)


Revision History:


--*/

{
    WCHAR   DeviceName[CCHDEVICENAME];


    if (pwDeviceName) {

        _WCPYSTR(DeviceName, pwDeviceName, CCHDEVICENAME);

        //
        // Make sure the PlotGPC's device name is ssync with the pDeviceName
        // passed
        //

        WStr2Str(pPlotGPC->DeviceName, DeviceName);

        PLOTDBG(DBG_DEFDEVMODE, ("PlotGPC DeviceName=%hs\npwDeviceName=%ls",
                            pPlotGPC->DeviceName, pwDeviceName));

    } else {

        PLOTERR(("No DeviceName passed, using GPC's '%hs'",
                                                    pPlotGPC->DeviceName));

        str2Wstr(DeviceName, pPlotGPC->DeviceName);
    }

    //
    // Make a default copy first then copy device name down
    //

    CopyMemory(pPlotDM, &_DefPlotDM, sizeof(PLOTDEVMODE));

    WCPYFIELDNAME(pPlotDM->dm.dmDeviceName, DeviceName);

    //
    // We must turn off the DM_xxx bits in dmFields if we do not support it,
    // look at default fields we copy down then update it
    //

    if (pPlotGPC->MaxScale) {

        if ((WORD)pPlotDM->dm.dmScale > pPlotGPC->MaxScale) {

            pPlotDM->dm.dmScale = (SHORT)pPlotGPC->MaxScale;
        }

    } else {

        pPlotDM->dm.dmFields &= ~DM_SCALE;
    }

    if (pPlotGPC->MaxCopies <= 1) {

        pPlotDM->dm.dmFields &= ~DM_COPIES;
    }

    if (!(pPlotGPC->MaxQuality)) {

        pPlotDM->dm.dmFields &= ~DM_PRINTQUALITY;
    }

    //
    // DEFAULT 50% quality for byte align plotter (DJ 600) to do ROP right
    //

    if (pPlotGPC->Flags & PLOTF_RASTERBYTEALIGN) {

        pPlotDM->dm.dmPrintQuality = DMRES_LOW;

        PLOTWARN(("SetDefaultPLOTDM: HACK Default Qaulity = DMRES_LOW"));
    }

    if (!(pPlotGPC->Flags & PLOTF_COLOR)) {

        if (pPlotGPC->Flags & PLOTF_RASTER) {

            pPlotDM->dm.dmFields &= ~DM_COLOR;
            pPlotDM->dm.dmColor   = DMCOLOR_MONOCHROME;

        } else {

            PLOTASSERT(0,
                       "SetDefaultPLOTDM: The Pen Ploter CANNOT be MONO.",
                       (pPlotGPC->Flags & PLOTF_COLOR), 0);

            pPlotGPC->Flags |= PLOTF_COLOR;
        }
    }

    //
    // Set default form name based on the country
    //

    SetDefaultDMForm(pPlotDM, pCurForm);

}
Beispiel #15
0
VOID
SetDefaultPLOTDM(
                HANDLE          hPrinter,
    _In_        PPLOTGPC        pPlotGPC,
    _In_opt_    LPCWSTR         pwDeviceName,
    _In_        PPLOTDEVMODE    pPlotDM,
    _Out_opt_   PFORMSIZE       pCurForm
    )

/*++

Routine Description:

    This function set the default devmode based on the current pPlotGPC

Arguments:

    hPrinter        - Handle to the printer

    pPlotGPC        - our loaded/verified GPC data.

    pwDeviceName    - the device name passed in

    pPlotDM         - Pointer to our ExtDevMode

    pCurForm        - Pointer to the FORMSIZE data structure which will be
                      updated if the pointer is not NULL, the final result of
                      the form size/imagable area selected by the user will
                      be written to here. the form name will be in
                      pPlotDM->dmFormName.

Return Value:

    VOID


Author:

    14-Dec-1993 Tue 20:21:48 updated
        Update the dmScale based on maximum the device can support

    06-Dec-1993 Mon 12:49:52 updated
        make sure we turn off the DM_xxx bits if one of those is not valid or
        supported in current plotter

    16-Nov-1993 Tue 13:49:27 created


Revision History:


--*/

{
    WCHAR   *pwchDeviceName = NULL;
    ULONG   ulStrLen = 0;

    UNREFERENCED_PARAMETER(hPrinter);

    //
    // Device name including NULL terminator
    // must be equal or shorter than CCHDEVICENAME.
    // PREFIX doesn' take this assumption. Buffer size needs to be flexible and
    // should not be on stack.
    //
    if (pwDeviceName) {

        ulStrLen = (ULONG)wcslen(pwDeviceName);

        //
        // Allocate buffer to hold pwDeviceName including null terminator.
        // Make sure that pwDeviceName has a device name.
        //
        if (0 == ulStrLen ||
            !(pwchDeviceName = (WCHAR*)LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, (ulStrLen + 1) * sizeof(WCHAR))))
        {
            PLOTERR(("SetDefaultPLOTDM: memory allocaton failed.\n"));

            //
            // Make sure that pPlotGPC->DeviceName has a null terminator.
            //
            pPlotGPC->DeviceName[0] = (BYTE)'\0';
        }
        else
        {

            _WCPYSTR_FILL_TRAIL_WITH_NULL(pwchDeviceName, ulStrLen + 1, pwDeviceName);

            //
            // Make sure the PlotGPC's device name is ssync with the pDeviceName
            // passed.
            // String length must be equal or shorter than CCHDEVICENAME.
            // DEVMODE's device name and pPlotGPC->DeviceName can't hold a sting
            // longer than CCHDEVICENAME.
            //
            if (ulStrLen + 1 > CCHDEVICENAME)
            {
                PLOTERR(("SetDefaultPLOTDM: DeviceName is longer than buffer size.\n"));
            }
            else
            {
                WStr2Str(pPlotGPC->DeviceName, CCHOF(pPlotGPC->DeviceName), pwchDeviceName);
            }
        }

        PLOTDBG(DBG_DEFDEVMODE, ("PlotGPC DeviceName=%hs\npwDeviceName=%ls",
                            pPlotGPC->DeviceName, pwDeviceName));

    } else {

        PLOTERR(("No DeviceName passed, using GPC's '%hs'",
                                                    pPlotGPC->DeviceName));
        ulStrLen = (ULONG)strlen(pPlotGPC->DeviceName);

        //
        // Allocate buffer to hold pwDeviceName including null terminator.
        // Make sure that pwDeviceName has a device name.
        //
        if (0 == ulStrLen ||
            !(pwchDeviceName = (WCHAR*)LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, (ulStrLen + 1) * sizeof(WCHAR))))
        {
            PLOTERR(("SetDefaultPLOTDM: memory allocaton failed.\n"));
        }
        else
        {
            str2Wstr(pwchDeviceName, ulStrLen + 1, pPlotGPC->DeviceName);
        }
    }

    //
    // Make a default copy first then copy device name down
    //

    CopyMemory(pPlotDM, &_DefPlotDM, sizeof(PLOTDEVMODE));

    if (pwchDeviceName)
    {
        WCPYFIELDNAME(pPlotDM->dm.dmDeviceName, CCHOF(pPlotDM->dm.dmDeviceName), pwchDeviceName);
        LocalFree(pwchDeviceName);
    }
    else
    {
        pPlotDM->dm.dmDeviceName[0] = L'\0';
    }

    //
    // We must turn off the DM_xxx bits in dmFields if we do not support it,
    // look at default fields we copy down then update it
    //

    if (pPlotGPC->MaxScale) {

        if ((WORD)pPlotDM->dm.dmScale > pPlotGPC->MaxScale) {

            pPlotDM->dm.dmScale = (SHORT)pPlotGPC->MaxScale;
        }

    } else {

        pPlotDM->dm.dmFields &= ~DM_SCALE;
    }

    if (pPlotGPC->MaxCopies <= 1) {

        pPlotDM->dm.dmFields &= ~DM_COPIES;
    }

    if (!(pPlotGPC->MaxQuality)) {

        pPlotDM->dm.dmFields &= ~DM_PRINTQUALITY;
    }

    //
    // DEFAULT 50% quality for byte align plotter (DJ 600) to do ROP right
    //

    if (pPlotGPC->Flags & PLOTF_RASTERBYTEALIGN) {

        pPlotDM->dm.dmPrintQuality = DMRES_LOW;

        PLOTWARN(("SetDefaultPLOTDM: Force Default Qaulity = DMRES_LOW"));
    }

    if (!(pPlotGPC->Flags & PLOTF_COLOR)) {

        if (pPlotGPC->Flags & PLOTF_RASTER) {

            pPlotDM->dm.dmFields &= ~DM_COLOR;
            pPlotDM->dm.dmColor   = DMCOLOR_MONOCHROME;

        } else {

            PLOTASSERT(0,
                       "SetDefaultPLOTDM: The Pen Ploter CANNOT be MONO.",
                       (pPlotGPC->Flags & PLOTF_COLOR), 0);

            pPlotGPC->Flags |= PLOTF_COLOR;
        }
    }

    //
    // Set default form name based on the country/region
    //

    SetDefaultDMForm(pPlotDM, pCurForm);

}
Beispiel #16
0
luabind::object LuaProxy::Misc::listLocalFiles(std::string path, lua_State* L)
{
    return listFiles(WStr2Str(getCustomFolderPath()) + path, L);
}
Beispiel #17
0
// *EXPORT* On Level Load -- Run once as a level is loaded (including title screen level)
int OnLvlLoad() {

	// Restore some code the hook overwrote
	*(DWORD*)0x00B25958 = 0;
    
    ResetLunaModule();

    // WIP
    // dumpTypeLibrary((IDispatch*)*(DWORD*)0xB2D7E8, std::wcout);

    
    std::string custPath = WStr2Str(getCustomFolderPath());
    std::string wldPath = WStr2Str(GM_FULLDIR);
    std::string SndRoot = MusicManager::SndRoot();
    replaceSubStr(wldPath, "\"", "");
    replaceSubStr(wldPath, "\\\\", "\\");
    replaceSubStr(wldPath, "/", "\\");

    replaceSubStr(SndRoot, "\"", "");
    replaceSubStr(SndRoot, "\\\\", "\\");
    replaceSubStr(SndRoot, "/", "\\");

    bool doSoundLoading = false;

    if ((!custPath.empty()) && (file_existsX(custPath + "\\sounds.ini"))) {
        //If custom-level specific sounds.ini detected
        doSoundLoading = true;
        LevelCustomSounds = true;
    }
    else if (LevelCustomSounds) {
        //If custom-level specific sounds.ini was NOT detected, but was loaded recently - reload episode specific sounds
        doSoundLoading = true;
        LevelCustomSounds = false;
    }

    if (!episodeStarted) {
        //Load custom sounds if episode is not finally started
        if (wldPath != SndRoot) doSoundLoading = true;
    }

    if (doSoundLoading) MusicManager::loadCustomSounds(wldPath + "\\", custPath);
//	BMPBox::initMovieCache();
	if(gLunaEnabled) {
		// Load autocode
		gAutoMan.Clear(false);		
		gAutoMan.ReadFile((std::wstring)GM_FULLDIR);

		// Try to load world codes		
		gAutoMan.ReadWorld((std::wstring)GM_FULLDIR);

		// Init var bank
		gSavedVarBank.TryLoadWorldVars();
		gSavedVarBank.CheckSaveDeletion();
		gSavedVarBank.CopyBank(&gAutoMan.m_UserVars);

        //  Don't try to call the CLunaLua constructor... It's already
        //  constructed automatically once, and trying to do this will call
        //  the constructor extra times *without* ever calling the destructor,
        //  which can result in a memory leak of the whole Lua state!
		//    gLunaLua = CLunaLua();
		gLunaLua.init(CLunaLua::LUNALUA_LEVEL, (std::wstring)GM_FULLDIR, Level::GetName());
        gLunaLua.setReady(true);

		// Do some stuff
		gAutoMan.DoEvents(true); // do with init

		// Init some stuff
		InitLevel();	
		gAutoMan.m_Hearts = 2;	

		// Recount deaths
		gDeathCounter.Recount();
	}

    //PGE DBG STUFF
    //readAndWriteNPCSettings();
    //overwriteFunc();

	return 0;
}