aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2012-06-09 01:20:08 +1000
committerPaul Gilbert2012-06-09 01:20:08 +1000
commit83f1cad02be38e56161350aabc29176f24c901a0 (patch)
tree7040f5d03e7c345c573a7b0a38553037dfcf1fe4
parent739983f42fae768dfee574122adbac93ac8b15d2 (diff)
downloadscummvm-rg350-83f1cad02be38e56161350aabc29176f24c901a0.tar.gz
scummvm-rg350-83f1cad02be38e56161350aabc29176f24c901a0.tar.bz2
scummvm-rg350-83f1cad02be38e56161350aabc29176f24c901a0.zip
TONY: Added code to free parsed MPC file data when the game ends
-rw-r--r--engines/tony/mpal/expr.cpp30
-rw-r--r--engines/tony/mpal/expr.h7
-rw-r--r--engines/tony/mpal/loadmpc.cpp108
-rw-r--r--engines/tony/mpal/loadmpc.h4
-rw-r--r--engines/tony/mpal/mpal.cpp1
-rw-r--r--engines/tony/tony.cpp1
6 files changed, 149 insertions, 2 deletions
diff --git a/engines/tony/mpal/expr.cpp b/engines/tony/mpal/expr.cpp
index 5ba2fff442..a9d48e2016 100644
--- a/engines/tony/mpal/expr.cpp
+++ b/engines/tony/mpal/expr.cpp
@@ -84,7 +84,7 @@ typedef struct {
byte type; // Tipo di oggetto (vedi enum ExprListTypes)
byte unary; // Unary operatore (NON SUPPORTATO)
- union {
+ union {
int num; // Numero (se type==ELT_NUMBER)
char *name; // Nome variabile (se type==ELT_VAR)
HGLOBAL son; // Handle a espressione (type==ELT_PARENTH)
@@ -400,6 +400,34 @@ bool compareExpressions(HGLOBAL h1, HGLOBAL h2) {
return true;
}
+/**
+ * Frees an expression that was previously parsed
+ *
+ * @param h Handle for the expression
+ */
+void freeExpression(HGLOBAL h) {
+ byte *data = (byte *)globalLock(h);
+ int num = *data;
+ LPEXPRESSION cur = (LPEXPRESSION)(data + 1);
+
+ for (int i = 0; i < num; ++i, ++cur) {
+ switch (cur->type) {
+ case ELT_VAR:
+ globalDestroy(cur->val.name);
+ break;
+
+ case ELT_PARENTH:
+ freeExpression(cur->val.son);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ globalUnlock(h);
+ globalFree(h);
+}
} // end of namespace MPAL
diff --git a/engines/tony/mpal/expr.h b/engines/tony/mpal/expr.h
index 9844add822..3130539000 100644
--- a/engines/tony/mpal/expr.h
+++ b/engines/tony/mpal/expr.h
@@ -65,6 +65,13 @@ int evaluateExpression(HGLOBAL h);
*/
bool compareExpressions(HGLOBAL h1, HGLOBAL h2);
+/**
+ * Frees an expression that was previously parsed
+ *
+ * @param h Handle for the expression
+ */
+void freeExpression(HGLOBAL h);
+
} // end of namespace MPAL
} // end of namespace Tony
diff --git a/engines/tony/mpal/loadmpc.cpp b/engines/tony/mpal/loadmpc.cpp
index 5a338b24b0..aa048c0b2f 100644
--- a/engines/tony/mpal/loadmpc.cpp
+++ b/engines/tony/mpal/loadmpc.cpp
@@ -122,6 +122,21 @@ static const byte *ParseScript(const byte *lpBuf, LPMPALSCRIPT lpmsScript) {
}
/**
+ * Frees a script allocated via a previous call to ParseScript
+ *
+ * @param lpmsScript Pointer to a script structure
+ */
+static void FreeScript(LPMPALSCRIPT lpmsScript) {
+ for (int i = 0; i < MAX_COMMANDS_PER_SCRIPT && (lpmsScript->_command[i].type); ++i, ++lpmsScript) {
+ if (lpmsScript->_command[i].type == 2) {
+ // Variable Assign
+ globalDestroy(lpmsScript->_command[i].lpszVarName);
+ freeExpression(lpmsScript->_command[i].expr);
+ }
+ }
+}
+
+/**
* Parses a dialog from the MPC file, and inserts its data into a structure
*
* @param lpBuf Buffer containing the compiled dialog.
@@ -428,6 +443,25 @@ static const byte *parseItem(const byte *lpBuf, LPMPALITEM lpmiItem) {
return lpBuf;
}
+/**
+ * Frees an item parsed from a prior call to ParseItem
+ *
+ * @param lpmiItem Pointer to an item structure
+ */
+static void freeItem(LPMPALITEM lpmiItem) {
+ // Free the actions
+ if (lpmiItem->Action)
+ globalDestroy(lpmiItem->Action);
+
+ // Free the commands
+ for (int i = 0; i < MAX_COMMANDS_PER_ITEM && (lpmiItem->_command[i].type); ++i, ++lpmiItem) {
+ if (lpmiItem->_command[i].type == 2) {
+ // Variable Assign
+ globalDestroy(lpmiItem->_command[i].lpszVarName);
+ freeExpression(lpmiItem->_command[i].expr);
+ }
+ }
+}
/**
* Parses a location from the MPC file, and inserts its data into a structure
@@ -651,6 +685,80 @@ bool ParseMpc(const byte *lpBuf) {
return true;
}
+/**
+ * Free the given dialog
+ */
+static void freeDialog(LPMPALDIALOG lpmdDialog) {
+ // Free the periods
+ int i;
+
+ for (i = 0; i < MAX_PERIODS_PER_DIALOG && (lpmdDialog->_periods[i]); ++i)
+ globalFree(lpmdDialog->_periods[i]);
+
+ for (i = 0; i < MAX_COMMANDS_PER_GROUP && (lpmdDialog->_command[i].type); i++) {
+ if (lpmdDialog->_command[i].type == 2) {
+ // Variable assign
+ globalDestroy(lpmdDialog->_command[i].lpszVarName);
+ freeExpression(lpmdDialog->_command[i].expr);
+ }
+ }
+}
+
+/**
+ * Frees any data allocated from the parsing of the MPC file
+ */
+void FreeMpc() {
+ int i;
+
+ // Free variables
+ globalFree(GLOBALS.hVars);
+
+ // Free messages
+ LPMPALMSG lpmmMsgs = (LPMPALMSG)globalLock(GLOBALS.hMsgs);
+ for (i = 0; i < GLOBALS.nMsgs; i++, ++lpmmMsgs)
+ globalFree(lpmmMsgs->hText);
+
+ globalUnlock(GLOBALS.hMsgs);
+ globalFree(GLOBALS.hMsgs);
+
+ // Free objects
+ if (GLOBALS.hDialogs) {
+ LPMPALDIALOG lpmdDialogs = (LPMPALDIALOG)globalLock(GLOBALS.hDialogs);
+
+ for (i = 0; i < GLOBALS.nDialogs; i++, ++lpmdDialogs)
+ freeDialog(lpmdDialogs);
+
+ globalFree(GLOBALS.hDialogs);
+ }
+
+ // Free items
+ if (GLOBALS.hItems) {
+ LPMPALITEM lpmiItems = (LPMPALITEM)globalLock(GLOBALS.hItems);
+
+ for (i = 0; i < GLOBALS.nItems; ++i, ++lpmiItems)
+ freeItem(lpmiItems);
+
+ globalUnlock(GLOBALS.hItems);
+ globalFree(GLOBALS.hItems);
+ }
+
+ // Free the locations
+ if (GLOBALS.hLocations) {
+ globalFree(GLOBALS.hLocations);
+ }
+
+ // Free the scripts
+ if (GLOBALS.hScripts) {
+ LPMPALSCRIPT lpmsScripts = (LPMPALSCRIPT)globalLock(GLOBALS.hScripts);
+
+ for (i = 0; i < GLOBALS.nScripts; ++i, ++lpmsScripts) {
+ FreeScript(lpmsScripts);
+ }
+
+ globalUnlock(GLOBALS.hScripts);
+ }
+}
+
} // end of namespace MPAL
} // end of namespace Tony
diff --git a/engines/tony/mpal/loadmpc.h b/engines/tony/mpal/loadmpc.h
index 2f8a1121ec..83463f0092 100644
--- a/engines/tony/mpal/loadmpc.h
+++ b/engines/tony/mpal/loadmpc.h
@@ -46,6 +46,10 @@ namespace MPAL {
*/
bool ParseMpc(const byte *lpBuf);
+/**
+ * Frees any data allocated from the parsing of the MPC file
+ */
+void FreeMpc();
} // end of namespace MPAL
diff --git a/engines/tony/mpal/mpal.cpp b/engines/tony/mpal/mpal.cpp
index 425fe187fc..04d562ffc9 100644
--- a/engines/tony/mpal/mpal.cpp
+++ b/engines/tony/mpal/mpal.cpp
@@ -803,7 +803,6 @@ void LocationPollThread(CORO_PARAM, const void *param) {
} MYTHREAD;
CORO_BEGIN_CONTEXT;
- // TODO: Requires endian fix
uint32 *il;
int i, j, k;
int numitems;
diff --git a/engines/tony/tony.cpp b/engines/tony/tony.cpp
index e53177513a..7f7930c5d7 100644
--- a/engines/tony/tony.cpp
+++ b/engines/tony/tony.cpp
@@ -573,6 +573,7 @@ void TonyEngine::close(void) {
_theBoxes.close();
_theEngine.close();
_window.close();
+ FreeMpc();
delete[] _curThumbnail;
}