I'm using odasl.h and odasl.lib in most all my single player maps to create a briefing dialog. Odasl is also used by PlymouthColdWar and TheMission. I believe we should move it into the API for common reference. I think it is a general Sierra Header file and possibly not specific only to Outpost 2. BlackBox seems to have done the original work on it, since it first showed up in PlymouthColdWar as far as I can tell.
We could just put it in API/odasl, but I'm not sure if would be more appropriate as a subfolder to another API project. Below is the contents of odasl.h and attached is the odasl.lib.
As a side note, an article on adding briefing screens to missions: http://wiki.outpost2.net/doku.php?id=op2_sdk:textdialogbox (http://wiki.outpost2.net/doku.php?id=op2_sdk:textdialogbox). Article needs more proof-reading and suffers from my limited knowledge of resources. I would be happy if someone with more knowledge on the subject cleaned it up, but hopefully it is useful in its current form.
odasl.h
// ODASL.DLL public interface.
// ODASL is the Sierra library that implements the ownerdraw in Outpost 2.
#ifndef ODASL_H
#define ODASL_H
#include <windows.h>
// Structure used to pass information to ODASL in wplInit.
struct wplOptions
{
ULONG structSize; // 60
ULONG unknown1; // 87 // Flags?
HINSTANCE hAppInst; // HINSTANCE OP2Shell.dll
HINSTANCE hResDllInst; // HINSTANCE op2shres.dll
ULONG startResId; // 200 // Starting resource id?
ULONG unknown3; // 0 // Palette?
ULONG unknown4; // 0 // More flags?
ULONG unknown5; // 96 // Size scale? Large values make windows huge
ULONG unknown[7]; // All 0
};
#ifdef BUILDING_ODASL
#define ODASL_API(rt) __declspec(dllexport) rt __cdecl
#else
#define ODASL_API(rt) __declspec(dllimport) rt __cdecl
#endif // BUILDING_ODASL
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
ODASL_API(int) wplInit(wplOptions *inf);
ODASL_API(void) wplExit();
ODASL_API(void) wplSetPalette(HPALETTE pal);
ODASL_API(int) wplGetSystemMetrics(int nIndex);
ODASL_API(BOOL) wplAdjustWindowRect(LPRECT lpRect, DWORD dwStyle, BOOL bMenu);
ODASL_API(HBITMAP) wplLoadResourceBitmap(HMODULE hModule, LPCTSTR lpName);
ODASL_API(int) wplManualDialogSubclass(HWND dlg);
ODASL_API(void) wplEnable();
ODASL_API(void) wplDisable();
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // ODASL_H
Perhaps the name Outpost2Dialog?
I can also put the code required to initialize the mission briefing dialog in the folder, briefing.cpp. It doesn't change between scenarios either. Really, the only thing that changes is briefing.rtf. The definition of the dialog box from the resource script file and resource.h doesn't change between scenarios either, but I'm not sure it would be smart to put the resource script file and associated resource.h in a project that is not the main level project that produces the dll.
I had a question on the header files though. In Black Box's original implementation of the briefing screen, there is no header file, just briefing.cpp. I added a header file in my implementation (mostly because I was troubleshooting and not knowing what I was doing at the time.)
I think the benefit of not using a header file is that it speeds up compile time. Are there other pros/cons? Is there a rule of thumb on when a header file should or should not be used? For example, I noticed it is common in Outpost 2 scenarios to separate out base scripting into a large function and place it in a separate .cpp file without giving it a header. Then just calling extern void BaseScriptingFunction() in main.cpp.
briefing.cpp from BlackBox
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
// These are needed for the mission briefing
#include <richedit.h>
#include "resource.h"
#include "odasl\odasl.h"
// These deal with the briefing screen
extern HINSTANCE hInst;
LRESULT CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void ShowBriefing()
{
// OP2 turns off the skinning before the game loads.
// We have to re-enable it (otherwise the briefing box will look ugly).
wplEnable();
// Show the dialog box, using the shell window as the parent
HWND shellWnd = FindWindow("Outpost2Shell", NULL);
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_MISSIONINFO), shellWnd, (DLGPROC)DialogProc, NULL);
// Turn off the skinning again (probably not needed but a good idea to do it anyway)
wplDisable();
}
LRESULT CALLBACK DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
...
}