Add ability for Lua to query movie length, rerecord count and headers
[jpcrr.git] / org / jpc / luaextensions / Base.java
blob2c641052263bbdeb8915a1ccc909e1e26507bc96
1 /*
2 JPC-RR: A x86 PC Hardware Emulator
3 Release 1
5 Copyright (C) 2007-2009 Isis Innovation Limited
6 Copyright (C) 2009-2010 H. Ilari Liusvaara
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as published by
10 the Free Software Foundation.
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.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 Based on JPC x86 PC Hardware emulator,
22 A project from the Physics Dept, The University of Oxford
24 Details about original JPC can be found at:
26 www-jpc.physics.ox.ac.uk
30 package org.jpc.luaextensions;
32 import mnj.lua.*;
34 import org.jpc.emulator.Clock;
35 import org.jpc.emulator.PC;
36 import org.jpc.emulator.EventRecorder;
37 import org.jpc.plugins.LuaPlugin;
39 //Locking this class is used for preventing termination and when terminating.
40 public class Base extends LuaPlugin.LuaResource
42 public void destroy()
46 private Base(LuaPlugin plugin)
48 super(plugin);
51 private static int intLuaCBInvoke(Lua l, boolean sync, LuaPlugin plugin)
53 LuaTable args = null;
54 String[] _args = null;
55 int elements = 0;
56 if(l.type(1) != Lua.TSTRING) {
57 l.error("Unexpected types to invoke");
58 return 0;
61 String cmd = l.value(1).toString();
62 if(l.type(2) == Lua.TNONE || l.type(2) == Lua.TNIL) {
63 ///Nothing.
64 } else if(l.type(2) == Lua.TTABLE) {
65 args = (LuaTable)l.value(2);
66 elements = Lua.objLen(args);
67 _args = new String[elements];
68 for(int i = 0; i < elements; i++) {
69 _args[i] = l.getTable(args, new Double(i + 1)).toString();
70 if(_args[i] == null)
71 _args[i] = "";
73 } else {
74 l.error("Unexpected types to invoke");
75 return 0;
78 plugin.callInvokeCommand(cmd, _args, sync);
79 return 0;
82 public static int luaCB_call(Lua l, LuaPlugin plugin)
84 LuaTable args = null;
85 String[] _args = null;
86 int elements = 0;
87 if(l.type(1) != Lua.TSTRING) {
88 l.error("Unexpected types to invoke");
89 return 0;
92 String cmd = l.value(1).toString();
93 if(l.type(2) == Lua.TNONE || l.type(2) == Lua.TNIL) {
94 ///Nothing.
95 } else if(l.type(2) == Lua.TTABLE) {
96 args = (LuaTable)l.value(2);
97 elements = Lua.objLen(args);
98 _args = new String[elements];
99 for(int i = 0; i < elements; i++) {
100 _args[i] = l.getTable(args, new Double(i + 1)).toString();
101 if(_args[i] == null)
102 _args[i] = "";
104 } else {
105 l.error("Unexpected types to invoke");
106 return 0;
109 Object[] ret = plugin.callCommand(cmd, _args);
110 if(ret == null) {
111 //System.err.println("No return values");
112 return 0;
114 int i = 1;
115 //System.err.println("" + ret.length + " return value(s)");
116 LuaTable tab = l.newTable();
117 for(Object retE : ret) {
118 if(retE == null)
119 i++;
120 else if(retE instanceof Boolean)
121 l.setTable(tab, new Double(i++), retE);
122 else if(retE instanceof Integer)
123 l.setTable(tab, new Double(i++), new Double(((Integer)retE).intValue()));
124 else if(retE instanceof Long)
125 l.setTable(tab, new Double(i++), new Double(((Long)retE).longValue()));
126 else if(retE instanceof String)
127 l.setTable(tab, new Double(i++), retE);
128 else
129 l.setTable(tab, new Double(i++), "<unconvertable object>");
131 l.push(tab);
132 return 1;
135 public static int luaCB_invoke(Lua l, LuaPlugin plugin)
137 return intLuaCBInvoke(l, false, plugin);
140 public static int luaCB_invoke_synchronous(Lua l, LuaPlugin plugin)
142 return intLuaCBInvoke(l, true, plugin);
145 public static int luaCB_wait_vga(Lua l, LuaPlugin plugin)
147 plugin.doLockVGA();
148 l.pushBoolean(plugin.getOwnsVGALock());
149 return 1;
152 public static int luaCB_release_vga(Lua l, LuaPlugin plugin)
154 plugin.doReleaseVGA();
155 return 0;
158 public static int luaCB_vga_resolution(Lua l, LuaPlugin plugin)
160 l.push(new Double(plugin.getXResolution()));
161 l.push(new Double(plugin.getYResolution()));
162 return 2;
165 public static int luaCB_pc_running(Lua l, LuaPlugin plugin)
167 l.pushBoolean(plugin.getPCRunning());
168 return 1;
171 public static int luaCB_clock_time(Lua l, LuaPlugin plugin)
173 Clock clk = (Clock)plugin.getComponent(Clock.class);
174 if(clk != null)
175 l.push(new Double(clk.getTime()));
176 else
177 l.pushNil();
178 return 1;
181 public static int luaCB_wait_pc_attach(Lua l, LuaPlugin plugin)
183 plugin.waitPCAttach();
184 return 0;
187 public static int luaCB_wait_message(Lua l, LuaPlugin plugin)
189 String msg = plugin.waitMessage();
190 if(msg != null)
191 l.push(msg);
192 else
193 l.pushNil();
194 return 1;
197 public static int luaCB_wait_pc_stop(Lua l, LuaPlugin plugin)
199 l.pushBoolean(plugin.waitPCStop());
200 return 1;
203 public static int luaCB_poll_message(Lua l, LuaPlugin plugin)
205 String msg = plugin.pollMessage();
206 if(msg != null)
207 l.push(msg);
208 else
209 l.pushNil();
210 return 1;
213 public static int luaCB_in_frame_hold(Lua l, LuaPlugin plugin)
215 l.pushBoolean(plugin.getOwnsVGALock());
216 return 1;
219 public static int luaCB_pc_connected(Lua l, LuaPlugin plugin)
221 l.pushBoolean(plugin.getPCConnected());
222 return 1;
225 public static int luaCB_stringlessthan(Lua l, LuaPlugin plugin)
227 int ret = 0;
228 String x = l.value(1).toString();
229 String y = l.value(2).toString();
230 int xlen = x.length();
231 int ylen = y.length();
232 for(int i = 0; i < xlen && i < ylen; i++) {
233 int xcp = x.charAt(i);
234 int ycp = y.charAt(i);
235 boolean xs = (xcp >= 0xD800 && xcp <= 0xDFFF);
236 boolean ys = (ycp >= 0xD800 && ycp <= 0xDFFF);
237 if(!xs && ys)
238 ret = (ret == 0) ? 1 : ret;
239 else if(xs && !ys)
240 ret = (ret == 0) ? -1 : ret;
241 else if(xcp < ycp)
242 ret = (ret == 0) ? 1 : ret;
243 else if(xcp > ycp)
244 ret = (ret == 0) ? -1 : ret;
246 if(ret == 0 && xlen < ylen)
247 ret = 1;
248 if(ret == 0 && xlen > ylen)
249 ret = -1;
251 l.pushBoolean(ret == 1);
252 return 1;
255 public static int luaCB_movie_length(Lua l, LuaPlugin plugin)
257 PC.ResetButton brb = ((PC.ResetButton)plugin.getComponent(PC.ResetButton.class));
258 if(brb == null) {
259 l.pushNil();
260 return 1;
262 EventRecorder rec = brb.getRecorder();
263 long lastTime = rec.getLastEventTime();
264 long attachTime = rec.getAttachTime();
265 long time = 0;
266 if(attachTime < lastTime)
267 time = lastTime - attachTime;
268 l.push(new Double(time));
269 return 1;
272 public static int luaCB_movie_rerecords(Lua l, LuaPlugin plugin)
274 PC.ResetButton brb = ((PC.ResetButton)plugin.getComponent(PC.ResetButton.class));
275 if(brb == null) {
276 l.pushNil();
277 return 1;
279 EventRecorder rec = brb.getRecorder();
280 l.push(new Double(rec.getRerecordCount()));
281 return 1;
284 public static int luaCB_movie_headers(Lua l, LuaPlugin plugin)
286 PC.ResetButton brb = ((PC.ResetButton)plugin.getComponent(PC.ResetButton.class));
287 if(brb == null) {
288 l.pushNil();
289 return 1;
291 EventRecorder rec = brb.getRecorder();
292 String[][] headers = rec.getHeaders();
293 LuaTable ret = l.newTable();
294 if(headers != null)
295 for(int i = 0; i < headers.length; i++) {
296 LuaTable tab = l.newTable();
297 int j = 1;
298 if(headers[i] != null)
299 for(String p : headers[i])
300 l.setTable(tab, new Double(j++), p);
301 l.setTable(ret, new Double(i + 1), tab);
303 l.push(ret);
304 return 1;