注册会员 登录
Project1 返回首页

独孤残云的个人空间 https://rpg.blue/?47826 [收藏] [复制] [分享] [RSS]

日志

【自行内嵌RGSS】相关讨论总结

已有 963 次阅读2010-10-21 08:46 |个人分类:讨论--启发--总结|

残云发布的讨论帖地址^_^||
 
总结:
=================================================================
 
From铃仙大人
 
HINSTANCE hInst;
hInst = LoadLibrary("RGSS202E.dll");
typedef int (_stdcall *fRGSSInitialize)(HINSTANCE);
typedef int (_stdcall *fRGSSFinalize)(void);
typedef int (_stdcall *fRGSSGameMain)(HWND, char*, char* /* ini */);
typedef int (_stdcall *fRGSSEval)(char*);
/* typedef int (_stdcall *fRGSSSetupRTP)(char*, int, int); */
fRGSSInitialize RGSSInitialize = GetProcAddress(hInst,"RGSSInitialize");
fRGSSFinalize RGSSFinalize = GetProcAddress(hInst,"RGSSFinalize");
fRGSSGameMain RGSSGameMain = GetProcAddress(hInst,"RGSSGameMain");
fRGSSEval RGSSEval = GetProcAddress(hInst,"RGSSEval");
fRGSSSetupRTP RGSSSetupRTP = GetProcAddress(hInst,"RGSSSetupRTP");
---------------------------------------------------------------
调用顺序是:
1. RGSSSetupRTP 获得 RTP  // 不知道参数,所以,Orz
2. RGSSInitialize 初始化 RGSS 解析器. // RGSSInitialize(hInst)
3. RGSSGameMain 游戏主循环 // RGSSGameMain(窗口句柄, 脚本文件名, ini文件名) 好像是这样的
N. RGSSEval 调用 // RGSSEval(脚本)
 
.dll动态加载:
比如说有个 dll 名字是 add.dll , 导出了一个函数 int _add(int, int), 加载就是这样:
HINSTANCE hInst;  //句柄
hInst = LoadLibrary("add.dll"); // 动态加载 add.dll
typedef int (_stdcall *dll_add)(int, int);  // 声明一个函数指针,用来指向导出的函数
dll_add d_add = GetProcAddress(hInst,"_add"); // 获取导出函数的地址。
print("1 + 2 = %d \n", d_add(1, 2)); // 然后就可以正常使用了~~
 
============================================================

IamI版主推荐
From夏娜版主

/**
* @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;
}

资源:点击下载

==============================================================

 

King大人的Phantom AVG Engine 0.99 古月 展望版

 

原帖地址:http://bbs.66rpg.com/thread-154984-1-1.html

 

相关资源下载请到King大人的原帖~

 

附图:

 

 


鸡蛋

鲜花

评论 (0 个评论)

facelist doodle 涂鸦笔

您需要登录后才可以评论 登录 | 注册会员

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-5-5 02:16

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

返回顶部