/**
* @file main.h
*
* @desc 第三方 RGSS Player
*
* @author 灼眼的夏娜
*
* @history 2009/07/21 初版
*/
#include <windows.h>
#include <stdio.h>
static const char* pWndClassName = "RGSS Player Ex";
static const char* pDefaultLibrary = "RGSS102J.dll";
static const char* pDefaultTitle = "Untitled";
static const char* pDefaultScripts = "Data\\Scripts.rxdata";
static const int nScreenWidth = 640;
static const int nScreenHeight = 480;
static const int nEvalErrorCode = 6;
void ShowErrorMsg(HWND hWnd, const char* szTitle, const char* szFormat, ...)
{
static char szError[1024];
va_list ap;
va_start(ap, szFormat);
vsprintf_s(szError, szFormat, ap);
va_end(ap);
MessageBoxA(hWnd, szError, szTitle, MB_ICONERROR);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
char szAppPath[MAX_PATH], szIniPath[MAX_PATH], szRgssadPath[MAX_PATH];
char szLibrary[MAX_PATH], szTitle[MAX_PATH], szScripts[MAX_PATH];
char* pRgssad = 0;
HWND hWnd = NULL;
HMODULE hRgssCore = NULL;
// app路径
DWORD len = ::GetModuleFileNameA(hInstance, szAppPath, MAX_PATH);
for (--len; len > 0; --len)
{
if (szAppPath[len] == '\\' || szAppPath[len] == '/')
{
szAppPath[len] = 0;
break;
}
}
SetCurrentDirectoryA(szAppPath);
// ini文件路径
len = ::GetModuleFileNameA(hInstance, szIniPath, MAX_PATH);
szIniPath[len - 1] = 'i';
szIniPath[len - 2] = 'n';
szIniPath[len - 3] = 'i';
// 加密包路径
len = ::GetModuleFileNameA(hInstance, szRgssadPath, MAX_PATH);
for (--len; len > 0; --len)
{
if (szRgssadPath[len] == '.')
{
//strcpy(...)
memcpy(&szRgssadPath[len + 1], "rgssad", strlen("rgssad") + 1);
//szRgssadPath[len + 1] = 'r';
//szRgssadPath[len + 2] = 'g';
//szRgssadPath[len + 3] = 's';
//szRgssadPath[len + 4] = 's';
//szRgssadPath[len + 5] = 'a';
//szRgssadPath[len + 6] = 'd';
//szRgssadPath[len + 7] = 0;
break;
}
}
// ini文件存在
if (GetFileAttributesA(szIniPath) != INVALID_FILE_ATTRIBUTES)
{
GetPrivateProfileStringA("Game", "Library", pDefaultLibrary, szLibrary, MAX_PATH, szIniPath);
GetPrivateProfileStringA("Game", "Title", pDefaultTitle, szTitle, MAX_PATH, szIniPath);
GetPrivateProfileStringA("Game", "Scripts", pDefaultScripts, szScripts, MAX_PATH, szIniPath);
}
else
{
memcpy(szLibrary, pDefaultLibrary, strlen(pDefaultLibrary) + 1);
memcpy(szTitle, pDefaultTitle, strlen(pDefaultTitle) + 1);
memcpy(szScripts, pDefaultScripts, strlen(pDefaultScripts) + 1);
}
if (GetFileAttributesA(szRgssadPath) != INVALID_FILE_ATTRIBUTES)
pRgssad = szRgssadPath;
// 创建窗口
WNDCLASS winclass;
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = DefWindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hInstance;
winclass.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = pWndClassName;
if (!RegisterClass(&winclass))
{
ShowErrorMsg(hWnd, szTitle, "注册窗口类失败 %s。", pWndClassName);
return 0;
}
int width = nScreenWidth + GetSystemMetrics(SM_CXFIXEDFRAME) * 2;
int height = nScreenHeight + GetSystemMetrics(SM_CYFIXEDFRAME) * 2 + GetSystemMetrics(SM_CYCAPTION);
RECT rt;
{
rt.left = (GetSystemMetrics(SM_CXSCREEN) - width) / 2;
rt.top = (GetSystemMetrics(SM_CYSCREEN) - height) / 2;
rt.right = rt.left + width;
rt.bottom = rt.top + height;
}
DWORD dwStyle = (WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE);
hWnd = ::CreateWindowEx(WS_EX_WINDOWEDGE, pWndClassName, szTitle, dwStyle,
rt.left, rt.top, rt.right - rt.left, rt.bottom - rt.top, 0, 0, hInstance, 0);
if (!hWnd)
{
ShowErrorMsg(hWnd, szTitle, "创建窗口失败 %s。", szTitle);
goto __exit;
}
ShowWindow(hWnd, SW_SHOW);
// 加载RGSS核心库
hRgssCore = ::LoadLibraryA(szLibrary);
if (!hRgssCore)
{
ShowErrorMsg(hWnd, szTitle, "加载RGSS核心库失败 %s。", szLibrary);
goto __exit;
}
typedef BOOL (*RGSSSetupRTP)(const char* pIniPath, char* pErrorMsgBuffer, int iBufferLength);
typedef void (*RGSSInitialize)(HMODULE hRgssDll);
typedef int (*RGSSEval)(const char* pScripts);
typedef void (*RGSSGameMain)(HWND hWnd, const char* pScriptNames, char** pRgssadName);
typedef BOOL (*RGSSExInitialize)(HWND hWnd);
RGSSSetupRTP pRGSSSetupRTP = NULL;
RGSSInitialize pRGSSInitialize = NULL;
RGSSEval pRGSSEval = NULL;
RGSSGameMain pRGSSGameMain = NULL;
RGSSExInitialize pRGSSExInitialize = (RGSSExInitialize)::GetProcAddress(hRgssCore, "RGSSExInitialize");
#define __get_check(fn) \
do \
{ \
p##fn = (fn)::GetProcAddress(hRgssCore, #fn); \
if (!p##fn) \
{ \
ShowErrorMsg(hWnd, szTitle, "获取RGSS核心库导出函数失败 %s。", #fn);\
goto __exit; \
} \
} while (0)
{
__get_check(RGSSSetupRTP);
__get_check(RGSSInitialize);
__get_check(RGSSEval);
__get_check(RGSSGameMain);
}
#undef __get_check
// 1、设置RTP
char szRtpName[1024];
if (!pRGSSSetupRTP(szIniPath, szRtpName, 1024))
{
ShowErrorMsg(hWnd, szTitle, "没有发现 RGSS-RTP %s。", szRtpName);
goto __exit;
}
// 2、初始化
pRGSSInitialize(hRgssCore);
// 2.1、扩展库初始化(补丁模式)
if (pRGSSExInitialize)
{
if (!pRGSSExInitialize(hWnd))
{
ShowErrorMsg(hWnd, szTitle, "RGSS扩展库初始化失败 %s。", "RGSSExInitialize");
goto __exit;
}
}
// 3、设置运行时变量
if (strcmp(lpCmdLine, "btest") == 0)
{
pRgssad = 0;
pRGSSEval("$DEBUG = true");
pRGSSEval("$BTEST = true");
}
else
{
if (strcmp(lpCmdLine, "debug") == 0)
{
pRgssad = 0;
pRGSSEval("$DEBUG = true");
}
else
pRGSSEval("$DEBUG = false");
pRGSSEval("$BTEST = false");
}
// 4、主逻辑
pRGSSGameMain(hWnd, szScripts, (pRgssad ? (char**)pRgssad : &pRgssad)); // ???
__exit:
if (hRgssCore)
{
FreeLibrary(hRgssCore);
hRgssCore = NULL;
}
if (hWnd)
{
DestroyWindow(hWnd);
hWnd = NULL;
}
UnregisterClassA("RGSS Player Ex", hInstance);
return 0;
}