Author Topic: Op2mod.dll  (Read 2688 times)

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3209
Op2mod.dll
« on: September 24, 2008, 04:57:04 PM »
So, uh... I actually tried looking around about this, but...
Is there some sort of tutorial on making an OP2Mod.dll? What I need and have to do, and any other important info would be nice to know.  It's important for MT2, in order to prevent suckage and loading old, MT1 maps.
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4913
Op2mod.dll
« Reply #1 on: September 24, 2008, 08:52:53 PM »
If I remember right, the /loadmod parameter just loads your DLL into the Outpost2 address space. Everything else is up to the DLL to handle.

When Windows loads the DLL, it will make a call to DllMain. If you need to hook anything, or make any changes, that's you're one chance to get setup. Windows also calls DllMain (with different parameters) when unloading the DLL, so you can also do cleanup in there.
 

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3209
Op2mod.dll
« Reply #2 on: September 25, 2008, 09:23:52 AM »
That doesn't really answer my question... What do I need to do so that I can, for example, change OP2 so it looks for "zXX.dll" for colony games instead of "cXX.dll"?
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4913
Op2mod.dll
« Reply #3 on: September 25, 2008, 11:32:49 AM »
Yeah, and I'm basically saying you're on your own. There is no standard way to make these changes. The DLLs that get loaded this way normally do some sort of mem hacking, or code overwriting to accomplish their goals. The /loadmod thing is really generic and basic. It doesn't do a whole lot for you. The actual specifics of what you want to do has nothing to do with /loadmod.


You should probably ask Eddy-B how he made the changes for Renegades. Failing that, I can probably dig up the approximate code location that needs modifications. But I'd rather not look into this if someone else has already done it.
 

Offline Arklon

  • Administrator
  • Hero Member
  • *****
  • Posts: 1240
Op2mod.dll
« Reply #4 on: September 25, 2008, 11:40:46 AM »
Hooman, I think you're forgetting the code that goes into a mod.dll :P Here's my CM1 mod.dll as an example,

Code: [Select]
// String table patch

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define EXPORT extern "C" __declspec(dllexport)

char **stringTable = (char**)0x004E88F8;
char *oldAddr[7];

void EXPORT mod_init()
{
// This code will be called during the DLL_PROCESS_ATTACH event of DllMain in op2ext.dll.
// No other code will have been run before this time.
// This is the appropriate place to add VOLs to the list or set the mod serial number.
// Use it to do anything you need to do before the code of Outpost2.exe begins executing.
}

void EXPORT mod_run()
{
// This code is called immediately after OP2Shell.dll is loaded and the language data is localized.
// (Right before the OP2 menu displays)
// It is too late to add VOLs or set the serial number (the game has already initialized this stuff)
// Use it to setup things that aren't already setup in mod_init. (The ResManager will be inited as well
// as the language strings)

    char *verAddr = (char*)0x004E973C;
    verAddr[0] = 49;
    verAddr[2] = 51;
    verAddr[4] = 48;
    verAddr[6] = 52;

for (int i = 0; i < 6; i++)
  oldAddr[i] = *(stringTable+658+i);
    oldAddr[7] = *(stringTable+834);

*(stringTable+658) = "Rose";
*(stringTable+659) = "Dark Red";
    *(stringTable+660) = "Black";
*(stringTable+661) = "Orange";
    *(stringTable+662) = "Teal";
*(stringTable+663) = "White";
*(stringTable+834) = "ZIG";
}

void EXPORT mod_destroy()
{
// This is called in the DLL_PROCESS_DETACH event of DllMain as op2ext.dll is unloading.
// Use it to cleanup any loose ends you created earlier in mod_init or mod_run.

for (int i = 0; i < 6; i++)
  *(stringTable+658+i) = oldAddr[i];
*(stringTable+834) = oldAddr[7];
}


Offline Eddy-B

  • Hero Member
  • *****
  • Posts: 1194
    • http://www.eddy-b.com
