1 /* ResidualVM - A 3D game interpreter
2 *
3 * ResidualVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "common/endian.h"
24 #include "common/savefile.h"
25 #include "common/system.h"
26 #include "common/config-manager.h"
27
28 #include "graphics/pixelbuffer.h"
29 #include "graphics/renderer.h"
30 #include "graphics/colormasks.h"
31
32 #include "math/matrix3.h"
33
34 #include "engines/grim/debug.h"
35 #include "engines/grim/lua_v1.h"
36 #include "engines/grim/registry.h"
37 #include "engines/grim/grim.h"
38 #include "engines/grim/savegame.h"
39 #include "engines/grim/resource.h"
40 #include "engines/grim/bitmap.h"
41 #include "engines/grim/font.h"
42 #include "engines/grim/gfx_base.h"
43 #include "engines/grim/localize.h"
44
45 #include "engines/grim/lua/lauxlib.h"
46 #include "engines/grim/lua/luadebug.h"
47
48 namespace Grim {
49
clamp_color(int c)50 byte clamp_color(int c) {
51 if (c < 0)
52 return 0;
53 else if (c > 255)
54 return 255;
55 else
56 return c;
57 }
58
59 int luaA_passresults();
60
new_dofile()61 void Lua_V1::new_dofile() {
62 const char *fname_str = luaL_check_string(1);
63 if (dofile(fname_str) == 0)
64 if (luaA_passresults() == 0)
65 lua_pushuserdata(0);
66 }
67
68 // Debugging message functions
69
PrintDebug()70 void Lua_V1::PrintDebug() {
71 if (Debug::isChannelEnabled(Debug::Scripts | Debug::Info)) {
72 Common::String msg("Debug: ");
73 lua_Object strObj = lua_getparam(1);
74 if (lua_isnil(strObj))
75 msg += "(nil)";
76 if (!lua_isstring(strObj))
77 return;
78 msg += Common::String(lua_getstring(strObj));
79 debugN("%s", msg.c_str());
80 }
81 }
82
PrintError()83 void Lua_V1::PrintError() {
84 if (Debug::isChannelEnabled(Debug::Scripts | Debug::Error)) {
85 Common::String msg("Error: ");
86 lua_Object strObj = lua_getparam(1);
87 if (lua_isnil(strObj))
88 msg += "(nil)";
89 if (!lua_isstring(strObj))
90 return;
91 msg += Common::String(lua_getstring(strObj));
92 debugN("%s", msg.c_str());
93 }
94 }
95
PrintWarning()96 void Lua_V1::PrintWarning() {
97 if (Debug::isChannelEnabled(Debug::Scripts | Debug::Warning)) {
98 Common::String msg("Warning: ");
99 lua_Object strObj = lua_getparam(1);
100 if (lua_isnil(strObj))
101 msg += "(nil)";
102 if (!lua_isstring(strObj))
103 return;
104 msg += Common::String(lua_getstring(strObj));
105 debugN("%s", msg.c_str());
106 }
107 }
108
FunctionName()109 void Lua_V1::FunctionName() {
110 const char *name;
111 char buf[256];
112 const char *filename = nullptr;
113 int32 line;
114 lua_Object param1 = lua_getparam(1);
115
116 if (!lua_isfunction(param1)) {
117 sprintf(buf, "function InvalidArgsToFunctionName");
118 lua_pushstring(buf);
119 return;
120 }
121
122 lua_funcinfo(param1, &filename, &line);
123 switch (*lua_getobjname(param1, &name)) {
124 case 'g':
125 sprintf(buf, "function %.100s", name);
126 break;
127 case 't':
128 sprintf(buf, "`%.100s' tag method", name);
129 break;
130 default:
131 {
132 if (line == 0)
133 sprintf(buf, "main of %.100s", filename);
134 else if (line < 0)
135 sprintf(buf, "%.100s", filename);
136 else {
137 sprintf(buf, "function (%.100s:%d)", filename, (int)line);
138 filename = nullptr;
139 }
140 }
141 }
142 int curr_line = lua_currentline(param1);
143 if (curr_line > 0)
144 sprintf(buf + strlen(buf), " at line %d", curr_line);
145 if (filename)
146 sprintf(buf + strlen(buf), " [in file %.100s]", filename);
147 lua_pushstring(buf);
148 }
149
CheckForFile()150 void Lua_V1::CheckForFile() {
151 lua_Object strObj = lua_getparam(1);
152
153 if (!lua_isstring(strObj))
154 return;
155
156 const char *filename = lua_getstring(strObj);
157 pushbool(SearchMan.hasFile(filename));
158 }
159
MakeColor()160 void Lua_V1::MakeColor() {
161 lua_Object rObj = lua_getparam(1);
162 lua_Object gObj = lua_getparam(2);
163 lua_Object bObj = lua_getparam(3);
164 int r, g, b;
165
166 if (!lua_isnumber(rObj))
167 r = 0;
168 else
169 r = clamp_color((int)lua_getnumber(rObj));
170
171 if (!lua_isnumber(gObj))
172 g = 0;
173 else
174 g = clamp_color((int)lua_getnumber(gObj));
175
176 if (!lua_isnumber(bObj))
177 b = 0;
178 else
179 b = clamp_color((int)lua_getnumber(bObj));
180
181 Color c(r, g, b);
182 int32 cTag = c.toEncodedValue();
183 if (g_grim->getGameType() == GType_MONKEY4)
184 cTag |= (0xFF << 24);
185 lua_pushusertag(cTag, MKTAG('C','O','L','R'));
186 }
187
GetColorComponents()188 void Lua_V1::GetColorComponents() {
189 lua_Object colorObj = lua_getparam(1);
190 Color c(getcolor(colorObj));
191 lua_pushnumber(c.getRed());
192 lua_pushnumber(c.getGreen());
193 lua_pushnumber(c.getBlue());
194 }
195
ReadRegistryValue()196 void Lua_V1::ReadRegistryValue() {
197 lua_Object keyObj = lua_getparam(1);
198
199 if (!lua_isstring(keyObj)) {
200 lua_pushnil();
201 return;
202 }
203 const char *key = lua_getstring(keyObj);
204
205 Registry::ValueType type = g_registry->getValueType(key);
206 switch (type) {
207 case Registry::String:
208 lua_pushstring(g_registry->getString(key).c_str());
209 break;
210 case Registry::Integer:
211 lua_pushnumber(g_registry->getInt(key));
212 break;
213 case Registry::Boolean:
214 pushbool(g_registry->getBool(key));
215 break;
216 }
217 }
218
WriteRegistryValue()219 void Lua_V1::WriteRegistryValue() {
220 lua_Object keyObj = lua_getparam(1);
221 lua_Object valObj = lua_getparam(2);
222
223 if (!lua_isstring(keyObj))
224 return;
225
226 const char *key = lua_getstring(keyObj);
227 if (strcmp(key, "GrimMannyState") == 0) //This isn't used. it's probably a left over from testing phase.
228 return;
229
230 // Check isnumber first, because isstring returns true for numbers
231 if (lua_isnumber(valObj)) {
232 int val = (int)lua_getnumber(valObj);
233 g_registry->setInt(key, val);
234 } else if (lua_isstring(valObj)) {
235 const char *val = lua_getstring(valObj);
236 g_registry->setString(key, val);
237 }
238 }
239
GetAngleBetweenVectors()240 void Lua_V1::GetAngleBetweenVectors() {
241 lua_Object vec1Obj = lua_getparam(1);
242 lua_Object vec2Obj = lua_getparam(2);
243
244 if (!lua_istable(vec1Obj) || !lua_istable(vec2Obj)) {
245 lua_pushnil();
246 return;
247 }
248
249 lua_pushobject(vec1Obj);
250 lua_pushstring("x");
251 lua_Object table = lua_gettable();
252 float x1 = lua_getnumber(table);
253 lua_pushobject(vec1Obj);
254 lua_pushstring("y");
255 table = lua_gettable();
256 float y1 = lua_getnumber(table);
257 lua_pushobject(vec1Obj);
258 lua_pushstring("z");
259 table = lua_gettable();
260 float z1 = lua_getnumber(table);
261 lua_pushobject(vec2Obj);
262 lua_pushstring("x");
263 table = lua_gettable();
264 float x2 = lua_getnumber(table);
265 lua_pushobject(vec2Obj);
266 lua_pushstring("y");
267 table = lua_gettable();
268 float y2 = lua_getnumber(table);
269 lua_pushobject(vec2Obj);
270 lua_pushstring("z");
271 table = lua_gettable();
272 float z2 = lua_getnumber(table);
273
274 Math::Vector3d vec1(x1, y1, z1);
275 Math::Vector3d vec2(x2, y2, z2);
276 vec1.normalize();
277 vec2.normalize();
278
279 float dot = vec1.dotProduct(vec2);
280 float angle = 90.0f - (180.0f * asin(dot)) / LOCAL_PI;
281 if (angle < 0)
282 angle = -angle;
283 lua_pushnumber(angle);
284 }
285
Is3DHardwareEnabled()286 void Lua_V1::Is3DHardwareEnabled() {
287 pushbool(g_driver->isHardwareAccelerated());
288 }
289
SetHardwareState()290 void Lua_V1::SetHardwareState() {
291 // changing only in config setup (software/hardware rendering)
292 bool accel = getbool(1);
293
294 Graphics::RendererType renderer = accel ? Graphics::kRendererTypeOpenGL : Graphics::kRendererTypeTinyGL;
295 renderer = Graphics::getBestMatchingAvailableRendererType(renderer);
296 ConfMan.set("renderer", Graphics::getRendererTypeCode(renderer));
297
298 g_grim->changeHardwareState();
299 }
300
SetVideoDevices()301 void Lua_V1::SetVideoDevices() {
302 /*int devId = (int)*/lua_getnumber(lua_getparam(1));
303 /*int modeId = (int)*/lua_getnumber(lua_getparam(2));
304 // ignore setting video devices
305 }
306
GetVideoDevices()307 void Lua_V1::GetVideoDevices() {
308 lua_pushnumber(0.0);
309 lua_pushnumber(-1.0);
310 }
311
EnumerateVideoDevices()312 void Lua_V1::EnumerateVideoDevices() {
313 lua_Object result = lua_createtable();
314 lua_pushobject(result);
315 lua_pushnumber(0.0); // id of device
316 lua_pushstring(g_driver->getVideoDeviceName()); // name of device
317 lua_settable();
318 lua_pushobject(result);
319 }
320
Enumerate3DDevices()321 void Lua_V1::Enumerate3DDevices() {
322 lua_Object result = lua_createtable();
323 lua_Object numObj = lua_getparam(1);
324 if (!lua_isnumber(numObj))
325 return;
326 /* int num = (int)lua_getnumber(numObj);*/
327 lua_pushobject(result);
328 lua_pushnumber(-1.0);
329 if (g_driver->isHardwareAccelerated()) {
330 lua_pushstring("OpenGL"); // type of 3d renderer
331 } else {
332 lua_pushstring("/engn003/Software"); // type of 3d renderer
333 }
334 lua_settable();
335 lua_pushobject(result);
336 }
337
338 /* RotateVector takes a vector and rotates it around
339 * the point (0,0,0) by the requested number of degrees.
340 * This function is used to calculate the locations for
341 * getting on and off of the Bone Wagon and for going up
342 * and down the slide with the chain at the end of the world.
343 */
RotateVector()344 void Lua_V1::RotateVector() {
345 lua_Object vecObj = lua_getparam(1);
346 lua_Object rotObj = lua_getparam(2);
347
348 if (!lua_istable(vecObj) || !lua_istable(rotObj)) {
349 lua_pushnil();
350 return;
351 }
352
353 lua_pushobject(vecObj);
354 lua_pushstring("x");
355 float x = lua_getnumber(lua_gettable());
356 lua_pushobject(vecObj);
357 lua_pushstring("y");
358 float y = lua_getnumber(lua_gettable());
359 lua_pushobject(vecObj);
360 lua_pushstring("z");
361 float z = lua_getnumber(lua_gettable());
362 Math::Vector3d vec(x, y, z);
363
364 lua_pushobject(rotObj);
365 lua_pushstring("x");
366 Math::Angle pitch = lua_getnumber(lua_gettable());
367 lua_pushobject(rotObj);
368 lua_pushstring("y");
369 Math::Angle yaw = lua_getnumber(lua_gettable());
370 lua_pushobject(rotObj);
371 lua_pushstring("z");
372 Math::Angle roll = lua_getnumber(lua_gettable());
373
374 Math::Matrix3 mat;
375 mat.buildFromEuler(yaw, pitch, roll, Math::EO_ZXY);
376 mat.transformVector(&vec);
377
378 lua_Object resObj = lua_createtable();
379 lua_pushobject(resObj);
380 lua_pushstring("x");
381 lua_pushnumber(vec.x());
382 lua_settable();
383 lua_pushobject(resObj);
384 lua_pushstring("y");
385 lua_pushnumber(vec.y());
386 lua_settable();
387 lua_pushobject(resObj);
388 lua_pushstring("z");
389 lua_pushnumber(vec.z());
390 lua_settable();
391
392 lua_pushobject(resObj);
393 }
394
FileFindDispose()395 void Lua_V1::FileFindDispose() {
396 g_grim->_listFiles.clear();
397 g_grim->_listFilesIter = nullptr;
398 }
399
FileFindNext()400 void Lua_V1::FileFindNext() {
401 if (g_grim->_listFilesIter == g_grim->_listFiles.end()) {
402 lua_pushnil();
403 Lua_V1::FileFindDispose();
404 } else {
405 lua_pushstring(g_grim->_listFilesIter->c_str());
406 g_grim->_listFilesIter++;
407 }
408 }
409
FileFindFirst()410 void Lua_V1::FileFindFirst() {
411 lua_Object extObj = lua_getparam(1);
412 if (!lua_isstring(extObj)) {
413 lua_pushnil();
414 return;
415 }
416
417 Lua_V1::FileFindDispose();
418
419 const char *extension = lua_getstring(extObj);
420 Common::String searchString = extension;
421 if (searchString == "*.gsv") {
422 searchString = "grim##.gsv";
423 }
424 Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
425 g_grim->_listFiles = saveFileMan->listSavefiles(searchString);
426 Common::sort(g_grim->_listFiles.begin(), g_grim->_listFiles.end());
427 g_grim->_listFilesIter = g_grim->_listFiles.begin();
428
429 if (g_grim->_listFilesIter == g_grim->_listFiles.end())
430 lua_pushnil();
431 else
432 Lua_V1::FileFindNext();
433 }
434
PerSecond()435 void Lua_V1::PerSecond() {
436 lua_Object rateObj = lua_getparam(1);
437
438 if (!lua_isnumber(rateObj)) {
439 lua_pushnil();
440 return;
441 }
442 float rate = lua_getnumber(rateObj);
443 lua_pushnumber(g_grim->getPerSecond(rate));
444 }
445
EnableControl()446 void Lua_V1::EnableControl() {
447 lua_Object numObj = lua_getparam(1);
448
449 if (!lua_isnumber(numObj)) {
450 lua_pushnil();
451 return;
452 }
453 int num = (int)lua_getnumber(numObj);
454 if (num < 0 || num >= KEYCODE_EXTRA_LAST)
455 error("control identifier out of range");
456
457 g_grim->enableControl(num);
458 }
459
DisableControl()460 void Lua_V1::DisableControl() {
461 lua_Object numObj = lua_getparam(1);
462
463 if (!lua_isnumber(numObj)) {
464 lua_pushnil();
465 return;
466 }
467 int num = (int)lua_getnumber(numObj);
468 if (num < 0 || num >= KEYCODE_EXTRA_LAST)
469 error("control identifier out of range");
470
471 g_grim->disableControl(num);
472 }
473
GetControlState()474 void Lua_V1::GetControlState() {
475 lua_Object numObj = lua_getparam(1);
476
477 if (!lua_isnumber(numObj))
478 return;
479
480 int num = (int)lua_getnumber(numObj);
481 if (num < 0 || num >= KEYCODE_EXTRA_LAST)
482 error("control identifier out of range");
483 if (num >= KEYCODE_AXIS_JOY1_X && num <= KEYCODE_AXIS_MOUSE_Z)
484 lua_pushnumber(g_grim->getControlAxis(num));
485 else {
486 pushbool(g_grim->getControlState(num)); // key down, originaly it push number if key down
487 //pushnil or number, what is is ?
488 }
489 }
490
Exit()491 void Lua_V1::Exit() {
492 g_grim->quitGame();
493 }
494
SetSpeechMode()495 void Lua_V1::SetSpeechMode() {
496 GrimEngine::SpeechMode mode = (GrimEngine::SpeechMode)((int)lua_getnumber(lua_getparam(1)));
497 if (mode >= 1 && mode <= 3)
498 g_grim->setSpeechMode(mode);
499 }
500
GetSpeechMode()501 void Lua_V1::GetSpeechMode() {
502 lua_pushnumber(g_grim->getSpeechMode());
503 }
504
GetDiskFreeSpace()505 void Lua_V1::GetDiskFreeSpace() {
506 //the ps2 version of emi wants more than 600 KB
507 //grim: amount of free space in MB, used for creating saves
508 lua_pushnumber(700);
509 }
510
GetCurrentScript()511 void Lua_V1::GetCurrentScript() {
512 current_script();
513 }
514
GetSaveGameImage()515 void Lua_V1::GetSaveGameImage() {
516 int width = 250, height = 188;
517 Bitmap *screenshot;
518 int dataSize;
519
520 lua_Object param = lua_getparam(1);
521 if (!lua_isstring(param)) {
522 lua_pushnil();
523 return;
524 }
525 const char *filename = lua_getstring(param);
526 SaveGame *savedState = SaveGame::openForLoading(filename);
527 if (!savedState || !savedState->isCompatible()) {
528 delete savedState;
529 lua_pushnil();
530 return;
531 }
532 dataSize = savedState->beginSection('SIMG');
533 uint16 *data = new uint16[dataSize / 2];
534 for (int l = 0; l < dataSize / 2; l++) {
535 data[l] = savedState->readLEUint16();
536 }
537 Graphics::PixelBuffer buf(Graphics::createPixelFormat<565>(), (byte *)data);
538 screenshot = new Bitmap(buf, width, height, "screenshot");
539 delete[] data;
540 if (screenshot) {
541 lua_pushusertag(screenshot->getId(), MKTAG('V','B','U','F'));
542 } else {
543 lua_pushnil();
544 warning("Could not restore screenshot from file");
545 delete savedState;
546 return;
547 }
548 savedState->endSection();
549 delete savedState;
550 }
551
SubmitSaveGameData()552 void Lua_V1::SubmitSaveGameData() {
553 lua_Object table, table2;
554 SaveGame *savedState;
555 const char *str;
556 table = lua_getparam(1);
557
558 savedState = g_grim->savedState();
559 if (!savedState)
560 error("Cannot obtain saved game");
561 savedState->beginSection('SUBS');
562 int count = 0;
563 Common::String localized;
564 for (;;) {
565 lua_pushobject(table);
566 lua_pushnumber(count);
567 count++;
568 table2 = lua_gettable();
569 if (lua_isnil(table2))
570 break;
571 str = lua_getstring(table2);
572 if (g_grim->getGameType() == GType_MONKEY4 &&
573 g_grim->getGamePlatform() == Common::kPlatformPS2) {
574 if (count == 1) {
575 localized = g_localizer->localize(str);
576 }
577 }
578 int32 len = strlen(str) + 1;
579 savedState->writeLESint32(len);
580 savedState->write(str, len);
581 }
582 savedState->endSection();
583
584 //give ps2 saves a human-readable name
585 if (g_grim->getGameType() == GType_MONKEY4 &&
586 g_grim->getGamePlatform() == Common::kPlatformPS2) {
587 savedState->beginSection('PS2S');
588 savedState->writeLESint32(localized.size() + 1);
589 savedState->write(localized.c_str(), localized.size() + 1);
590 savedState->endSection();
591 }
592 }
593
GetSaveGameData()594 void Lua_V1::GetSaveGameData() {
595 lua_Object param = lua_getparam(1);
596 if (!lua_isstring(param))
597 return;
598 Common::String filename(lua_getstring(param));
599 if (g_grim->getGameType() == GType_MONKEY4 &&
600 g_grim->getGamePlatform() == Common::kPlatformPS2) {
601 filename += ".ps2";
602 }
603 SaveGame *savedState = SaveGame::openForLoading(filename);
604 lua_Object result = lua_createtable();
605
606 if (!savedState || !savedState->isCompatible()) {
607 lua_pushobject(result);
608 lua_pushnumber(2);
609 lua_pushstring("mo.set"); // Just a placeholder to not make it throw a lua error
610 lua_settable();
611 lua_pushobject(result);
612
613 if (!savedState) {
614 warning("Savegame %s is invalid", filename.c_str());
615 } else {
616 warning("Savegame %s is incompatible with this ResidualVM build. Save version: %d.%d; current version: %d.%d",
617 filename.c_str(), savedState->saveMajorVersion(), savedState->saveMinorVersion(),
618 SaveGame::SAVEGAME_MAJOR_VERSION, SaveGame::SAVEGAME_MINOR_VERSION);
619 }
620 delete savedState;
621 return;
622 }
623 int32 dataSize = savedState->beginSection('SUBS');
624
625 char str[200];
626 int32 strSize;
627 int count = 0;
628
629 for (;;) {
630 if (dataSize <= 0)
631 break;
632 strSize = savedState->readLESint32();
633 savedState->read(str, strSize);
634 lua_pushobject(result);
635 lua_pushnumber(count);
636 lua_pushstring(str);
637 lua_settable();
638 dataSize -= strSize;
639 dataSize -= 4;
640 count++;
641 }
642 lua_pushobject(result);
643
644 savedState->endSection();
645 delete savedState;
646 }
647
Load()648 void Lua_V1::Load() {
649 lua_Object fileNameObj = lua_getparam(1);
650 if (lua_isnil(fileNameObj)) {
651 g_grim->loadGame("");
652 } else if (lua_isstring(fileNameObj)) {
653 Common::String fileName(lua_getstring(fileNameObj));
654 if (g_grim->getGameType() == GType_MONKEY4 &&
655 g_grim->getGamePlatform() == Common::kPlatformPS2) {
656 fileName += ".ps2";
657 }
658 g_grim->loadGame(fileName);
659 } else {
660 warning("Load() fileName is wrong");
661 return;
662 }
663 }
664
Save()665 void Lua_V1::Save() {
666 lua_Object fileNameObj = lua_getparam(1);
667 if (lua_isnil(fileNameObj)) {
668 g_grim->saveGame("");
669 } else if (lua_isstring(fileNameObj)) {
670 Common::String fileName(lua_getstring(fileNameObj));
671 if (g_grim->getGameType() == GType_MONKEY4 &&
672 g_grim->getGamePlatform() == Common::kPlatformPS2) {
673 fileName += ".ps2";
674 }
675 g_grim->saveGame(fileName);
676 } else {
677 warning("Save() fileName is wrong");
678 return;
679 }
680 }
681
Remove()682 void Lua_V1::Remove() {
683 if (g_system->getSavefileManager()->removeSavefile(luaL_check_string(1)))
684 lua_pushuserdata(0);
685 else {
686 lua_pushnil();
687 lua_pushstring(g_system->getSavefileManager()->getErrorDesc().c_str());
688 }
689 }
690
LockFont()691 void Lua_V1::LockFont() {
692 lua_Object param1 = lua_getparam(1);
693 if (lua_isstring(param1)) {
694 const char *fontName = lua_getstring(param1);
695 Font *result = g_resourceloader->loadFont(fontName);
696 if (result) {
697 lua_pushusertag(result->getId(), MKTAG('F','O','N','T'));
698 return;
699 }
700 }
701
702 lua_pushnil();
703 }
704
EnableDebugKeys()705 void Lua_V1::EnableDebugKeys() {
706 }
707
LightMgrSetChange()708 void Lua_V1::LightMgrSetChange() {
709 // that seems only used when some control panel is opened
710 }
711
LightMgrStartup()712 void Lua_V1::LightMgrStartup() {
713 // we will not implement this opcode
714 }
715
JustLoaded()716 void Lua_V1::JustLoaded() {
717 Debug::error("OPCODE USAGE VERIFICATION: JustLoaded");
718 }
719
SetEmergencyFont()720 void Lua_V1::SetEmergencyFont() {
721 Debug::error("OPCODE USAGE VERIFICATION: SetEmergencyFont");
722 }
723
724
725 // Stub function for builtin functions not yet implemented
stubWarning(const char * funcName)726 static void stubWarning(const char *funcName) {
727 warning("Stub function: %s", funcName);
728 }
729
730 #define STUB_FUNC(name) void name() { stubWarning(#name); }
731
732 STUB_FUNC(Lua_V1::SetActorInvClipNode)
733 STUB_FUNC(Lua_V1::NukeResources)
734 STUB_FUNC(Lua_V1::ResetTextures)
735 STUB_FUNC(Lua_V1::AttachToResources)
736 STUB_FUNC(Lua_V1::DetachFromResources)
737 STUB_FUNC(Lua_V1::SetActorClipPlane)
738 STUB_FUNC(Lua_V1::SetActorClipActive)
739 STUB_FUNC(Lua_V1::FlushControls)
740 STUB_FUNC(Lua_V1::GetCameraLookVector)
741 STUB_FUNC(Lua_V1::SetCameraRoll)
742 STUB_FUNC(Lua_V1::SetCameraInterest)
743 STUB_FUNC(Lua_V1::GetCameraPosition)
744 STUB_FUNC(Lua_V1::SpewStartup)
745 STUB_FUNC(Lua_V1::WorldToScreen)
746 STUB_FUNC(Lua_V1::SetActorRoll)
747 STUB_FUNC(Lua_V1::SetActorFrustrumCull)
748 STUB_FUNC(Lua_V1::DriveActorTo)
749 STUB_FUNC(Lua_V1::GetTranslationMode)
750 STUB_FUNC(Lua_V1::SetTranslationMode)
751 STUB_FUNC(Lua_V1::WalkActorToAvoiding)
752 STUB_FUNC(Lua_V1::GetActorChores)
753 STUB_FUNC(Lua_V1::SetCameraPosition)
754 STUB_FUNC(Lua_V1::GetCameraFOV)
755 STUB_FUNC(Lua_V1::SetCameraFOV)
756 STUB_FUNC(Lua_V1::GetCameraRoll)
757 STUB_FUNC(Lua_V1::GetMemoryUsage)
758 STUB_FUNC(Lua_V1::GetFontDimensions)
759 STUB_FUNC(Lua_V1::PurgeText)
760
761 struct luaL_reg grimMainOpcodes[] = {
762 { "EngineDisplay", LUA_OPCODE(Lua_V1, EngineDisplay) },
763 { "CheckForFile", LUA_OPCODE(Lua_V1, CheckForFile) },
764 { "Load", LUA_OPCODE(Lua_V1, Load) },
765 { "Save", LUA_OPCODE(Lua_V1, Save) },
766 { "remove", LUA_OPCODE(Lua_V1, Remove) },
767 { "SetActorColormap", LUA_OPCODE(Lua_V1, SetActorColormap) },
768 { "GetActorCostume", LUA_OPCODE(Lua_V1, GetActorCostume) },
769 { "SetActorCostume", LUA_OPCODE(Lua_V1, SetActorCostume) },
770 { "SetActorScale", LUA_OPCODE(Lua_V1, SetActorScale) },
771 { "GetActorTimeScale", LUA_OPCODE(Lua_V1, GetActorTimeScale) },
772 { "SetActorTimeScale", LUA_OPCODE(Lua_V1, SetActorTimeScale) },
773 { "GetActorNodeLocation", LUA_OPCODE(Lua_V1, GetActorNodeLocation) },
774 { "SetActorWalkChore", LUA_OPCODE(Lua_V1, SetActorWalkChore) },
775 { "SetActorTurnChores", LUA_OPCODE(Lua_V1, SetActorTurnChores) },
776 { "SetActorRestChore", LUA_OPCODE(Lua_V1, SetActorRestChore) },
777 { "SetActorMumblechore", LUA_OPCODE(Lua_V1, SetActorMumblechore) },
778 { "SetActorTalkChore", LUA_OPCODE(Lua_V1, SetActorTalkChore) },
779 { "SetActorWalkRate", LUA_OPCODE(Lua_V1, SetActorWalkRate) },
780 { "GetActorWalkRate", LUA_OPCODE(Lua_V1, GetActorWalkRate) },
781 { "SetActorTurnRate", LUA_OPCODE(Lua_V1, SetActorTurnRate) },
782 { "SetSelectedActor", LUA_OPCODE(Lua_V1, SetSelectedActor) },
783 { "LoadActor", LUA_OPCODE(Lua_V1, LoadActor) },
784 { "GetActorPos", LUA_OPCODE(Lua_V1, GetActorPos) },
785 { "GetActorRect", LUA_OPCODE(Lua_V1, GetActorRect) },
786 { "GetActorPuckVector", LUA_OPCODE(Lua_V1, GetActorPuckVector) },
787 { "GetActorYawToPoint", LUA_OPCODE(Lua_V1, GetActorYawToPoint) },
788 { "SetActorReflection", LUA_OPCODE(Lua_V1, SetActorReflection) },
789 { "PutActorAtInterest", LUA_OPCODE(Lua_V1, PutActorAtInterest) },
790 { "PutActorAt", LUA_OPCODE(Lua_V1, PutActorAt) },
791 { "PutActorInSet", LUA_OPCODE(Lua_V1, PutActorInSet) },
792 { "WalkActorVector", LUA_OPCODE(Lua_V1, WalkActorVector) },
793 { "WalkActorForward", LUA_OPCODE(Lua_V1, WalkActorForward) },
794 { "DriveActorTo", LUA_OPCODE(Lua_V1, DriveActorTo) },
795 { "WalkActorTo", LUA_OPCODE(Lua_V1, WalkActorTo) },
796 { "WalkActorToAvoiding", LUA_OPCODE(Lua_V1, WalkActorToAvoiding) },
797 { "ActorLookAt", LUA_OPCODE(Lua_V1, ActorLookAt) },
798 { "SetActorLookRate", LUA_OPCODE(Lua_V1, SetActorLookRate) },
799 { "GetActorLookRate", LUA_OPCODE(Lua_V1, GetActorLookRate) },
800 { "GetVisibleThings", LUA_OPCODE(Lua_V1, GetVisibleThings) },
801 { "GetCameraActor", LUA_OPCODE(Lua_V1, GetCameraActor) },
802 { "SetActorHead", LUA_OPCODE(Lua_V1, SetActorHead) },
803 { "SetActorVisibility", LUA_OPCODE(Lua_V1, SetActorVisibility) },
804 { "SetActorFollowBoxes", LUA_OPCODE(Lua_V1, SetActorFollowBoxes) },
805 { "ShutUpActor", LUA_OPCODE(Lua_V1, ShutUpActor) },
806 { "SetActorFrustrumCull", LUA_OPCODE(Lua_V1, SetActorFrustrumCull) },
807 { "IsActorInSector", LUA_OPCODE(Lua_V1, IsActorInSector) },
808 { "GetActorSector", LUA_OPCODE(Lua_V1, GetActorSector) },
809 { "IsPointInSector", LUA_OPCODE(Lua_V1, IsPointInSector) },
810 { "GetPointSector", LUA_OPCODE(Lua_V1, GetPointSector) },
811 { "TurnActor", LUA_OPCODE(Lua_V1, TurnActor) },
812 { "GetActorRot", LUA_OPCODE(Lua_V1, GetActorRot) },
813 { "SetActorRot", LUA_OPCODE(Lua_V1, SetActorRot) },
814 { "SetActorPitch", LUA_OPCODE(Lua_V1, SetActorPitch) },
815 { "SetActorRoll", LUA_OPCODE(Lua_V1, SetActorRoll) },
816 { "IsActorTurning", LUA_OPCODE(Lua_V1, IsActorTurning) },
817 { "PlayActorChore", LUA_OPCODE(Lua_V1, PlayActorChore) },
818 { "PlayActorChoreLooping", LUA_OPCODE(Lua_V1, PlayActorChoreLooping) },
819 { "StopActorChore", LUA_OPCODE(Lua_V1, StopActorChore) },
820 { "CompleteActorChore", LUA_OPCODE(Lua_V1, CompleteActorChore) },
821 { "IsActorMoving", LUA_OPCODE(Lua_V1, IsActorMoving) },
822 { "IsActorChoring", LUA_OPCODE(Lua_V1, IsActorChoring) },
823 { "IsActorResting", LUA_OPCODE(Lua_V1, IsActorResting) },
824 { "SetActorChoreLooping", LUA_OPCODE(Lua_V1, SetActorChoreLooping) },
825 { "GetActorChores", LUA_OPCODE(Lua_V1, GetActorChores) },
826 { "GetActorCostumeDepth", LUA_OPCODE(Lua_V1, GetActorCostumeDepth) },
827 { "WorldToScreen", LUA_OPCODE(Lua_V1, WorldToScreen) },
828 { "exit", LUA_OPCODE(Lua_V1, Exit) },
829 { "FunctionName", LUA_OPCODE(Lua_V1, FunctionName) },
830 { "EnableDebugKeys", LUA_OPCODE(Lua_V1, EnableDebugKeys) },
831 { "LockFont", LUA_OPCODE(Lua_V1, LockFont) },
832 { "EnableControl", LUA_OPCODE(Lua_V1, EnableControl) },
833 { "DisableControl", LUA_OPCODE(Lua_V1, DisableControl) },
834 { "GetControlState", LUA_OPCODE(Lua_V1, GetControlState) },
835 { "PrintError", LUA_OPCODE(Lua_V1, PrintError) },
836 { "PrintWarning", LUA_OPCODE(Lua_V1, PrintWarning) },
837 { "PrintDebug", LUA_OPCODE(Lua_V1, PrintDebug) },
838 { "MakeCurrentSet", LUA_OPCODE(Lua_V1, MakeCurrentSet) },
839 { "LockSet", LUA_OPCODE(Lua_V1, LockSet) },
840 { "UnLockSet", LUA_OPCODE(Lua_V1, UnLockSet) },
841 { "MakeCurrentSetup", LUA_OPCODE(Lua_V1, MakeCurrentSetup) },
842 { "GetCurrentSetup", LUA_OPCODE(Lua_V1, GetCurrentSetup) },
843 { "NextSetup", LUA_OPCODE(Lua_V1, NextSetup) },
844 { "PreviousSetup", LUA_OPCODE(Lua_V1, PreviousSetup) },
845 { "StartFullscreenMovie", LUA_OPCODE(Lua_V1, StartFullscreenMovie) },
846 { "IsFullscreenMoviePlaying", LUA_OPCODE(Lua_V1, IsFullscreenMoviePlaying) },
847 { "StartMovie", LUA_OPCODE(Lua_V1, StartMovie) },
848 { "StopMovie", LUA_OPCODE(Lua_V1, StopMovie) },
849 { "PauseMovie", LUA_OPCODE(Lua_V1, PauseMovie) },
850 { "IsMoviePlaying", LUA_OPCODE(Lua_V1, IsMoviePlaying) },
851 { "PlaySound", LUA_OPCODE(Lua_V1, PlaySound) },
852 { "PlaySoundAt", LUA_OPCODE(Lua_V1, PlaySoundAt) },
853 { "IsSoundPlaying", LUA_OPCODE(Lua_V1, IsSoundPlaying) },
854 { "SetSoundPosition", LUA_OPCODE(Lua_V1, SetSoundPosition) },
855 { "FileFindFirst", LUA_OPCODE(Lua_V1, FileFindFirst) },
856 { "FileFindNext", LUA_OPCODE(Lua_V1, FileFindNext) },
857 { "FileFindDispose", LUA_OPCODE(Lua_V1, FileFindDispose) },
858 { "InputDialog", LUA_OPCODE(Lua_V1, InputDialog) },
859 { "WriteRegistryValue", LUA_OPCODE(Lua_V1, WriteRegistryValue) },
860 { "ReadRegistryValue", LUA_OPCODE(Lua_V1, ReadRegistryValue) },
861 { "GetSectorOppositeEdge", LUA_OPCODE(Lua_V1, GetSectorOppositeEdge) },
862 { "MakeSectorActive", LUA_OPCODE(Lua_V1, MakeSectorActive) },
863 { "PreRender", LUA_OPCODE(Lua_V1, PreRender) },
864 { "SpewStartup", LUA_OPCODE(Lua_V1, SpewStartup) },
865 { "GetCurrentScript", LUA_OPCODE(Lua_V1, GetCurrentScript) },
866 { "PrintActorCostumes", LUA_OPCODE(Lua_V1, PrintActorCostumes) },
867 { "PushActorCostume", LUA_OPCODE(Lua_V1, PushActorCostume) },
868 { "PopActorCostume", LUA_OPCODE(Lua_V1, PopActorCostume) },
869 { "LoadCostume", LUA_OPCODE(Lua_V1, LoadCostume) },
870 { "RotateVector", LUA_OPCODE(Lua_V1, RotateVector) },
871 { "GetCameraPosition", LUA_OPCODE(Lua_V1, GetCameraPosition) },
872 { "SetCameraPosition", LUA_OPCODE(Lua_V1, SetCameraPosition) },
873 { "SetCameraInterest", LUA_OPCODE(Lua_V1, SetCameraInterest) },
874 { "GetCameraFOV", LUA_OPCODE(Lua_V1, GetCameraFOV) },
875 { "SetCameraFOV", LUA_OPCODE(Lua_V1, SetCameraFOV) },
876 { "GetCameraRoll", LUA_OPCODE(Lua_V1, GetCameraRoll) },
877 { "SetCameraRoll", LUA_OPCODE(Lua_V1, SetCameraRoll) },
878 { "GetCameraLookVector", LUA_OPCODE(Lua_V1, GetCameraLookVector) },
879 { "PointActorAt", LUA_OPCODE(Lua_V1, PointActorAt) },
880 { "TurnActorTo", LUA_OPCODE(Lua_V1, TurnActorTo) },
881 { "PerSecond", LUA_OPCODE(Lua_V1, PerSecond) },
882 { "GetAngleBetweenVectors", LUA_OPCODE(Lua_V1, GetAngleBetweenVectors) },
883 { "GetAngleBetweenActors", LUA_OPCODE(Lua_V1, GetAngleBetweenActors) },
884 { "SetAmbientLight", LUA_OPCODE(Lua_V1, SetAmbientLight) },
885 { "TurnLightOn", LUA_OPCODE(Lua_V1, TurnLightOn) },
886 { "SetLightPosition", LUA_OPCODE(Lua_V1, SetLightPosition) },
887 { "SetLightIntensity", LUA_OPCODE(Lua_V1, SetLightIntensity) },
888 { "LightMgrSetChange", LUA_OPCODE(Lua_V1, LightMgrSetChange) },
889 { "LightMgrStartup", LUA_OPCODE(Lua_V1, LightMgrStartup) },
890 { "ImStartSound", LUA_OPCODE(Lua_V1, ImStartSound) },
891 { "ImStopSound", LUA_OPCODE(Lua_V1, ImStopSound) },
892 { "ImStopAllSounds", LUA_OPCODE(Lua_V1, ImStopAllSounds) },
893 { "ImGetParam", LUA_OPCODE(Lua_V1, ImGetParam) },
894 { "ImSetParam", LUA_OPCODE(Lua_V1, ImSetParam) },
895 { "ImFadeParam", LUA_OPCODE(Lua_V1, ImFadeParam) },
896 { "ImGetSfxVol", LUA_OPCODE(Lua_V1, ImGetSfxVol) },
897 { "ImSetSfxVol", LUA_OPCODE(Lua_V1, ImSetSfxVol) },
898 { "ImGetVoiceVol", LUA_OPCODE(Lua_V1, ImGetVoiceVol) },
899 { "ImSetVoiceVol", LUA_OPCODE(Lua_V1, ImSetVoiceVol) },
900 { "ImGetMusicVol", LUA_OPCODE(Lua_V1, ImGetMusicVol) },
901 { "ImSetMusicVol", LUA_OPCODE(Lua_V1, ImSetMusicVol) },
902 { "ImSetState", LUA_OPCODE(Lua_V1, ImSetState) },
903 { "ImSetSequence", LUA_OPCODE(Lua_V1, ImSetSequence) },
904 { "ImPause", LUA_OPCODE(Lua_V1, ImPause) },
905 { "ImResume", LUA_OPCODE(Lua_V1, ImResume) },
906 { "ImSetVoiceEffect", LUA_OPCODE(Lua_V1, ImSetVoiceEffect) },
907 { "LoadBundle", LUA_OPCODE(Lua_V1, LoadBundle) },
908 { "SetGamma", LUA_OPCODE(Lua_V1, SetGamma) },
909 { "SetActorWalkDominate", LUA_OPCODE(Lua_V1, SetActorWalkDominate) },
910 { "SetActorConstrain", LUA_OPCODE(Lua_V1, SetActorConstrain) },
911 { "RenderModeUser", LUA_OPCODE(Lua_V1, RenderModeUser) },
912 { "ForceRefresh", LUA_OPCODE(Lua_V1, ForceRefresh) },
913 { "DimScreen", LUA_OPCODE(Lua_V1, DimScreen) },
914 { "DimRegion", LUA_OPCODE(Lua_V1, DimRegion) },
915 { "CleanBuffer", LUA_OPCODE(Lua_V1, CleanBuffer) },
916 { "Display", LUA_OPCODE(Lua_V1, Display) },
917 { "SetSpeechMode", LUA_OPCODE(Lua_V1, SetSpeechMode) },
918 { "GetSpeechMode", LUA_OPCODE(Lua_V1, GetSpeechMode) },
919 { "SetShadowColor", LUA_OPCODE(Lua_V1, SetShadowColor) },
920 { "ActivateActorShadow", LUA_OPCODE(Lua_V1, ActivateActorShadow) },
921 { "SetActorShadowPlane", LUA_OPCODE(Lua_V1, SetActorShadowPlane) },
922 { "SetActorShadowPoint", LUA_OPCODE(Lua_V1, SetActorShadowPoint) },
923 { "SetActiveShadow", LUA_OPCODE(Lua_V1, SetActiveShadow) },
924 { "KillActorShadows", LUA_OPCODE(Lua_V1, KillActorShadows) },
925 { "AddShadowPlane", LUA_OPCODE(Lua_V1, AddShadowPlane) },
926 { "SetActorShadowValid", LUA_OPCODE(Lua_V1, SetActorShadowValid) },
927 { "FreeObjectState", LUA_OPCODE(Lua_V1, FreeObjectState) },
928 { "NewObjectState", LUA_OPCODE(Lua_V1, NewObjectState) },
929 { "SetObjectType", LUA_OPCODE(Lua_V1, SetObjectType) },
930 { "SendObjectToBack", LUA_OPCODE(Lua_V1, SendObjectToBack) },
931 { "SendObjectToFront", LUA_OPCODE(Lua_V1, SendObjectToFront) },
932 { "ActorToClean", LUA_OPCODE(Lua_V1, ActorToClean) },
933 { "FlushControls", LUA_OPCODE(Lua_V1, FlushControls) },
934 { "SetActorCollisionMode", LUA_OPCODE(Lua_V1, SetActorCollisionMode) },
935 { "SetActorCollisionScale", LUA_OPCODE(Lua_V1, SetActorCollisionScale) },
936 { "SetActorClipActive", LUA_OPCODE(Lua_V1, SetActorClipActive) },
937 { "SetActorClipPlane", LUA_OPCODE(Lua_V1, SetActorClipPlane) },
938 { "FadeOutChore", LUA_OPCODE(Lua_V1, FadeOutChore) },
939 { "FadeInChore", LUA_OPCODE(Lua_V1, FadeInChore) },
940 { "IrisDown", LUA_OPCODE(Lua_V1, IrisDown) },
941 { "IrisUp", LUA_OPCODE(Lua_V1, IrisUp) },
942 { "TextFileGetLineCount", LUA_OPCODE(Lua_V1, TextFileGetLineCount) },
943 { "TextFileGetLine", LUA_OPCODE(Lua_V1, TextFileGetLine) },
944 { "ScreenShot", LUA_OPCODE(Lua_V1, ScreenShot) },
945 { "GetSaveGameImage", LUA_OPCODE(Lua_V1, GetSaveGameImage) },
946 { "GetImage", LUA_OPCODE(Lua_V1, GetImage) },
947 { "FreeImage", LUA_OPCODE(Lua_V1, FreeImage) },
948 { "BlastImage", LUA_OPCODE(Lua_V1, BlastImage) },
949 { "BlastRect", LUA_OPCODE(Lua_V1, BlastRect) },
950 { "SubmitSaveGameData", LUA_OPCODE(Lua_V1, SubmitSaveGameData) },
951 { "GetSaveGameData", LUA_OPCODE(Lua_V1, GetSaveGameData) },
952 { "SetTextSpeed", LUA_OPCODE(Lua_V1, SetTextSpeed) },
953 { "GetTextSpeed", LUA_OPCODE(Lua_V1, GetTextSpeed) },
954 { "DetachFromResources", LUA_OPCODE(Lua_V1, DetachFromResources) },
955 { "AttachToResources", LUA_OPCODE(Lua_V1, AttachToResources) },
956 { "ActorPuckOrient", LUA_OPCODE(Lua_V1, ActorPuckOrient) },
957 { "JustLoaded", LUA_OPCODE(Lua_V1, JustLoaded) },
958 { "ResetTextures", LUA_OPCODE(Lua_V1, ResetTextures) },
959 { "ShrinkBoxes", LUA_OPCODE(Lua_V1, ShrinkBoxes) },
960 { "UnShrinkBoxes", LUA_OPCODE(Lua_V1, UnShrinkBoxes) },
961 { "GetShrinkPos", LUA_OPCODE(Lua_V1, GetShrinkPos) },
962 { "NukeResources", LUA_OPCODE(Lua_V1, NukeResources) },
963 { "SetActorInvClipNode", LUA_OPCODE(Lua_V1, SetActorInvClipNode) },
964 { "GetDiskFreeSpace", LUA_OPCODE(Lua_V1, GetDiskFreeSpace) },
965 { "SaveIMuse", LUA_OPCODE(Lua_V1, SaveIMuse) },
966 { "RestoreIMuse", LUA_OPCODE(Lua_V1, RestoreIMuse) },
967 { "GetMemoryUsage", LUA_OPCODE(Lua_V1, GetMemoryUsage) },
968 { "dofile", LUA_OPCODE(Lua_V1, new_dofile) },
969 };
970
971 static struct luaL_reg grimTextOpcodes[] = {
972 { "IsMessageGoing", LUA_OPCODE(Lua_V1, IsMessageGoing) },
973 { "SetSayLineDefaults", LUA_OPCODE(Lua_V1, SetSayLineDefaults) },
974 { "SetActorTalkColor", LUA_OPCODE(Lua_V1, SetActorTalkColor) },
975 { "GetActorTalkColor", LUA_OPCODE(Lua_V1, GetActorTalkColor) },
976 { "SayLine", LUA_OPCODE(Lua_V1, SayLine) },
977 { "PrintLine", LUA_OPCODE(Lua_V1, PrintLine) },
978 { "MakeTextObject", LUA_OPCODE(Lua_V1, MakeTextObject) },
979 { "GetTextObjectDimensions", LUA_OPCODE(Lua_V1, GetTextObjectDimensions) },
980 { "GetFontDimensions", LUA_OPCODE(Lua_V1, GetFontDimensions) },
981 { "ChangeTextObject", LUA_OPCODE(Lua_V1, ChangeTextObject) },
982 { "KillTextObject", LUA_OPCODE(Lua_V1, KillTextObject) },
983 { "BlastText", LUA_OPCODE(Lua_V1, BlastText) },
984 { "ExpireText", LUA_OPCODE(Lua_V1, ExpireText) },
985 { "PurgeText", LUA_OPCODE(Lua_V1, PurgeText) },
986 { "MakeColor", LUA_OPCODE(Lua_V1, MakeColor) },
987 { "GetColorComponents", LUA_OPCODE(Lua_V1, GetColorComponents) },
988 { "SetTranslationMode", LUA_OPCODE(Lua_V1, SetTranslationMode) },
989 { "GetTranslationMode", LUA_OPCODE(Lua_V1, GetTranslationMode) },
990 { "GetTextCharPosition", LUA_OPCODE(Lua_V1, GetTextCharPosition) },
991 { "LocalizeString", LUA_OPCODE(Lua_V1, LocalizeString) },
992 { "SetEmergencyFont", LUA_OPCODE(Lua_V1, SetEmergencyFont) },
993 { "SetOffscreenTextPos", LUA_OPCODE(Lua_V1, SetOffscreenTextPos) }
994 };
995
996 struct luaL_reg grimPrimitivesOpcodes[] = {
997 { "DrawLine", LUA_OPCODE(Lua_V1, DrawLine) },
998 { "DrawPolygon", LUA_OPCODE(Lua_V1, DrawPolygon) },
999 { "DrawRectangle", LUA_OPCODE(Lua_V1, DrawRectangle) },
1000 { "ChangePrimitive", LUA_OPCODE(Lua_V1, ChangePrimitive) },
1001 { "KillPrimitive", LUA_OPCODE(Lua_V1, KillPrimitive) },
1002 { "PurgePrimitiveQueue", LUA_OPCODE(Lua_V1, PurgePrimitiveQueue) }
1003 };
1004
1005 struct luaL_reg grimHardwareOpcodes[] = {
1006 { "Is3DHardwareEnabled", LUA_OPCODE(Lua_V1, Is3DHardwareEnabled) },
1007 { "GetVideoDevices", LUA_OPCODE(Lua_V1, GetVideoDevices) },
1008 { "SetVideoDevices", LUA_OPCODE(Lua_V1, SetVideoDevices) },
1009 { "SetHardwareState", LUA_OPCODE(Lua_V1, SetHardwareState) },
1010 { "Enumerate3DDevices", LUA_OPCODE(Lua_V1, Enumerate3DDevices) },
1011 { "EnumerateVideoDevices", LUA_OPCODE(Lua_V1, EnumerateVideoDevices) }
1012 };
1013
registerOpcodes()1014 void Lua_V1::registerOpcodes() {
1015 // Register main opcodes functions
1016 luaL_openlib(grimMainOpcodes, ARRAYSIZE(grimMainOpcodes));
1017
1018 // Register text opcodes functions
1019 luaL_openlib(grimTextOpcodes, ARRAYSIZE(grimTextOpcodes));
1020
1021 // Register primitives opcodeEs functions
1022 luaL_openlib(grimPrimitivesOpcodes, ARRAYSIZE(grimPrimitivesOpcodes));
1023
1024 // Register hardware opcode functions
1025 luaL_openlib(grimHardwareOpcodes, ARRAYSIZE(grimHardwareOpcodes));
1026
1027 LuaBase::registerOpcodes();
1028 }
1029
boot()1030 void Lua_V1::boot() {
1031 // The default value of these globals, defined in _controls.lua, is 256, 257, 258, 259.
1032 // These values clash with the numpad 0, 1, 2 and 3 keycodes, so we set them here.
1033 lua_pushnumber(KEYCODE_JOY1_HLEFT);
1034 lua_setglobal("JOYSTICK_X_LEFT");
1035
1036 lua_pushnumber(KEYCODE_JOY1_HRIGHT);
1037 lua_setglobal("JOYSTICK_X_RIGHT");
1038
1039 lua_pushnumber(KEYCODE_JOY1_HUP);
1040 lua_setglobal("JOYSTICK_Y_UP");
1041
1042 lua_pushnumber(KEYCODE_JOY1_HDOWN);
1043 lua_setglobal("JOYSTICK_Y_DOWN");
1044
1045 LuaBase::boot();
1046 }
1047
postRestoreHandle()1048 void Lua_V1::postRestoreHandle() {
1049
1050 if (g_grim->getGameType() == GType_GRIM) {
1051 lua_beginblock();
1052 // Set the developerMode, since the save contains the value of
1053 // the installation it was made with.
1054 lua_pushobject(lua_getglobal("developerMode"));
1055 bool devMode = g_registry->getBool("good_times");
1056 pushbool(devMode);
1057 lua_setglobal("developerMode");
1058 lua_endblock();
1059 }
1060
1061 // Starting a movie calls the function 'music_state.pause()', which saves the current sfx volume to a temp
1062 // variable and sets it to 0. When the movie finishes 'music_state.unpause()' will be called, which reads
1063 // the volume from the temp variable and sets it. But if we have modified the sfx volume in the options
1064 // and than load a savegame made during a movie, at the end of the movie the temp variable will have the
1065 // old value. So here we call 'music_state.pause()' again, so that it can set the right value to the
1066 // temp variable.
1067 lua_beginblock();
1068 lua_Object o = lua_getglobal("music_state");
1069 if (!lua_isnil(o)) {
1070 lua_pushobject(o);
1071 lua_pushstring("paused");
1072 if (!lua_isnil(lua_gettable())) {
1073 lua_pushobject(o);
1074 lua_pushstring("paused");
1075 pushbool(false);
1076 lua_settable();
1077
1078 lua_pushobject(o);
1079 lua_pushstring("pause");
1080 lua_Object func = lua_gettable();
1081 lua_pushobject(o);
1082 lua_callfunction(func);
1083 }
1084 }
1085 lua_endblock();
1086 }
1087
1088 } // end of namespace Grim
1089