2 -- Copyright 2009-2010 Ilari Liusvaara
4 -- Licenced under GNU GPL v2.
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
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
24 -- - bit.any(number...)
25 -- Returns 48-bit number that has those bits set that are set in any of its
27 -- - bit.parity(number...)
28 -- Returns 48-bit number that has those bits set that are set in even number
30 -- - bit.any(number...)
31 -- Returns 48-bit number that has those bits set that are set in all of its
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
50 -- - bit.rol(number num, number shift)
51 -- Returns 48 rightmost bits of num rotated by shift places left. Going outside
52 -- shift range 0-47 produces unpredicatable results.
53 -- - bit.ror(number num, number shift)
54 -- Returns 48 rightmost bits of num rotated by shift places right. Going outside
55 -- shift range 0-47 produces unpredicatable results.
56 -- - bit.bswap2(number num)
57 -- Returns 16 rightmost bits of num byte-swapped.
58 -- - bit.bswap3(number num)
59 -- Returns 24 rightmost bits of num byte-swapped.
60 -- - bit.bswap4(number num)
61 -- Returns 32 rightmost bits of num byte-swapped.
62 -- - bit.bswap5(number num)
63 -- Returns 40 rightmost bits of num byte-swapped.
64 -- - bit.bswap6(number num)
65 -- Returns 48 rightmost bits of num byte-swapped.
66 -- - bit.signextend(number num, number bitnum)
67 -- Copy bitnum'th bit of num to all higher bits of num and return result. Going
68 -- outside bitnum range of 0-47 produces unpredictable results.
69 -- - bit.tosigned(number num, number bitnum)
70 -- Mask off bitnum'th bit and all higher bits. If bitnum'th bit of num was set,
71 -- perform 2s complement on number and negate the result.
72 -- - bit.tohex(number num)
73 -- Returns hexadecimal string representation of number.
74 -- - jpcrr.wait_message()
75 -- Waits for message (string) to come from message queue. Reutrns nil if interrupted.
76 -- - jpcrr.poll_message()
77 -- Checks if there is message from message queue. Reutrns message if there is one,
79 -- - jpcrr.wait_pc_stop()
80 -- Waits for PC execution to stop (but does not attempt to actually stop it).
81 -- If script is in frame hold, the frame hold is released.
82 -- Returns true if execution got stopped, false if interrupted.
83 -- - jpcrr.pc_running()
84 -- Returns true if PC is running.
85 -- - jpcrr.clock_time()
86 -- Returns current time or nil if no PC.
87 -- - jpcrr.pc_connected()
88 -- Returns true if PC is connected.
89 -- - jpcrr.wait_pc_attach()
90 -- Wait for PC to attach.
91 -- - jpcrr.next_frame()
92 -- Wait for next frame output hold.
93 -- - jpcrr.in_frame_hold()
94 -- Returns true if in frame hold, false otherwise.
95 -- - jpcrr.keypressed(number key)
96 -- Return true if key is pressed, else false.
98 -- Waits for VGA to enter frame hold mode. Frame hold happens once per frame.
99 -- - jpcrr.release_vga()
100 -- Allow VGA to exit frame hold mode. Wait for frame hold first.
101 -- - jpcrr.vga_resolution()
102 -- Return VGA x and y resolutions. -1x-1 or 0x0 is returned if no valid resolution.
103 -- Should only be called during frame hold.
104 -- - jpcrr.hud.left_gap(number flags, number gap)
105 -- Set left gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
106 -- 1 (2) is set, dump to video dump.
107 -- - jpcrr.hud.right_gap(number flags, number gap)
108 -- Set right gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
109 -- 1 (2) is set, dump to video dump.
110 -- - jpcrr.hud.top_gap(number flags, number gap)
111 -- Set top gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
112 -- 1 (2) is set, dump to video dump.
113 -- - jpcrr.hud.bottom_gap(number flags, number gap)
114 -- Set bottom gap for HUD. If flags has bit 0 (1) set, draw on screen, if bit
115 -- 1 (2) is set, dump to video dump.
116 -- - jpcrr.hud.white_solid_box(number flags, number x, number y, number w, number h)
117 -- Draw with solid opaque box.
118 -- - jpcrr.hud.box(number flags, number x, number y, number w, number h, number linethick,
119 -- number lineRed, number lineGreen, number lineBlue, number lineAlpha,
120 -- number fillRed, number fillGreen, number fillBlue, number fillAlpha)
121 -- Draw box with specified size, border line thickness, line color and fill color.
122 -- - jpcrr.hud.circle(number flags, number x, number y, number r, number linethick,
123 -- number lineRed, number lineGreen, number lineBlue, number lineAlpha,
124 -- number fillRed, number fillGreen, number fillBlue, number fillAlpha)
125 -- Draw circle with specified size, border line thickness, line color and fill color.
126 -- - jpcrr.hud.bitmap(number flags, number x, number y, string bmap,
127 -- number fgRed, number fgGreen, number fgBlue, number fgAlpha,
128 -- number bgRed, number bgGreen, number bgBlue, number bgAlpha)
129 -- Draw bitmap with specified foreground color and background color.
130 -- - jpcrr.hud.bitmap_binary(number flags, number x, number y, string bmap,
131 -- number fgRed, number fgGreen, number fgBlue, number fgAlpha,
132 -- number bgRed, number bgGreen, number bgBlue, number bgAlpha)
133 -- Draw binary bitmap with specified foreground color and background color.
134 -- - jpcrr.joystick_state()
135 -- Returns nil if no joystick. Otherwise returns hold times for all four axis (numeric)
136 -- followed by button states (boolean).
137 -- - jpcrr.keyboard_leds()
138 -- Returns nil if no keyboard, false if LED status is unknown. Otherwise returns three
139 -- booleans, first being state of num lock, second being state of caps lock and third
140 -- being state of scroll lock.
141 -- - jpcrr.mouse_state()
142 -- Returns nil if no mouse. Otherwise returns X, Y and Z axis pending motions (numeric)
143 -- followed by button states (5 booleans).
144 -- - jpcrr.component_encode(table components)
145 -- Return component encoding for specified components.
146 -- - jpcrr.component_decode(string line)
147 -- Return component decoding for specified line, nil/nil if it doesn't encode
148 -- anything, nil/string if parse error occurs (the error is the second return).
149 -- - jpcrr.save_state(string name)
150 -- Savestate into specified file. Returns name used.
151 -- - jpcrr.save_movie(string name)
152 -- Save movie into specified file. Returns name used.
153 -- - jpcrr.load_state_normal(string name)
154 -- Load specified savestate. Returns name used.
155 -- - jpcrr.load_state_preserve_events(string name)
156 -- Load specified savestate, preserving events. Returns name used.
157 -- - jpcrr.load_state_movie(string name)
158 -- Load specified savestate as movie. Returns name used.
159 -- - jpcrr.assemble()
160 -- Open system settings dialog.
161 -- - jpcrr.change_authors()
162 -- Open change authors dialog.
163 -- - jpcrr.exit = function()
165 -- - jpcrr.ram_dump(string name, boolean binary)
166 -- Dump PC memory to specified file. If binary is true, dump is binary, otherwise
167 -- textual hexadecimal dump.
168 -- - jpcrr.write_byte(number addr, number value)
169 -- Write byte to specified physical address.
170 -- - jpcrr.write_word(number addr, number value)
171 -- Write word to specified physical address (little endian).
172 -- - jpcrr.write_dword(number addr, number value)
173 -- Write dword to specified physical address (little endian).
174 -- - jpcrr.read_byte(number addr)
175 -- Return byte from specified physical address.
176 -- - jpcrr.read_word(number addr)
177 -- Return word from specified physical address (little endian).
178 -- - jpcrr.read_dword(number addr)
179 -- Return dword from specified physical address (little endian).
180 -- - jpcrr.read_byte_signed(number addr)
181 -- Return signed byte from specified physical address.
182 -- - jpcrr.read_word_signed(number addr)
183 -- Return signed word from specified physical address (little endian).
184 -- - jpcrr.read_dword_signed(number addr)
185 -- Return signed dword from specified physical address (little endian).
186 -- - jpcrr.timed_trap(number nsecs)
187 -- Set trap after specified number of nanoseconds. Use nil as nsecs to disable.
188 -- - jpcrr.vretrace_start_trap(boolean is_on)
189 -- Set trap on vretrace start on/off.
190 -- - jpcrr.vretrace_end_trap(boolean is_on)
191 -- Set trap on vretrace end on/off.
192 -- - jpcrr.pc_start()
193 -- Start PC execution.
195 -- Stop PC execution.
196 -- - jpcrr.set_pccontrol_pos(number x, number y)
197 -- Set position of PCControl window.
198 -- - jpcrr.set_luaplugin_pos(number x, number y)
199 -- Set position of LuaPlugin window.
200 -- - jpcrr.set_pcmonitor_pos(number x, number y)
201 -- Set position of PCMonitor window.
202 -- - jpcrr.set_pcstartstoptest_pos(number x, number y)
203 -- Set position of PCStartStopTest window.
204 -- - jpcrr.set_virtualkeyboard_pos(number x, number y)
205 -- Set position of VirtualKeyboard window.
206 -- - jpcrr.stringlessthan(String x, String y)
207 -- Return true if x is before y in codepoint lexical order, otherwise false.
208 -- - jpcrr.screenshot(boolean include_hud)
209 -- Take screen shot (Requires monitor). If include_hud is true, include HUD
210 -- (as shown on screen). Note that this should only be called during frame
211 -- hold or results are pretty much undefined.
212 -- - jpcrr.sendevent(string/number...)
213 -- Sends specified event.
215 -- I/O functions have the following conventions. If function returns any real data, the first
216 -- return value returns this data or is nil. Otherwise first return value is true or false.
217 -- If first return value is nil or false, then the second return value gives textual error
218 -- message for failed operation, or is nil if EOF occured before anything was read.
220 -- Unlink, rename and mkdir don't follow this pattern. They just return true/false to signal
221 -- success or failure.
223 -- Specifying nil as name of file results random filename being used (it even works with unlink,
224 -- mkdir, rename and read-only access, but doesn't make any sense there).
226 -- Class: BinaryFile:
227 -- Binary file for RO or RW access. Methods are as follows:
229 -- Return name of file.
231 -- Return length of file.
232 -- - set_length(number length)
233 -- Truncate file to specified length
234 -- - read(number offset, number length)
235 -- Read up to length bytes from offset.
236 -- - write(number offset, string content)
237 -- Write content to specified offset.
240 -- Class: BinaryInput:
241 -- Binary file for sequential input. Methods are as follows:
243 -- Return name of file.
245 -- Return BinaryInput that is four to five decoding of this stream.
247 -- Return stream as TextInput.
249 -- Return BinaryInput that is inflate of this stream.
250 -- - read(number bytes)
251 -- Read up to bytes bytes from file.
253 -- Read the entiere file at once.
256 -- Character set for binary files is Latin-1.
258 -- Class: BinaryOutput:
259 -- Binary file for sequential output. Methods are as follows:
261 -- Return name of file.
263 -- Return BinaryOutput that writes four to five encoded output to this stream.
265 -- Return stream as TextOutput.
267 -- Return BinaryOutput that writes deflate output to this stream.
268 -- - write(string content)
269 -- Write string to file.
272 -- Character set for binary files is Latin-1.
276 -- Return name of file.
278 -- Read line from file.
279 -- - read_component()
280 -- Read next componented line into array.
282 -- Line iterator function.
285 -- Character set for text files is UTF-8.
287 -- Class: TextOutput:
289 -- Return name of file.
290 -- - write(string line)
291 -- Write line line to file.
292 -- - write_component(table components)
293 -- Write componented line.
296 -- Character set for text files is UTF-8.
299 -- - member(string name)
300 -- Open substream for member name. The methods are the same as for io.opentextin.
301 -- - member_binary(string name)
302 -- Open binary (four to five) substream for member name. The methods are the same as
303 -- for io.openbinaryin.
305 -- Close the file. Any opened substreams are invalidated.
307 -- Return table listing all members of archive (sorted by name).
309 -- - member(string name)
310 -- Open substream for member name. The methods are the same as for io.opentextout. Note that
311 -- previous member must be closed before next can open.
312 -- - member_binary(string name)
313 -- Open binary (four to five) substream for member name. The methods are the same as
314 -- for io.openbinaryout. Note that previous substream must be closed before next can open.
316 -- Commit the file. No substream may be open. Closes the file.
318 -- Rollback the file. No substream may be open. Closes the file.
320 -- - io.open(string name, string mode) -> BinaryFile
321 -- Open file named @name in specified mode. The mode can be 'r' (read only) or 'rw' (read and
323 -- - io.open_read(string name) -> BinaryInput
324 -- Open file named @name as binary input stream.
325 -- - io.open_write(string name) -> BinaryOutput
326 -- Open file named @name as binary input stream.
327 -- - io.open_arch_read(string name) -> ArchiveIn
328 -- Open file named @name as input archive.
329 -- - io.open_arch_write(string name) -> ArchiveOut
330 -- Open file named @name as output archive.
331 -- - io.mkdir(string name)
332 -- Create directory name. Returns name created on success, nil on failure.
333 -- - io.unlink(string name)
334 -- Delete file/directory name. Returns name deleted on success, nil on failure.
335 -- - io.rename(string old, string new)
336 -- Rename file old -> new. Returns old, new on success, nil on failure.
337 -- - io.transform.text()
338 -- Returns function that calls text() method of its parameter.
339 -- - io.transform.four_to_five()
340 -- Returns function that calls four_to_five() method of its parameter.
341 -- - io.transform.deflate()
342 -- Returns function that calls deflate() method of its parameter.
343 -- - io.transform.inflate()
344 -- Returns function that calls inflate() method of its parameter.
345 -- - io.dotransform(object obj, function...)
346 -- Call specified functions on specified object. If any function fails (first argument nil
347 -- or false), call close method on preceeding object. Otherwise call specified functions
348 -- chained left to right and return the result.
349 -- - io.dotransform2(object obj, string err, function...)
350 -- Similar to dotransform except if obj is nil or false, returns obj, err.
356 local handle
, err
, chunk
, indication
, k
, v
;
358 local loadmod
= loadmodule
;
361 local export_module_in
= function(tab
, modname
, prefix
)
362 local fun
= loadmod(modname
);
363 for k
, v
in pairs(fun
) do
364 tab
[(prefix
or "") .. k
] = v
;
373 export_module_in(jpcrr
, "org.jpc.luaextensions.Base");
374 export_module_in(jpcrr
, "org.jpc.luaextensions.InputDevices");
375 export_module_in(jpcrr
, "org.jpc.luaextensions.ComponentCoding", "component_");
376 export_module_in(bit
, "org.jpc.luaextensions.Bitops");
378 -- Few misc functions.
379 assert = function(val
, err
)
380 if (not val
) and err
then
386 modulus_split
= function(number, ...)
387 local dividers
= {...};
391 for k
, v
in ipairs(dividers
) do
393 table.insert(results
, (number - rem
) / v
);
397 table.insert(results
, number);
398 return unpack(results
);
401 local getmtable
= getmetatable
;
402 local toString
= tostring;
403 local inject_binary_file
;
404 local inject_binary_input
;
405 local inject_binary_output
;
406 local inject_text_input
;
407 local inject_text_output
;
408 local inject_archive_input
;
409 local inject_archive_output
;
411 -- Class member injectors.
412 inject_binary_file
= function(obj
, name
)
414 getmtable(obj
).name
= function(obj
)
417 getmtable(obj
).__index
= function(tab
, name
)
418 local x
= getmtable(obj
)[name
];
422 error("Invalid method " .. name
.. " for BinaryFile");
427 inject_binary_input
= function(obj
, underlying
, name
)
429 local old_four_to_five
= getmtable(obj
).four_to_five
;
430 local old_inflate
= getmtable(obj
).inflate
;
431 local old_text
= getmtable(obj
).text
;
432 local old_read
= getmtable(obj
).read;
433 local old_close
= getmtable(obj
).close
;
434 local underlying_object
= underlying
;
436 getmtable(obj
).name
= function(obj
)
439 getmtable(obj
).four_to_five
= function(obj
)
441 res
, err
= old_four_to_five(obj
);
445 return inject_binary_input(res
, obj
, "four-to-five<" .. _name
.. ">");
447 getmtable(obj
).inflate
= function(obj
)
449 res
, err
= old_inflate(obj
);
453 return inject_binary_input(res
, obj
, "inflate<" .. _name
.. ">");
455 getmtable(obj
).text
= function(obj
)
457 res
, err
= old_text(obj
);
461 return inject_text_input(res
, obj
, "text<" .. _name
.. ">");
463 getmtable(obj
).read = function(obj
, toread
)
465 return old_read(obj
, toread
);
470 ret
, err
= old_read(obj
, 16384);
481 getmtable(obj
).close
= function(obj
)
482 local ret
, err
, ret2
, err2
;
483 ret
, err
= old_close(obj
);
484 if underlying_object
then ret2
, err2
= underlying_object
:close(); end
485 if ret
and not ret2
then
491 getmtable(obj
).__index
= function(tab
, name
)
492 local x
= getmtable(obj
)[name
];
496 error("Invalid method " .. name
.. " for BinaryInput");
501 inject_binary_output
= function(obj
, underlying
, name
)
503 local old_four_to_five
= getmtable(obj
).four_to_five
;
504 local old_deflate
= getmtable(obj
).deflate
;
505 local old_text
= getmtable(obj
).text
;
506 local old_close
= getmtable(obj
).close
;
507 local underlying_object
= underlying
;
509 getmtable(obj
).name
= function(obj
)
512 getmtable(obj
).four_to_five
= function(obj
)
514 res
, err
= old_four_to_five(obj
);
518 return inject_binary_output(res
, obj
, "four-to-five<" .. _name
.. ">");
520 getmtable(obj
).deflate
= function(obj
)
522 res
, err
= old_deflate(obj
);
526 return inject_binary_output(res
, obj
, "deflate<" .. _name
.. ">");
528 getmtable(obj
).text
= function(obj
)
530 res
, err
= old_text(obj
);
534 return inject_text_output(res
, obj
, "text<" .. _name
.. ">");
536 getmtable(obj
).close
= function(obj
)
537 local ret
, err
, ret2
, err2
;
538 ret
, err
= old_close(obj
);
539 if underlying_object
then ret2
, err2
= underlying_object
:close(); end
540 if ret
and not ret2
then
546 getmtable(obj
).__index
= function(tab
, name
)
547 local x
= getmtable(obj
)[name
];
551 error("Invalid method " .. name
.. " for BinaryOutput");
556 inject_text_input
= function(obj
, underlying
, name
)
558 local old_close
= getmtable(obj
).close
;
559 local underlying_object
= underlying
;
561 getmtable(obj
).lines
= function(obj
)
562 return function(state
, prevline
)
566 getmtable(obj
).name
= function(obj
)
569 getmtable(obj
).close
= function(obj
)
570 local ret
, err
, ret2
, err2
;
571 ret
, err
= old_close(obj
);
572 if underlying_object
then ret2
, err2
= underlying_object
:close(); end
573 if ret
and not ret2
then
579 getmtable(obj
).__index
= function(tab
, name
)
580 local x
= getmtable(obj
)[name
];
584 error("Invalid method " .. name
.. " for TextInput");
589 inject_text_output
= function(obj
, underlying
, name
)
591 local old_close
= getmtable(obj
).close
;
592 local underlying_object
= underlying
;
594 getmtable(obj
).name
= function(obj
)
597 getmtable(obj
).close
= function(obj
)
598 local ret
, err
, ret2
, err2
;
599 ret
, err
= old_close(obj
);
600 if underlying_object
then ret2
, err2
= underlying_object
:close(); end
601 if ret
and underlying_object
then
607 getmtable(obj
).__index
= function(tab
, name
)
608 local x
= getmtable(obj
)[name
];
612 error("Invalid method " .. name
.. " for TextOutput");
617 inject_archive_input
= function(obj
, name
)
619 local old_member
= getmtable(obj
).member
;
620 local old_member_list
= getmtable(obj
).member_list
;
621 getmtable(obj
).member
= function(obj
, member
)
623 res
, err
= old_member(obj
, member
);
627 return inject_binary_input(res
, nil, _name
.. "[" .. member
.. "]");
629 getmtable(obj
).name
= function(obj
)
632 getmtable(obj
).member_list
= function(obj
)
633 local tab
= old_member_list(obj
);
634 if tab
then table.sort(tab
, jpcrr
.stringlessthan
); end
637 getmtable(obj
).__index
= function(tab
, name
)
638 local x
= getmtable(obj
)[name
];
642 error("Invalid method " .. name
.. " for ArchiveInput");
647 inject_archive_output
= function(obj
, name
)
649 local old_member
= getmtable(obj
).member
;
650 getmtable(obj
).member
= function(obj
, member
)
652 res
, err
= old_member(obj
, member
);
656 return inject_binary_output(res
, nil, _name
.. "[" .. member
.. "]");
658 getmtable(obj
).name
= function(obj
)
661 getmtable(obj
).__index
= function(tab
, name
)
662 local x
= getmtable(obj
)[name
];
666 error("Invalid method " .. name
.. " for ArchiveOutput");
674 local rprint
= print_console_msg
;
675 print_console_msg
= nil;
676 print = function(...)
682 x
= x
.. "\t" .. toString(y
[i
]);
689 print_console_msg
= nil;
693 local stringfind
= string.find
;
694 local randname
= loadmod("org.jpc.luaextensions.DelayedDelete").random_temp_name
;
695 local path
= args
["luapath"] or ".";
696 local toresourcename
= function(resname
)
698 return randname(path
.. "/", "luatemp-");
701 if not stringfind(resname
, "[%d%l%u_%-]") then
702 error("Bad resource name (case 1): " .. resname
);
704 if stringfind(resname
, "^/") then
705 error("Bad resource name (case 2): " .. resname
);
707 if stringfind(resname
, "%.%.") then
708 error("Bad resource name (case 3): " .. resname
);
710 if stringfind(resname
, "\\") then
711 error("Bad resource name (case 4): " .. resname
);
714 return resname
, path
.. "/" .. resname
;
719 local openbinin
= loadmod("org.jpc.luaextensions.BinaryInFile").open
;
720 local openbinout
= loadmod("org.jpc.luaextensions.BinaryOutFile").open
;
721 local openarchin
= loadmod("org.jpc.luaextensions.ArchiveIn").open
;
722 local openarchout
= loadmod("org.jpc.luaextensions.ArchiveOut").open
;
723 local openbinary
= loadmod("org.jpc.luaextensions.BinaryFile").open
;
725 local baseFS
= loadmod("org.jpc.luaextensions.BaseFSOps");
726 local mkdir
= baseFS
.mkdir
;
727 local unlink
= baseFS
.unlink
;
728 local rename = baseFS
.rename;
730 local getmtable
= getmetatable
;
732 loadfile
= function(_script
)
733 local file
, file2
, err
, content
;
735 x
, y
= toresourcename(_script
);
736 file
, err
= openbinin(y
, "r");
738 return nil, "Can't open " .. _script
.. ": " .. err
;
740 file2
, err
= file
:text();
742 return nil, "Can't transform " .. _script
.. ": " .. err
;
747 content
= content
.. line
.. "\n";
752 return loadstring(content
, _script
);
755 io
.open
= function(name
, mode
)
759 _name
, y
= toresourcename(name
);
760 res
, err
= openbinary(y
, mode
);
764 return inject_binary_file(res
, _name
);
767 io
.open_arch_read
= function(name
)
771 _name
, y
= toresourcename(name
);
772 res
, err
= openarchin(y
);
776 return inject_archive_input(res
, _name
);
779 io
.open_arch_write
= function(name
)
783 _name
, y
= toresourcename(name
);
784 res
, err
= openarchout(y
);
788 return inject_archive_output(res
, _name
);
791 io
.open_read
= function(name
)
795 _name
, y
= toresourcename(name
);
796 res
, err
= openbinin(y
);
800 return inject_binary_input(res
, nil, _name
);
803 io
.open_write
= function(name
)
807 _name
, y
= toresourcename(name
);
808 res
, err
= openbinout(y
);
812 return inject_binary_output(res
, nil, _name
);
815 io
.mkdir
= function(name
)
817 _name
, y
= toresourcename(name
);
825 io
.unlink
= function(name
)
827 _name
, y
= toresourcename(name
);
835 io
.rename = function(name1
, name2
)
838 _name
, y
= toresourcename(name1
);
839 _name2
, y2
= toresourcename(name2
);
840 if rename(y
, y2
) then
841 return _name
, _name2
;
849 io
.transform
.text
= function()
855 io
.transform
.four_to_five
= function()
857 return obj
:four_to_five();
861 io
.transform
.inflate
= function()
863 return obj
:inflate();
867 io
.transform
.deflate
= function()
869 return obj
:deflate();
873 io
.dotransform
= function(obj
, ...)
877 for k
, v
in ipairs(todo
) do
888 io
.dotransform2
= function(obj
, err
, ...)
892 return io
.dotransform(obj
, err
, ...);
897 jpcrr
.next_frame
= function(name
)
899 if not jpcrr
.pc_connected() then
900 jpcrr
.wait_pc_attach();
902 if jpcrr
.in_frame_hold() then
905 if jpcrr
.wait_vga() then
912 -- Various stuff built on top of ECI.
913 local invoke
= jpcrr
.invoke
;
914 local invokecall
= jpcrr
.call;
915 local invokesync
= jpcrr
.invoke_synchronous
;
917 jpcrr
.sendevent
= function(...)
918 local arguments
= {...};
920 for k
, v
in ipairs(arguments
) do
921 arguments
[k
] = toString(v
);
923 invokesync("sendevent", arguments
);
926 jpcrr
.save_state
= function(name
)
928 _name
, _fname
= toresourcename(name
);
929 invokesync("state-save", {_fname
});
933 jpcrr
.save_movie
= function(name
)
935 _name
, _fname
= toresourcename(name
);
936 invokesync("movie-save", {_name
});
940 jpcrr
.load_state_normal
= function(name
)
942 _name
, _fname
= toresourcename(name
);
943 invokesync("state-load", {_name
});
947 jpcrr
.load_state_preserve_events
= function(name
)
949 _name
, _fname
= toresourcename(name
);
950 invokesync("state-load-noevents", {_name
});
954 jpcrr
.load_state_movie
= function(name
)
956 _name
, _fname
= toresourcename(name
);
957 invokesync("state-load-movie", {_name
});
961 jpcrr
.assemble
= function()
962 invokesync("pc-assemble");
965 jpcrr
.change_authors
= function()
966 invokesync("change-authors");
969 jpcrr
.ram_dump
= function(name
, binary
)
971 _name
, _fname
= toresourcename(name
);
973 invokesync("ram-dump-binary", {_name
});
975 invokesync("ram-dump-text", {_name
});
980 jpcrr
.hud
.left_gap
= function(f
, g
)
981 invoke("hud-left-gap", {toString(f
), toString(g
)});
984 jpcrr
.hud
.right_gap
= function(f
, g
)
985 invoke("hud-right-gap", {toString(f
), toString(g
)});
988 jpcrr
.hud
.top_gap
= function(f
, g
)
989 invoke("hud-top-gap", {toString(f
), toString(g
)});
992 jpcrr
.hud
.bottom_gap
= function(f
, g
)
993 invoke("hud-bottom-gap", {toString(f
), toString(g
)});
996 jpcrr
.hud
.white_solid_box
= function(f
, x
, y
, w
, h
)
997 invoke("hud-white-solid-box", {toString(f
), toString(x
), toString(y
), toString(w
), toString(h
)});
1000 jpcrr
.hud
.box
= function(f
, x
, y
, w
, h
, t
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
)
1001 invoke("hud-box", {toString(f
), toString(x
), toString(y
), toString(w
), toString(h
),
1002 toString(t
), toString(lr
), toString(lg
), toString(lb
), toString(la
), toString(fr
),
1003 toString(fg
), tostring(fb
), toString(fa
)});
1006 jpcrr
.hud
.circle
= function(f
, x
, y
, r
, t
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
)
1007 invoke("hud-circle", {toString(f
), toString(x
), toString(y
), toString(r
),
1008 toString(t
), toString(lr
), toString(lg
), toString(lb
), toString(la
), toString(fr
),
1009 toString(fg
), tostring(fb
), toString(fa
)});
1012 jpcrr
.hud
.bitmap
= function(f
, x
, y
, bmap
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
)
1013 invoke("hud-bitmap", {toString(f
), toString(x
), toString(y
), bmap
, toString(lr
),
1014 toString(lg
), toString(lb
), toString(la
), toString(fr
), toString(fg
), tostring(fb
),
1018 jpcrr
.hud
.bitmap_binary
= function(f
, x
, y
, bmap
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
)
1019 invoke("hud-bitmap-binary", {toString(f
), toString(x
), toString(y
), bmap
, toString(lr
),
1020 toString(lg
), toString(lb
), toString(la
), toString(fr
), toString(fg
), tostring(fb
),
1024 jpcrr
.set_pccontrol_pos
= function(x
, y
)
1025 invokesync("pccontrol-setwinpos", {toString(x
), toString(y
)});
1028 jpcrr
.set_luaplugin_pos
= function(x
, y
)
1029 invokesync("luaplugin-setwinpos", {toString(x
), toString(y
)});
1032 jpcrr
.set_pcmonitor_pos
= function(x
, y
)
1033 invokesync("pcmonitor-setwinpos", {toString(x
), toString(y
)});
1036 jpcrr
.set_pcstartstoptest_pos
= function(x
, y
)
1037 invokesync("pcstartstoptest-setwinpos", {toString(x
), toString(y
)});
1040 jpcrr
.set_virtualkeyboard_pos
= function(x
, y
)
1041 invokesync("virtualkeyboard-setwinpos", {toString(x
), toString(y
)});
1044 jpcrr
.exit = function()
1045 invokesync("luaplugin-terminate");
1048 jpcrr
.pc_start
= function()
1052 jpcrr
.pc_stop
= function()
1053 invokesync("pc-stop");
1056 jpcrr
.screenshot
= function(include_hud
)
1058 invoke("screenshot-renderbuffer");
1060 invoke("screenshot-vgabuffer");
1065 jpcrr
.vretrace_start_trap
= function(is_on
)
1067 invokesync("trap-vretrace-start-on");
1069 invokesync("trap-vretrace-start-off");
1073 jpcrr
.vretrace_end_trap
= function(is_on
)
1075 invokesync("trap-vretrace-end-on");
1077 invokesync("trap-vretrace-end-off");
1081 jpcrr
.timed_trap
= function(nsecs
)
1083 invokesync("trap-timed", {toString(nsecs
)});
1085 invokesync("trap-timed-disable");
1089 jpcrr
.write_byte
= function(addr
, value
)
1090 invokesync("memory-write", {toString(addr
), toString(value
), "1"});
1093 jpcrr
.write_word
= function(addr
, value
)
1094 invokesync("memory-write", {toString(addr
), toString(value
), "2"});
1097 jpcrr
.write_dword
= function(addr
, value
)
1098 invokesync("memory-write", {toString(addr
), toString(value
), "4"});
1101 jpcrr
.read_byte
= function(addr
)
1102 local t
= {toString(addr
), "1"};
1103 t
= invokecall("memory-read", t
);
1104 return (t
or {})[1];
1107 jpcrr
.read_word
= function(addr
)
1108 local t
= {toString(addr
), "2"};
1109 t
= invokecall("memory-read", t
);
1110 return (t
or {})[1];
1113 jpcrr
.read_dword
= function(addr
)
1114 local t
= {toString(addr
), "4"};
1115 t
= invokecall("memory-read", t
);
1116 return (t
or {})[1];
1119 jpcrr
.read_byte_signed
= function(addr
)
1120 local t
= {toString(addr
), "1"};
1121 t
= invokecall("memory-read", t
);
1122 return bit
.tosigned((t
or {})[1], 7);
1125 jpcrr
.read_word_signed
= function(addr
)
1126 local t
= {toString(addr
), "2"};
1127 t
= invokecall("memory-read", t
);
1128 return bit
.tosigned((t
or {})[1], 15);
1131 jpcrr
.read_dword_signed
= function(addr
)
1132 local t
= {toString(addr
), "4"};
1133 t
= invokecall("memory-read", t
);
1134 return bit
.tosigned((t
or {})[1], 31);
1138 jpcrr
.invoke_synchronous
= nil;
1142 dofile = function(_script
)
1143 local chunk
, err
, indication
1144 chunk
, err
= loadfile(_script
);
1146 error("Kernel: Can't load subscript " .. _script
.. ": " .. err
);
1154 for k
, v
in pairs(args2
) do
1155 if (#k
> 2 and string.byte(k
, 1) == 120 and string.byte(k
, 2) == 45) then
1156 args
[string.sub(k
, 3)] = v
;
1163 loaded
, err
= pcall(function()
1164 chunk
, err
= loadfile(script
);
1170 print("Kernel: Can't load script " .. script
.. ": " .. err
);
1171 invoke("luaplugin-terminate");
1176 indication
, err
= pcall(chunk
);
1177 if not indication
then
1178 print("Kernel: Unprotected error in script: " .. err
);
1179 invoke("luaplugin-terminate");