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