Op2mod.dll
« Reply #5 on: September 25, 2008, 11:47:22 AM »
Since there is a need to know, i will post my the Renegades modload source here. Do with it as you please (don't forget to mention my name in your credits list - if you have one that is :P).
Code: [Select]

//----------------------------------------------------------------------------------------
// Outpost - Renegades
//----------------------------------------------------------------------------------------
// Module loader

#define EXPORT extern "C" __declspec(dllexport)

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include "outpost2app.h"
#include "public.h"

#define arraysize(x) (sizeof(x)/sizeof(*(x)))
#define autosize(x)  (x),arraysize(x)

#define Msg(x)  OP2MessageBox(NULL,(x),"DEBUG",MB_OK)

char s[80];
typedef int (__fastcall *EMB)(int,char*,char*,unsigned int);
EMB OP2MessageBox = (EMB)0x0041E0E0;

//----------------------------------------------------------------------------------------

char ren[]="REN";
char renegades[]="Renegades";

char version[]="1.0.0.0";

//char modulename[80];
//char moddir[80];

// PatchInfo contains information about the patch
struct PatchInfo
{
int memlocation;
char *patch;
int bytes;
};

PatchInfo patches[]=
{
{ 0x4E96A0,autosize(ren)-1 },
{ 0x4E96C0,autosize(ren)-1 },

// change file extention "OP2" into "REN"
{ 0x4E061C,autosize(ren)-1 },
{ 0x4E0630,autosize(ren)-1 },
{ 0x4E5AB7,autosize(ren)-1 },
{ 0x4E5ABE,autosize(ren)-1 },

// "Failed to load OP2Shell" > "RENShell"
{ 0x4E5AD3,autosize(ren)-1 },

// "INI" > "REN"
{ 0x4DF36C,autosize(ren)-1 },

// mission dll names
{ 0x4E971C,"Q",1 },
// { 0x4E9728,"F",1 },

// "Outpost 2" > "Renegades"
{ 0x4E484A,autosize(renegades)-1 },
{ 0x4E4870,autosize(renegades)-1 },
{ 0x4E555C,autosize(renegades)-1 },
{ 0x4E561A,autosize(renegades)-1 },
{ 0x4E57FE,autosize(renegades)-1 },
{ 0x4E580C,autosize(renegades)-1 },
{ 0x4E5AA4,autosize(renegades)-1 },
{ 0x4E5BE0,autosize(renegades)-1 },
{ 0x4E5C6C,autosize(renegades)-1 },
{ 0x4E5DEC,autosize(renegades)-1 },
{ 0x4E6124,autosize(renegades)-1 },
{ 0x4E7CC6,autosize(renegades)-1 },
{ 0x4E7CEE,autosize(renegades)-1 },

// Version info
{ 0x4E973C,autosize(version)-1 },  // unused at the moment
};


void patch(PatchInfo pi)
{
_asm {
  MOV ECX,pi.bytes
  MOV EDI,pi.memlocation
  MOV ESI,pi.patch
  REP MOVSB
}
}


void PatchOutpost()
{
for (int i=0; i<arraysize(patches); ++i)
  patch(patches[i]);
}

/*
void ExtractDir()
{
int x,l=strlen(modulename);
bool foundend=false;

x=l;
while (--x>=0)
{
  if (modulename[x]=='\\') foundend=true;
  if (foundend) moddir[x]=modulename[x];
}
}

// concat's mod-folder and volname
void AddVol(char *volname)
{
char filename[128];

strcpy(filename,moddir);
strcat(filename,volname);
AddVolToList(filename);
}
*/

//----------------------------------------------------------------------------------------
// Exported functions -> required by op2ext.dll
//----------------------------------------------------------------------------------------


EXPORT void mod_init()
{
PatchOutpost();
AddVolToList("ren.vol");  // renegades story + briefings
AddVolToList("extra.vol");  // extra waves
AddVolToList("ren1.vol");  // first 4 missions + tek files
}

EXPORT void mod_run()
{
}

EXPORT void mod_destroy()
{
}

// Main DLL entry Routine
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
// GetModuleFileName((HMODULE)hModule,modulename,sizeof(modulename)-1);
// ExtractDir();
   return TRUE;
}

