-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.cpp
247 lines (199 loc) · 6.5 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#include "obse/PluginAPI.h"
#include "obse/CommandTable.h"
#include "Hooks.h"
#include "Redirector.h"
#if OBLIVION
#include "obse/GameAPI.h"
/* As of 0020, ExtractArgsEx() and ExtractFormatStringArgs() are no longer directly included in plugin builds.
They are available instead through the OBSEScriptInterface.
To make it easier to update plugins to account for this, the following can be used.
It requires that g_scriptInterface is assigned correctly when the plugin is first loaded.
*/
#define ENABLE_EXTRACT_ARGS_MACROS 1 // #define this as 0 if you prefer not to use this
#if ENABLE_EXTRACT_ARGS_MACROS
OBSEScriptInterface * g_scriptInterface = NULL; // make sure you assign to this
#define ExtractArgsEx(...) g_scriptInterface->ExtractArgsEx(__VA_ARGS__)
#define ExtractFormatStringArgs(...) g_scriptInterface->ExtractFormatStringArgs(__VA_ARGS__)
#endif
#else
#include "obse_editor/EditorAPI.h"
#endif
#include "obse/ParamInfos.h"
#include "obse/Script.h"
#include "obse/GameObjects.h"
#include <string>
IDebugLog gLog("Transformation Framework.log");
PluginHandle g_pluginHandle = kPluginHandle_Invalid;
OBSESerializationInterface * g_serialization = NULL;
OBSEArrayVarInterface * g_arrayIntfc = NULL;
OBSEScriptInterface * g_scriptIntfc = NULL;
/***************************
* Serialization routines
***************************/
std::string g_strData;
static void ResetData(void)
{
g_strData.clear();
}
static void ExamplePlugin_SaveCallback(void * reserved)
{
// write out the string
g_serialization->OpenRecord('STR ', 0);
g_serialization->WriteRecordData(g_strData.c_str(), g_strData.length());
// write out some other data
g_serialization->WriteRecord('ASDF', 1234, "hello world", 11);
}
static void ExamplePlugin_LoadCallback(void * reserved)
{
UInt32 type, version, length;
ResetData();
char buf[512];
while(g_serialization->GetNextRecordInfo(&type, &version, &length))
{
_MESSAGE("record %08X (%.4s) %08X %08X", type, &type, version, length);
switch(type)
{
case 'STR ':
g_serialization->ReadRecordData(buf, length);
buf[length] = 0;
_MESSAGE("got string %s", buf);
g_strData = buf;
break;
case 'ASDF':
g_serialization->ReadRecordData(buf, length);
buf[length] = 0;
_MESSAGE("ASDF chunk = %s", buf);
break;
default:
_MESSAGE("Unknown chunk type $08X", type);
}
}
}
static void ExamplePlugin_PreloadCallback(void * reserved)
{
_MESSAGE("Preload Callback start");
ExamplePlugin_LoadCallback(reserved);
_MESSAGE("Preload Callback finished");
}
static void ExamplePlugin_NewGameCallback(void * reserved)
{
ResetData();
}
/**************************
* Command definitions
**************************/
/*************************
Messaging API example
*************************/
OBSEMessagingInterface* g_msg;
void MessageHandler(OBSEMessagingInterface::Message* msg)
{
switch (msg->type)
{
case OBSEMessagingInterface::kMessage_ExitGame:
_MESSAGE("Plugin Example received ExitGame message");
break;
case OBSEMessagingInterface::kMessage_ExitToMainMenu:
_MESSAGE("Plugin Example received ExitToMainMenu message");
break;
case OBSEMessagingInterface::kMessage_PostLoad:
_MESSAGE("Plugin Example received PostLoad mesage");
break;
case OBSEMessagingInterface::kMessage_LoadGame:
case OBSEMessagingInterface::kMessage_SaveGame:
_MESSAGE("Plugin Example received save/load message with file path %s", msg->data);
break;
case OBSEMessagingInterface::kMessage_PreLoadGame:
_MESSAGE("Plugin Example received pre-loadgame message with file path %s", msg->data);
break;
case OBSEMessagingInterface::kMessage_ExitGame_Console:
_MESSAGE("Plugin Example received quit game from console message");
break;
default:
break;
}
}
extern "C" {
bool OBSEPlugin_Query(const OBSEInterface * obse, PluginInfo * info)
{
_MESSAGE("query");
// fill out the info structure
info->infoVersion = PluginInfo::kInfoVersion;
info->name = "Transformation Framework and other additions";
info->version = 1;
// version checks
if(!obse->isEditor)
{
if(obse->obseVersion < OBSE_VERSION_INTEGER)
{
_ERROR("OBSE version too old (got %08X expected at least %08X)", obse->obseVersion, OBSE_VERSION_INTEGER);
return false;
}
#if OBLIVION
if(obse->oblivionVersion != OBLIVION_VERSION)
{
_ERROR("incorrect Oblivion version (got %08X need %08X)", obse->oblivionVersion, OBLIVION_VERSION);
return false;
}
#endif
g_serialization = (OBSESerializationInterface *)obse->QueryInterface(kInterface_Serialization);
if(!g_serialization)
{
_ERROR("serialization interface not found");
return false;
}
if(g_serialization->version < OBSESerializationInterface::kVersion)
{
_ERROR("incorrect serialization version found (got %08X need %08X)", g_serialization->version, OBSESerializationInterface::kVersion);
return false;
}
g_arrayIntfc = (OBSEArrayVarInterface*)obse->QueryInterface(kInterface_ArrayVar);
if (!g_arrayIntfc)
{
_ERROR("Array interface not found");
return false;
}
g_scriptIntfc = (OBSEScriptInterface*)obse->QueryInterface(kInterface_Script);
}
else
{
// no version checks needed for editor
}
// version checks pass
return true;
}
bool OBSEPlugin_Load(const OBSEInterface * obse)
{
_MESSAGE("load");
g_pluginHandle = obse->GetPluginHandle();
/***************************************************************************
*
* READ THIS!
* -
* Before releasing your plugin, you need to request an opcode range from
* the OBSE team and set it in your first SetOpcodeBase call. If you do not
* do this, your plugin will create major compatibility issues with other
* plugins, and may not load in future versions of OBSE. See
* obse_readme.txt for more information.
*
**************************************************************************/
// register commands
//obse->SetOpcodeBase(0x2000);
// set up serialization callbacks when running in the runtime
if (!obse->isEditor)
{
InitHooks();
CreareRedirections();
InstallRedirects();
// NOTE: SERIALIZATION DOES NOT WORK USING THE DEFAULT OPCODE BASE IN RELEASE BUILDS OF OBSE
// it works in debug builds
g_serialization->SetSaveCallback(g_pluginHandle, ExamplePlugin_SaveCallback);
g_serialization->SetLoadCallback(g_pluginHandle, ExamplePlugin_LoadCallback);
g_serialization->SetNewGameCallback(g_pluginHandle, ExamplePlugin_NewGameCallback);
#if 0 // enable below to test Preload callback, don't use unless you actually need it
g_serialization->SetPreloadCallback(g_pluginHandle, ExamplePlugin_PreloadCallback);
#endif
}
return true;
}
};