scummvm/engines/tony/mpal/mpal.h
2014-02-28 22:49:05 +01:00

503 lines
16 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/*
* This code is based on original Tony Tough source code
*
* Copyright (c) 1997-2003 Nayma Software
*/
/****************************************************************************\
* General Introduction
\****************************************************************************/
/*
* MPAL (MultiPurpose Adventure Language) is a high level language
* for the definition of adventure. Through the use of MPAL you can describe
* storyboard the adventure, and then use it with any user interface.
* In fact, unlike many other similar products, MPAL is not programmed through
* the whole adventure, but are defined only the locations, objects, as they may
* interact with each other, etc.. thus making MPAL useful for any type of adventure.
*/
/****************************************************************************\
* Structure
\****************************************************************************/
/*
* MPAL consists of two main files: MPAL.DLL and MPAL.H
* The first is the DLL that contains the code to interface with MPAL
* adventures, the second is the header that defines the prototypes
* functions. MPAL is compiled for Win32, and it can therefore be used with
* any compiler that supports Win32 DLL (Watcom C++, Visual C++,
* Delphi, etc.), and therefore compatible with both Windows 95 and Windows NT.
*
* To use the DLL, and 'obviously need to create a library for symbols to export.
*
*/
/****************************************************************************\
* Custom Functions
\****************************************************************************/
/*
* A custom function and a function specified by the program that uses the
* library, to perform the particular code. The custom functions are
* retrieved from the library as specified in the source MPAL, and in particular
* in defining the behavior of an item with some action.
*
* To use the custom functions, you need to prepare an array of
* pointers to functions (such as using the type casting LPCUSTOMFUNCTION,
* (defined below), and pass it as second parameter to mpalInit (). Note you
* must specify the size of the array, as elements of pointers and which do not
* contain the same: the library will call it only those functions specified in
* the source MPAL. It can be useful, for debugging reasons, do not bet
* the shares of arrays used to debugging function, to avoid unpleasant crash,
* if it has been made an error in source and / or some oversight in the code.
*
*/
#ifndef TONY_MPAL_H
#define TONY_MPAL_H
#include "common/scummsys.h"
#include "common/coroutines.h"
#include "common/rect.h"
#include "common/str.h"
#include "tony/mpal/memory.h"
namespace Tony {
namespace MPAL {
/****************************************************************************\
* Macro definitions and structures
\****************************************************************************/
// OK value for the error codes
#define OK 0
#define MAXFRAMES 400 // frame animation of an object
#define MAXPATTERN 40 // pattern of animation of an object
#define MAXPOLLINGLOCATIONS 64
#define GETARG(type) va_arg(v, type)
/**
* Macro for use with queries that may refer to X and Y co-ordinates
*/
enum QueryCoordinates {
MPQ_X,
MPQ_Y
};
/**
* Query can be used with mpalQuery methods. In practice corresponds all claims
* that can do at the library
*/
enum QueryTypes {
// General Query
MPQ_VERSION = 10,
MPQ_GLOBAL_VAR = 50,
MPQ_RESOURCE,
MPQ_MESSAGE,
// Query on leases
MPQ_LOCATION_IMAGE = 100,
MPQ_LOCATION_SIZE,
// Queries about items
MPQ_ITEM_LIST = 200,
MPQ_ITEM_DATA,
MPQ_ITEM_PATTERN,
MPQ_ITEM_NAME,
MPQ_ITEM_IS_ACTIVE,
// Query dialog
MPQ_DIALOG_PERIOD = 300,
MPQ_DIALOG_WAITFORCHOICE,
MPQ_DIALOG_SELECTLIST,
MPQ_DIALOG_SELECTION,
// Query execution
MPQ_DO_ACTION = 400,
MPQ_DO_DIALOG
};
/**
* Framework to manage the animation of an item
*/
typedef struct {
char *_frames[MAXFRAMES];
Common::Rect _frameslocations[MAXFRAMES];
Common::Rect _bbox[MAXFRAMES];
short _pattern[MAXPATTERN][MAXFRAMES];
short _speed;
char _numframe;
char _numpattern;
char _curframe;
char _curpattern;
short _destX, _destY;
signed char _destZ;
short _objectID;
} Item;
typedef Item *LpItem;
/**
* Define a custom function, to use the language MPAL to perform various controls as a result of an action
*/
typedef void (*LPCUSTOMFUNCTION)(CORO_PARAM, uint32, uint32, uint32, uint32);
typedef LPCUSTOMFUNCTION *LPLPCUSTOMFUNCTION;
/**
*
* Define an IRQ of an item that is called when the pattern changes or the status of an item
*/
typedef void (*LPITEMIRQFUNCTION)(uint32, int, int);
typedef LPITEMIRQFUNCTION* LPLPITEMIRQFUNCTION;
/**
* @defgroup Macrofunctions query
*
* The following are defines used for simplifying calling the mpalQuery variants
*/
//@{
/**
* Gets the current version of MPAL
*
* @returns Version number (0x1232 = 1.2.3b)
*/
#define mpalQueryVersion() \
(uint16)mpalQueryDWORD(MPQ_VERSION)
/**
* Gets the numerical value of a global variable
*
* @param lpszVarName Variable name (ASCIIZ)
* @returns Global variable value
* @remarks This query was implemented for debugging. The program,
* if well designed, should not need to access variables from
* within the library.
*/
#define mpalQueryGlobalVar(lpszVarName) \
mpalQueryDWORD(MPQ_GLOBAL_VAR, (const char *)(lpszVarName))
/**
* Provides access to a resource inside the .MPC file
*
* @param dwResId Resource Id
* @returns Handle to a memory area containing the resource, ready for use.
*/
#define mpalQueryResource(dwResId) \
mpalQueryHANDLE(MPQ_RESOURCE, (uint32)(dwResId))
/**
* Returns a message.
*
* @param nMsg Message number
* @returns ASCIIZ message
* @remarks The returned pointer must be freed via the memory manager
* after use. The message will be in ASCIIZ format.
*/
#define mpalQueryMessage(nMsg) \
(char *)mpalQueryHANDLE(MPQ_MESSAGE, (uint32)(nMsg))
/**
* Provides a location image
* @return Returns a picture handle
*/
#define mpalQueryLocationImage(nLoc) \
mpalQueryHANDLE(MPQ_LOCATION_IMAGE, (uint32)(nLoc))
/**
* Request the x or y size of a location in pixels
*
* @param nLoc Location number
* @param dwCoord MPQ_X or MPQ_Y coordinate to retrieve
* @returns Size
*/
#define mpalQueryLocationSize(nLoc, dwCoord) \
mpalQueryDWORD(MPQ_LOCATION_SIZE, (uint32)(nLoc), (uint32)(dwCoord))
/**
* Provides the list of objects in a location.
*
* @param nLoc Location number
* @returns List of objects (accessible by Item [0], Item [1], etc.)
*/
// TODO: Determine if this is endian safe
#define mpalQueryItemList(nLoc) \
(uint32 *)mpalQueryHANDLE(MPQ_ITEM_LIST, (uint32)(nLoc))
/**
* Provides information on an item
*
* @param nItem Item number
* @returns Structure filled with requested information
*/
#define mpalQueryItemData(nItem) \
(LpItem)mpalQueryHANDLE(MPQ_ITEM_DATA, (uint32)(nItem))
/**
* Provides the current pattern of an item
*
* @param nItem Item number
* @returns Number of animation patterns to be executed.
* @remarks By default, the pattern of 0 indicates that we should do nothing.
*/
#define mpalQueryItemPattern(nItem) \
mpalQueryDWORD(MPQ_ITEM_PATTERN, (uint32)(nItem))
/**
* Returns true if an item is active
*
* @param nItem Item number
* @returns TRUE if the item is active, FALSE otherwise
*/
#define mpalQueryItemIsActive(nItem) \
(bool)mpalQueryDWORD(MPQ_ITEM_IS_ACTIVE, (uint32)(nItem))
/**
* Returns the name of an item
*
* @param nItem Item number
* @param lpszName Pointer to a buffer of at least 33 bytes
* that will be filled with the name
* @remarks If the item is not active (ie. if its status or number
* is less than or equal to 0), the string will be empty.
*/
#define mpalQueryItemName(nItem, lpszName) \
mpalQueryHANDLE(MPQ_ITEM_NAME, (uint32)(nItem), (char *)(lpszName))
/**
* Returns a sentence of dialog.
*
* @param nDialog Dialog number
* @param nPeriod Number of words
* @returns A pointer to the string of words, or NULL on failure.
* @remarks The string must be freed after use using the memory manager.
* Unlike normal messages, the sentences of dialogue are formed by a single
* string terminated with 0.
*/
#define mpalQueryDialogPeriod(nPeriod) \
(char *)mpalQueryHANDLE(MPQ_DIALOG_PERIOD, (uint32)(nPeriod))
/**
* Wait until the moment in which the need is signaled to make a choice by the user.
* @returns Number of choice to be made, or -1 if the dialogue is finished.
*/
#define mpalQueryDialogWaitForChoice(dwRet) \
CORO_INVOKE_2(mpalQueryCORO, MPQ_DIALOG_WAITFORCHOICE, dwRet)
/**
* Requires a list of various options for some choice within the current dialog.
*
* @param nChoice Choice number
* @returns A pointer to an array containing the data matched to each option.
* @remarks The figure 'a uint32 specified in the source to which MPAL
* You can assign meaning that the more' suits.
* The pointer msut be freed after use using the memory memory.
*/
#define mpalQueryDialogSelectList(nChoice) \
(uint32 *)mpalQueryHANDLE(MPQ_DIALOG_SELECTLIST, (uint32)(nChoice))
/**
* Warns the library that the user has selected, in a certain choice of the current dialog,
* corresponding option at a certain given.
*
* @param nChoice Choice number of the choice that was in progress
* @param dwData Option that was selected by the user.
* @returns TRUE if all OK, FALSE on failure.
* @remarks After execution of this query, MPAL continue
* Groups according to the execution of the dialogue. And necessary so the game
* remains on hold again for another chosen by mpalQueryDialogWaitForChoice ().
*/
#define mpalQueryDialogSelection(nChoice, dwData) \
(bool)mpalQueryDWORD(MPQ_DIALOG_SELECTION, (uint32)(nChoice), (uint32)(dwData))
#define mpalQueryDialogSelectionDWORD(nChoice, dwData) \
mpalQueryDWORD(MPQ_DIALOG_SELECTION, (uint32)(nChoice), (uint32)(dwData))
/**
* Warns the library an action was performed on a Object.
* The library will call custom functions, if necessary.
*
* @param nAction Action number
* @param nItem Item number
* @param dwParam Action parameter
* @returns Handle to the thread that is performing the action, or CORO_INVALID_PID_VALUE
* if the action is not defined for the item, or the item is inactive.
* @remarks The parameter is used primarily to implement actions
* as "U.S." involving two objects together. The action will be executed only
* if the item is active, ie if its status is a positive number greater than 0.
*/
#define mpalQueryDoAction(nAction, nItem, dwParam) \
mpalQueryDWORD(MPQ_DO_ACTION, (uint32)(nAction), (uint32)(nItem), (uint32)(dwParam))
/**
* Warns the library a dialogue was required.
*
* @param nDialog Dialog number
* @param nGroup Group number to use
* @returns Handle to the thread that is running the box, or
* CORO_INVALID_PID_VALUE if the dialogue does not exist.
*/
#define mpalQueryDoDialog(nDialog, nGroup) \
mpalQueryDWORD(MPQ_DO_DIALOG, (uint32)(nDialog), (uint32)(nGroup))
/**
* @defgroup Functions exported to the main game
*/
//@{
/**
* Initializes the MPAL library, and opens an .MPC file, which will be 'used for all queries
* @param lpszMpcFileName Name of the .MPC file, including extension
* @param lpszMprFileName Name of the .MPR file, including extension
* @param lplpcfArray Array of pointers to custom functions
* @returns TRUE if all OK, FALSE on failure
*/
bool mpalInit(const char *lpszFileName, const char *lpszMprFileName,
LPLPCUSTOMFUNCTION lplpcfArray, Common::String *lpcfStrings);
/**
* Frees resources allocated by the MPAL subsystem
*/
void mpalFree();
/**
* This is a general function to communicate with the library, to request information
* about what is in the .MPC file
*
* @param wQueryType Type of query. The list is in the QueryTypes enum.
* @returns 4 bytes depending on the type of query
* @remarks This is the specialized version of the original single mpalQuery
* method that returns numeric results.
*/
uint32 mpalQueryDWORD(uint16 wQueryType, ...);
/**
* This is a general function to communicate with the library, to request information
* about what is in the .MPC file
*
* @param wQueryType Type of query. The list is in the QueryTypes enum.
* @returns 4 bytes depending on the type of query
* @remarks This is the specialized version of the original single mpalQuery
* method that returns a pointer or handle.
*/
MpalHandle mpalQueryHANDLE(uint16 wQueryType, ...);
/**
* This is a general function to communicate with the library, to request information
* about what is in the .MPC file
*
* @param wQueryType Type of query. The list is in the QueryTypes enum.
* @returns 4 bytes depending on the type of query
* @remarks This is the specialized version of the original single mpalQuery
* method that needs to run within a co-routine context.
*/
void mpalQueryCORO(CORO_PARAM, uint16 wQueryType, uint32 *dwRet);
/**
* Execute a script. The script runs on multitasking by a thread.
*
* @param nScript Script number to run
* @returns TRUE if the script 'was launched, FALSE on failure
*/
bool mpalExecuteScript(int nScript);
/**
* Returns the current MPAL error code
*
* @returns Error code
*/
uint32 mpalGetError();
/**
* Install a custom routine That will be called by MPAL every time the pattern
* of an item has been changed.
*
* @param lpiifCustom Custom function to install
*/
void mpalInstallItemIrq(LPITEMIRQFUNCTION lpiifCustom);
/**
* Process the idle actions of the items on one location.
*
* @param nLoc Number of the location whose items must be processed
* for idle actions.
* @returns TRUE if all OK, and FALSE if it exceeded the maximum limit.
* @remarks The maximum number of locations that can be polled
* simultaneously is defined defined by MAXPOLLINGFUNCIONS
*/
bool mpalStartIdlePoll(int nLoc);
/**
* Stop processing the idle actions of the items on one location.
*
* @param nLo Number of the location
* @returns TRUE if all OK, FALSE if the specified location was not
* in the process of polling
*/
void mpalEndIdlePoll(CORO_PARAM, int nLoc, bool *result);
/**
* Load a save state from a buffer.
*
* @param buf Buffer where to store the state
* @returns Length of the state buffer in bytes
*/
int mpalLoadState(byte *buf);
/**
* Store the save state into a buffer. The buffer must be
* length at least the size specified with mpalGetSaveStateSize
*
* @param buf Buffer where to store the state
*/
void mpalSaveState(byte *buf);
/**
* Retrieve the length of a save state
*
* @returns Length in bytes
*/
int mpalGetSaveStateSize();
/**
* Locks the variables for access
*/
void lockVar();
/**
* Unlocks variables after use
*/
void unlockVar();
} // end of namespace MPAL
} // end of namespace Tony
#endif