You can start up Outpost using: OUTPOST2.EXE /MODLOAD <modname> and OP2 will open the subfolder <modname> and load & execute the file modload.dll

You will always need to export the functions mod_init, mod_run, mod_destroy and ofcourse DllMain.
Rule #1:  Eddy is always right
Rule #2: If you think he's wrong, see rule #1
--------------------

Outpost : Renegades - Eddy-B.com - Electronics Pit[/siz

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4913
Op2mod.dll
« Reply #6 on: September 25, 2008, 12:00:37 PM »
Quote
You will always need to export the functions mod_init, mod_run, mod_destroy and ofcourse DllMain.

The net fix doesn't do this. It only has DllMain. That other ones would appear to be optional.


Edit: Hmm, yes, I just checked some source BlackBox sent me. It does try to find those functions, but checks for NULL before trying to call them. I never even knew it looked for them actually. Nobody ever told me. (Mind you, by the time I asked about it, I don't think anyone remembered how it worked). Anyways, you can use those functions, but they are optional.
 
« Last Edit: September 25, 2008, 12:04:23 PM by Hooman »

Offline Eddy-B

  • Hero Member
  • *****
  • Posts: 1194
    • http://www.eddy-b.com
Op2mod.dll
« Reply #7 on: September 25, 2008, 12:22:49 PM »
If i remember correctly: DllMain is called right after the mod dll is loaded, while the mod_init function is called after outpost is done loading all its libraries.

In my case (patching the code) i need op2 to be loaded completely.
You should check with Blackbox to be sure.
Rule #1:  Eddy is always right
Rule #2: If you think he's wrong, see rule #1
--------------------

Outpost : Renegades - Eddy-B.com - Electronics Pit[/siz

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4913
Op2mod.dll
« Reply #8 on: September 25, 2008, 01:12:16 PM »
According to the source, mod_init is called immediately after LoadLibrary is called on the mod DLL. This is all done from a call from op2ext's DllMain.
 

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3209
Op2mod.dll
« Reply #9 on: September 25, 2008, 03:28:49 PM »
Thanks, Arklon and Eddy-B!
Hooman, you smell!  :P But thanks for trying.
Now let's see how I can abuse... err, enhance OP2 when I get some free time!

Edit: Where can I get outpost2app.h and public.h? Though I imagine I have public.h but only have to find it...
« Last Edit: September 25, 2008, 04:06:36 PM by Sirbomber »
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4913
Op2mod.dll
« Reply #10 on: September 25, 2008, 04:51:08 PM »
Ahh yes, the forgotten header file: Outpost2App.h thread

I have no idea about the other one. I don't remember any public.h.
 

Offline Eddy-B

  • Hero Member
  • *****
  • Posts: 1194
    • http://www.eddy-b.com
Op2mod.dll
« Reply #11 on: September 27, 2008, 11:44:28 AM »
Maybe i made that header (i don't know).
Judging from the remark i placed after GetCurrentModDir function, it seems i talked to op2hacker (BlackBox) about the contents..


Anyway, here it is!
« Last Edit: September 27, 2008, 11:44:42 AM by Eddy-B »
Rule #1:  Eddy is always right
Rule #2: If you think he's wrong, see rule #1
--------------------

Outpost : Renegades - Eddy-B.com - Electronics Pit[/siz

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3209
Op2mod.dll
« Reply #12 on: October 03, 2008, 04:15:26 PM »
So, uh, is there a list of changeable stuff and what I need to know to change said stuff anywhere?
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4913
Op2mod.dll
« Reply #13 on: October 03, 2008, 04:36:44 PM »
Well apparently you can change the list of loaded Vol files. Other than that, it looks like you're pretty much on your own.