Text rendering library
[jpcrr.git] / luakernel.lua
blob6452d7f6bd35f493df5a09a0feca95cf1e99690a
1 --
2 -- Copyright 2009 Ilari Liusvaara
3 --
4 -- Licenced under GNU GPL v2.
5 --
7 -- Exported tables:
8 -- - args
9 -- Contains user-level arguments.
11 -- Exported functions:
12 -- - All lua standard functions in tables main, "coroutine", "string" and "table".
13 -- - modulus_split(number num, number...)
14 -- Returns quotents and quotent remainders of number divided by given dividers.
15 -- The number of results returned is equal to number of numbers passed. The
16 -- dividers must be in decreasing order and all dividers must be nonzero and
17 -- should be >1.
18 -- - assert(object ret, object err)
19 -- If ret is considered true, return ret. Otherwise raise err as error. Exception
20 -- if err is nil too, then ret is returned anyway.
21 -- - bit.none(number...)
22 -- Returns 48-bit number that has those bits set that are set in none of its
23 -- arguments.
24 -- - bit.any(number...)
25 -- Returns 48-bit number that has those bits set that are set in any of its
26 -- arguments.
27 -- - bit.parity(number...)
28 -- Returns 48-bit number that has those bits set that are set in even number
29 -- of its arguments.
30 -- - bit.any(number...)
31 -- Returns 48-bit number that has those bits set that are set in all of its
32 -- arguments.
33 -- - bit.lshift(number num, number shift)
34 -- Returns 48 rightmost bits of num shifted by shift places left. Going outside
35 -- shift range 0-47 produces unpredicatable results.
36 -- - bit.rshift(number num, number shift)
37 -- Returns 48 rightmost bits of num shifted by shift places right. Going outside
38 -- shift range 0-47 produces unpredicatable results.
39 -- - bit.arshift(number num, number shift)
40 -- Returns 48 rightmost bits of num shifted by shift places right and bit 47
41 -- value copied to all incoming bits. Going outside shift range 0-47 produces
42 -- unpredicatable results.
43 -- - bit.add(number...)
44 -- Returns sum of all passed numbers modulo 2^48.
45 -- - bit.addneg(number...)
46 -- Returns 0 minus sum of all passed numbers modulo 2^48.
47 -- - bit.addalt(number...)
48 -- Returns sum of odd arguments (first is odd) minus sum of even arguments modulo
49 -- 2^48.
50 -- - bit.tohex(number num)
51 -- Returns hexadecimal string representation of number.
52 -- - jpcrr.pc_running()
53 -- Returns true if PC is running.
54 -- - jpcrr.pc_connected()
55 -- Returns true if PC is connected.
56 -- - jpcrr.wait_vga()
57 -- Waits for VGA to enter frame hold mode. Frame hold happens once per frame.
58 -- - jpcrr.release_vga()
59 -- Allow VGA to exit frame hold mode. Wait for frame hold first.
60 -- - jpcrr.vga_resolution()
61 -- Return VGA x and y resolutions. -1x-1 or 0x0 is returned if no valid resolution.
62 -- Should only be called during frame hold.
63 -- - jpcrr.hud.left_gap(number flags, number gap)
64 -- Set left gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
65 -- 1 (2) is set, dump to video dump.
66 -- - jpcrr.hud.right_gap(number flags, number gap)
67 -- Set right gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
68 -- 1 (2) is set, dump to video dump.
69 -- - jpcrr.hud.top_gap(number flags, number gap)
70 -- Set top gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
71 -- 1 (2) is set, dump to video dump.
72 -- - jpcrr.hud.bottom_gap(number flags, number gap)
73 -- Set bottom gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
74 -- 1 (2) is set, dump to video dump.
75 -- - jpcrr.hud.white_solid_box(number flags, number x, number y, number w, number h)
76 -- Draw with solid opaque box.
77 -- - jpcrr.hud.box(number flags, number x, number y, number w, number h, number linethick,
78 -- number lineRed, number lineGreen, number lineBlue, number lineAlpha,
79 -- number fillRed, number fillGreen, number fillBlue, number fillAlpha)
80 -- Draw box with specified size, border line thickness, line color and fill color.
81 -- - jpcrr.hud.bitmap(number flags, number x, number y, string bmap,
82 -- number fgRed, number fgGreen, number fgBlue, number fgAlpha,
83 -- number bgRed, number bgGreen, number bgBlue, number bgAlpha)
84 -- Draw bitmal with specified foreground color and background color.
85 -- - jpcrr.component_encode(table components)
86 -- Return component encoding for specified components.
87 -- - jpcrr.component_decode(string line)
88 -- Return component decoding for specified line, nil/nil if it doesn't encode
89 -- anything, nil/string if parse error occurs (the error is the second return).
90 -- - jpcrr.save_state(string name)
91 -- Savestate into specified file. Returns name used.
92 -- - jpcrr.save_movie(string name)
93 -- Save movie into specified file. Returns name used.
94 -- - jpcrr.load_state_normal(string name)
95 -- Load specified savestate. Returns name used.
96 -- - jpcrr.load_state_preserve_events(string name)
97 -- Load specified savestate, preserving events. Returns name used.
98 -- - jpcrr.load_state_movie(string name)
99 -- Load specified savestate as movie. Returns name used.
100 -- - jpcrr.assemble()
101 -- Open system settings dialog.
102 -- - jpcrr.change_authors()
103 -- Open change authors dialog.
104 -- - jpcrr.exit = function()
105 -- Exit the Lua VM.
106 -- - jpcrr.ram_dump(string name, boolean binary)
107 -- Dump PC memory to specified file. If binary is true, dump is binary, otherwise
108 -- textual hexadecimal dump.
109 -- - jpcrr.write_byte(number addr, number value)
110 -- Write byte to specified physical address.
111 -- - jpcrr.write_word(number addr, number value)
112 -- Write word to specified physical address (little endian).
113 -- - jpcrr.write_dword(number addr, number value)
114 -- Write dword to specified physical address (little endian).
115 -- - jpcrr.read_byte(number addr)
116 -- Return byte from specified physical address.
117 -- - jpcrr.read_word(number addr)
118 -- Return word from specified physical address (little endian).
119 -- - jpcrr.read_dword(number addr)
120 -- Return dword from specified physical address (little endian).
121 -- - jpcrr.timed_trap(number nsecs)
122 -- Set trap after specified number of nanoseconds. Use nil as nsecs to disable.
123 -- - jpcrr.vretrace_start_trap(boolean is_on)
124 -- Set trap on vretrace start on/off.
125 -- - jpcrr.vretrace_end_trap(boolean is_on)
126 -- Set trap on vretrace end on/off.
127 -- - jpcrr.pc_start()
128 -- Start PC execution.
129 -- - jpcrr.pc_stop()
130 -- Stop PC execution.
131 -- - jpcrr.set_pccontrol_pos(number x, number y)
132 -- Set position of PCControl window.
133 -- - jpcrr.set_luaplugin_pos(number x, number y)
134 -- Set position of LuaPlugin window.
135 -- - jpcrr.set_pcmonitor_pos(number x, number y)
136 -- Set position of PCMonitor window.
137 -- - jpcrr.set_pcstartstoptest_pos(number x, number y)
138 -- Set position of PCStartStopTest window.
139 -- - jpcrr.set_virtualkeyboard_pos(number x, number y)
140 -- Set position of VirtualKeyboard window.
142 -- I/O functions have the following conventions. If function returns any real data, the first
143 -- return value returns this data or is nil. Otherwise first return value is true or false.
144 -- If first return value is nil or false, then the second return value gives textual error
145 -- message for failed operation, or is nil if EOF occured before anything was read.
147 -- Unlink, rename and mkdir don't follow this pattern. They just return true/false to signal
148 -- success or failure.
150 -- Specifying nil as name of file results random filename being used (it even works with unlink,
151 -- mkdir, rename and read-only access, but doesn't make any sense there).
153 -- Class: BinaryFile:
154 -- Binary file for RO or RW access. Methods are as follows:
155 -- - name()
156 -- Return name of file.
157 -- - length()
158 -- Return length of file.
159 -- - set_length(number length)
160 -- Truncate file to specified length
161 -- - read(number offset, number length)
162 -- Read up to length bytes from offset.
163 -- - write(number offset, string content)
164 -- Write content to specified offset.
165 -- - close()
166 -- Close the file.
167 -- Class: BinaryInput:
168 -- Binary file for sequential input. Methods are as follows:
169 -- - name()
170 -- Return name of file.
171 -- - four_to_five()
172 -- Return BinaryInput that is four to five decoding of this stream.
173 -- - text()
174 -- Return stream as TextInput.
175 -- - inflate()
176 -- Return BinaryInput that is inflate of this stream.
177 -- - read(number bytes)
178 -- Read up to bytes bytes from file.
179 -- - read()
180 -- Read the entiere file at once.
181 -- - close()
182 -- Close the file.
183 -- Character set for binary files is Latin-1.
185 -- Class: BinaryOutput:
186 -- Binary file for sequential output. Methods are as follows:
187 -- - name()
188 -- Return name of file.
189 -- - four_to_five()
190 -- Return BinaryOutput that writes four to five encoded output to this stream.
191 -- - text()
192 -- Return stream as TextOutput.
193 -- - deflate()
194 -- Return BinaryOutput that writes deflate output to this stream.
195 -- - write(string content)
196 -- Write string to file.
197 -- - close()
198 -- Close the file.
199 -- Character set for binary files is Latin-1.
201 -- Class: TextInput:
202 -- - name()
203 -- Return name of file.
204 -- - read()
205 -- Read line from file.
206 -- - read_component()
207 -- Read next componented line into array.
208 -- - lines()
209 -- Line iterator function.
210 -- - close()
211 -- Close the file.
212 -- Character set for text files is UTF-8.
214 -- Class: TextOutput:
215 -- - name()
216 -- Return name of file.
217 -- - write(string line)
218 -- Write line line to file.
219 -- - write_component(table components)
220 -- Write componented line.
221 -- - close()
222 -- Close the file.
223 -- Character set for text files is UTF-8.
225 -- Class ArchiveIn:
226 -- - member(string name)
227 -- Open substream for member name. The methods are the same as for io.opentextin.
228 -- - member_binary(string name)
229 -- Open binary (four to five) substream for member name. The methods are the same as
230 -- for io.openbinaryin.
231 -- - close()
232 -- Close the file. Any opened substreams are invalidated.
234 -- Class ArchiveOut:
235 -- - member(string name)
236 -- Open substream for member name. The methods are the same as for io.opentextout. Note that
237 -- previous member must be closed before next can open.
238 -- - member_binary(string name)
239 -- Open binary (four to five) substream for member name. The methods are the same as
240 -- for io.openbinaryout. Note that previous substream must be closed before next can open.
241 -- - commit()
242 -- Commit the file. No substream may be open. Closes the file.
243 -- - rollback()
244 -- Rollback the file. No substream may be open. Closes the file.
246 -- - io.open(string name, string mode) -> BinaryFile
247 -- Open file named @name in specified mode. The mode can be 'r' (read only) or 'rw' (read and
248 -- write).
249 -- - io.open_read(string name) -> BinaryInput
250 -- Open file named @name as binary input stream.
251 -- - io.open_write(string name) -> BinaryOutput
252 -- Open file named @name as binary input stream.
253 -- - io.open_arch_read(string name) -> ArchiveIn
254 -- Open file named @name as input archive.
255 -- - io.open_arch_write(string name) -> ArchiveOut
256 -- Open file named @name as output archive.
257 -- - io.mkdir(string name)
258 -- Create directory name. Returns name created on success, nil on failure.
259 -- - io.unlink(string name)
260 -- Delete file/directory name. Returns name deleted on success, nil on failure.
261 -- - io.rename(string old, string new)
262 -- Rename file old -> new. Returns old, new on success, nil on failure.
271 local handle, err, chunk, indication, k, v;
273 local loadmod = loadmodule;
274 loadmodule = nil;
276 local export_module_in = function(tab, modname, prefix)
277 local fun = loadmod(modname);
278 for k, v in pairs(fun) do
279 tab[(prefix or "") .. k] = v;
283 jpcrr = {};
284 jpcrr.hud = {};
285 bit = {};
286 io = {};
288 export_module_in(jpcrr, "org.jpc.luaextensions.Base");
289 export_module_in(jpcrr, "org.jpc.luaextensions.ComponentCoding", "component_");
290 export_module_in(bit, "org.jpc.luaextensions.Bitops");
292 -- Few misc functions.
293 assert = function(val, err)
294 if (not val) and err then
295 error(err);
297 return val;
300 modulus_split = function(number, ...)
301 local dividers = {...};
302 local results = {};
303 local rem;
305 for k, v in ipairs(dividers) do
306 rem = number % v;
307 table.insert(results, (number - rem) / v);
308 number = rem;
311 table.insert(results, number);
312 return unpack(results);
315 local getmtable = getmetatable;
316 local toString = tostring;
317 local inject_binary_file;
318 local inject_binary_input;
319 local inject_binary_output;
320 local inject_text_input;
321 local inject_text_output;
322 local inject_archive_input;
323 local inject_archive_output;
325 -- Class member injectors.
326 inject_binary_file = function(obj, name)
327 local _name = name;
328 getmtable(obj).name = function(obj)
329 return _name;
331 getmtable(obj).__index = function(tab, name)
332 local x = getmtable(obj)[name];
333 if x then
334 return x;
336 error("Invalid method " .. name .. " for BinaryFile");
338 return obj;
341 inject_binary_input = function(obj, name)
342 local _name = name;
343 local old_four_to_five = getmtable(obj).four_to_five;
344 local old_inflate = getmtable(obj).inflate;
345 local old_text = getmtable(obj).text;
346 local old_read = getmtable(obj).read;
348 getmtable(obj).name = function(obj)
349 return _name;
351 getmtable(obj).four_to_five = function(obj)
352 local res, err;
353 res, err = old_four_to_five(obj);
354 if not res then
355 return res, err;
357 return inject_binary_input(res, "four-to-five<" .. _name .. ">");
359 getmtable(obj).inflate = function(obj)
360 local res, err;
361 res, err = old_inflate(obj);
362 if not res then
363 return res, err;
365 return inject_binary_input(res, "inflate<" .. _name .. ">");
367 getmtable(obj).text = function(obj)
368 local res, err;
369 res, err = old_text(obj);
370 if not res then
371 return res, err;
373 return inject_text_input(res, "text<" .. _name .. ">");
375 getmtable(obj).read = function(obj, toread)
376 if toread then
377 return old_read(obj, toread);
378 else
379 local res = "";
380 local ret, err;
381 while true do
382 ret, err = old_read(obj, 16384);
383 if not ret then
384 if not err then
385 return res;
387 return nil, err;
389 res = res .. ret;
393 getmtable(obj).__index = function(tab, name)
394 local x = getmtable(obj)[name];
395 if x then
396 return x;
398 error("Invalid method " .. name .. " for BinaryInput");
400 return obj;
403 inject_binary_output = function(obj, name)
404 local _name = name;
405 local old_four_to_five = getmtable(obj).four_to_five;
406 local old_deflate = getmtable(obj).deflate;
407 local old_text = getmtable(obj).text;
409 getmtable(obj).name = function(obj)
410 return _name;
412 getmtable(obj).four_to_five = function(obj)
413 local res, err;
414 res, err = old_four_to_five(obj);
415 if not res then
416 return res, err;
418 return inject_binary_output(res, "four-to-five<" .. _name .. ">");
420 getmtable(obj).deflate = function(obj)
421 local res, err;
422 res, err = old_deflate(obj);
423 if not res then
424 return res, err;
426 return inject_binary_output(res, "deflate<" .. _name .. ">");
428 getmtable(obj).text = function(obj)
429 local res, err;
430 res, err = old_text(obj);
431 if not res then
432 return res, err;
434 return inject_text_output(res, "text<" .. _name .. ">");
436 getmtable(obj).__index = function(tab, name)
437 local x = getmtable(obj)[name];
438 if x then
439 return x;
441 error("Invalid method " .. name .. " for BinaryOutput");
443 return obj;
446 inject_text_input = function(obj, name)
447 local _name = name;
448 getmtable(obj).lines = function(obj)
449 return function(state, prevline)
450 return state:read();
451 end, obj, nil;
453 getmtable(obj).name = function(obj)
454 return _name;
456 getmtable(obj).__index = function(tab, name)
457 local x = getmtable(obj)[name];
458 if x then
459 return x;
461 error("Invalid method " .. name .. " for TextInput");
463 return obj;
466 inject_text_output = function(obj, name)
467 local _name = name;
468 getmtable(obj).name = function(obj)
469 return _name;
471 getmtable(obj).__index = function(tab, name)
472 local x = getmtable(obj)[name];
473 if x then
474 return x;
476 error("Invalid method " .. name .. " for TextOutput");
478 return obj;
481 inject_archive_input = function(obj, name)
482 local _name = name;
483 local old_member = getmtable(obj).member;
484 getmtable(obj).member = function(obj, member)
485 local res, err;
486 res, err = old_member(obj, member);
487 if not res then
488 return res, err;
490 return inject_binary_input(res, _name .. "[" .. member .. "]");
492 getmtable(obj).name = function(obj)
493 return _name;
495 getmtable(obj).__index = function(tab, name)
496 local x = getmtable(obj)[name];
497 if x then
498 return x;
500 error("Invalid method " .. name .. " for ArchiveInput");
502 return obj;
505 inject_archive_output = function(obj, name)
506 local _name = name;
507 local old_member = getmtable(obj).member;
508 getmtable(obj).member = function(obj, member)
509 local res, err;
510 res, err = old_member(obj, member);
511 if not res then
512 return res, err;
514 return inject_binary_output(res, _name .. "[" .. member .. "]");
516 getmtable(obj).name = function(obj)
517 return _name;
519 getmtable(obj).__index = function(tab, name)
520 local x = getmtable(obj)[name];
521 if x then
522 return x;
524 error("Invalid method " .. name .. " for ArchiveOutput");
526 return obj;
530 -- Redefined print.
532 local rprint = print_console_msg;
533 print_console_msg = nil;
534 print = function(...)
535 local x = "";
536 local y = {...};
537 local i;
538 for i = 1,#y do
539 if i > 1 then
540 x = x .. "\t" .. toString(y[i]);
541 else
542 x = toString(y[i]);
545 rprint(x);
547 print_console_msg = nil;
550 -- I/O routines.
551 local stringfind = string.find;
552 local randname = loadmod("org.jpc.luaextensions.DelayedDelete").random_temp_name;
553 local path = args["luapath"] or ".";
554 local toresourcename = function(resname)
555 if not resname then
556 return randname(path .. "/", "luatemp-");
559 if not stringfind(resname, "[%d%l%u_%-]") then
560 error("Bad resource name (case 1): " .. resname);
562 if stringfind(resname, "^/") then
563 error("Bad resource name (case 2): " .. resname);
565 if stringfind(resname, "%.%.") then
566 error("Bad resource name (case 3): " .. resname);
568 if stringfind(resname, "\\") then
569 error("Bad resource name (case 4): " .. resname);
572 return resname, path .. "/" .. resname;
577 local openbinin = loadmod("org.jpc.luaextensions.BinaryInFile").open;
578 local openbinout = loadmod("org.jpc.luaextensions.BinaryOutFile").open;
579 local openarchin = loadmod("org.jpc.luaextensions.ArchiveIn").open;
580 local openarchout = loadmod("org.jpc.luaextensions.ArchiveOut").open;
581 local openbinary = loadmod("org.jpc.luaextensions.BinaryFile").open;
583 local baseFS = loadmod("org.jpc.luaextensions.BaseFSOps");
584 local mkdir = baseFS.mkdir;
585 local unlink = baseFS.unlink;
586 local rename = baseFS.rename;
588 local getmtable = getmetatable;
590 loadfile = function(_script)
591 local file, file2, err, content;
592 local x, y;
593 x, y = toresourcename(_script);
594 file, err = openbinin(y, "r");
595 if not file then
596 return nil, "Can't open " .. _script .. ": " .. err;
598 file2, err = file:text();
599 if not file2 then
600 return nil, "Can't transform " .. _script .. ": " .. err;
602 content = "";
603 line = file2:read();
604 while line do
605 content = content .. line .. "\n";
606 line = file2:read();
608 file2:close();
609 file:close();
610 return loadstring(content, _script);
613 io.open = function(name, mode)
614 local _name;
615 local res, err;
616 local y;
617 _name, y = toresourcename(name);
618 res, err = openbinary(y, mode);
619 if not res then
620 return res, err;
622 return inject_binary_file(res, _name);
625 io.open_arch_read = function(name)
626 local _name = name;
627 local res, err;
628 local y;
629 _name, y = toresourcename(name);
630 res, err = openarchin(y);
631 if not res then
632 return res, err;
634 return inject_archive_input(res, _name);
637 io.open_arch_write = function(name)
638 local _name = name;
639 local res, err;
640 local y;
641 _name, y = toresourcename(name);
642 res, err = openarchout(y);
643 if not res then
644 return res, err;
646 return inject_archive_output(res, _name);
649 io.open_read = function(name)
650 local _name = name;
651 local res, err;
652 local y;
653 _name, y = toresourcename(name);
654 res, err = openbinin(y);
655 if not res then
656 return res, err;
658 return inject_binary_input(res, _name);
661 io.open_write = function(name)
662 local _name = name;
663 local res, err;
664 local y;
665 _name, y = toresourcename(name);
666 res, err = openbinout(y);
667 if not res then
668 return res, err;
670 return inject_binary_output(res, _name);
673 io.mkdir = function(name)
674 local _name, y;
675 _name, y = toresourcename(name);
676 if mkdir(y) then
677 return _name;
678 else
679 return nil;
683 io.unlink = function(name)
684 local _name, y;
685 _name, y = toresourcename(name);
686 if unlink(y) then
687 return _name;
688 else
689 return nil;
693 io.rename = function(name1, name2)
694 local _name, y;
695 local _name2, y2;
696 _name, y = toresourcename(name1);
697 _name2, y2 = toresourcename(name2);
698 if rename(y, y2) then
699 return _name, _name2;
700 else
701 return nil;
706 -- Various stuff built on top of ECI.
707 local invoke = jpcrr.invoke;
708 local invokecall = jpcrr.call;
709 local invokesync = jpcrr.invoke_synchronous;
711 jpcrr.save_state = function(name)
712 local _name, _fname;
713 _name, _fname = toresourcename(name);
714 invokesync("state-save", {_fname});
715 return _name;
718 jpcrr.save_movie = function(name)
719 local _name, _fname;
720 _name, _fname = toresourcename(name);
721 invokesync("movie-save", {_name});
722 return _name;
725 jpcrr.load_state_normal = function(name)
726 local _name, _fname;
727 _name, _fname = toresourcename(name);
728 invokesync("state-load", {_name});
729 return _name;
732 jpcrr.load_state_preserve_events = function(name)
733 local _name, _fname;
734 _name, _fname = toresourcename(name);
735 invokesync("state-load-noevents", {_name});
736 return _name;
739 jpcrr.load_state_movie = function(name)
740 local _name, _fname;
741 _name, _fname = toresourcename(name);
742 invokesync("state-load-movie", {_name});
743 return _name;
746 jpcrr.assemble = function()
747 invokesync("pc-assemble");
750 jpcrr.change_authors = function()
751 invokesync("change-authors");
754 jpcrr.ram_dump = function(name, binary)
755 local _name, _fname;
756 _name, _fname = toresourcename(name);
757 if binary then
758 invokesync("ram-dump-binary", {_name});
759 else
760 invokesync("ram-dump-text", {_name});
762 return _name;
765 jpcrr.hud.left_gap = function(f, g)
766 invoke("hud-left-gap", {toString(f), toString(g)});
769 jpcrr.hud.right_gap = function(f, g)
770 invoke("hud-right-gap", {toString(f), toString(g)});
773 jpcrr.hud.top_gap = function(f, g)
774 invoke("hud-top-gap", {toString(f), toString(g)});
777 jpcrr.hud.bottom_gap = function(f, g)
778 invoke("hud-bottom-gap", {toString(f), toString(g)});
781 jpcrr.hud.white_solid_box = function(f, x, y, w, h)
782 invoke("hud-white-solid-box", {toString(f), toString(x), toString(y), toString(w), toString(h)});
785 jpcrr.hud.box = function(f, x, y, w, h, t, lr, lg, lb, la, fr, fg, fb, fa)
786 invoke("hud-box", {toString(f), toString(x), toString(y), toString(w), toString(h),
787 toString(t), toString(lr), toString(lg), toString(lb), toString(la), toString(fr),
788 toString(fg), tostring(fb), toString(fa)});
791 jpcrr.hud.bitmap = function(f, x, y, bmap, lr, lg, lb, la, fr, fg, fb, fa)
792 invoke("hud-bitmap", {toString(f), toString(x), toString(y), bmap, toString(lr),
793 toString(lg), toString(lb), toString(la), toString(fr), toString(fg), tostring(fb),
794 toString(fa)});
797 jpcrr.set_pccontrol_pos = function(x, y)
798 invokesync("pccontrol-setwinpos", {toString(x), toString(y)});
801 jpcrr.set_luaplugin_pos = function(x, y)
802 invokesync("luaplugin-setwinpos", {toString(x), toString(y)});
805 jpcrr.set_pcmonitor_pos = function(x, y)
806 invokesync("pcmonitor-setwinpos", {toString(x), toString(y)});
809 jpcrr.set_pcstartstoptest_pos = function(x, y)
810 invokesync("pcstartstoptest-setwinpos", {toString(x), toString(y)});
813 jpcrr.set_virtualkeyboard_pos = function(x, y)
814 invokesync("virtualkeyboard-setwinpos", {toString(x), toString(y)});
817 jpcrr.exit = function()
818 invokesync("luaplugin-terminate");
821 jpcrr.pc_start = function()
822 invoke("pc-start");
825 jpcrr.pc_stop = function()
826 invokesync("pc-stop");
829 jpcrr.vretrace_start_trap = function(is_on)
830 if is_on then
831 invokesync("trap-vretrace-start-on");
832 else
833 invokesync("trap-vretrace-start-off");
837 jpcrr.vretrace_end_trap = function(is_on)
838 if is_on then
839 invokesync("trap-vretrace-end-on");
840 else
841 invokesync("trap-vretrace-end-off");
845 jpcrr.timed_trap = function(nsecs)
846 if nsecs then
847 invokesync("trap-timed", {toString(nsecs)});
848 else
849 invokesync("trap-timed-disable");
853 jpcrr.write_byte = function(addr, value)
854 invokesync("memory-write", {toString(addr), toString(value), "1"});
857 jpcrr.write_word = function(addr, value)
858 invokesync("memory-write", {toString(addr), toString(value), "2"});
861 jpcrr.write_dword = function(addr, value)
862 invokesync("memory-write", {toString(addr), toString(value), "4"});
865 jpcrr.read_byte = function(addr)
866 local t = {toString(addr), "1"};
867 t = invokecall("memory-read", t);
868 return (t or {})[1];
871 jpcrr.read_word = function(addr)
872 local t = {toString(addr), "2"};
873 t = invokecall("memory-read", t);
874 return (t or {})[1];
877 jpcrr.read_dword = function(addr)
878 local t = {toString(addr), "4"};
879 t = invokecall("memory-read", t);
880 return (t or {})[1];
883 jpcrr.invoke = nil;
884 jpcrr.invoke_synchronous = nil;
885 jpcrr.call = null
887 -- Dofile.
888 dofile = function(_script)
889 local chunk, err, indication
890 chunk, err = loadfile(_script);
891 if not chunk then
892 error("Kernel: Can't load subscript " .. _script .. ": " .. err);
894 return chunk();
897 local args2 = args;
898 args = null;
899 args = {};
900 for k, v in pairs(args2) do
901 if (#k > 2 and string.byte(k, 1) == 120 and string.byte(k, 2) == 45) then
902 args[string.sub(k, 3)] = v;
905 jpcrr_raw = null;
908 chunk, err = loadfile(script);
909 if not chunk then
910 print("Kernel: Can't load script " .. script .. ": " .. err);
911 invoke("luaplugin-terminate");
912 while true do end
915 script = null;
916 indication, err = pcall(chunk);
917 if not indication then
918 print("Kernel: Unprotected error in script: " .. err);
919 invoke("luaplugin-terminate");
920 while true do end