2 JPC-RR: A x86 PC Hardware Emulator
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
.plugins
;
34 import java
.util
.zip
.*;
35 import org
.jpc
.emulator
.*;
36 import org
.jpc
.output
.*;
37 import org
.jpc
.pluginsaux
.HUDRenderer
;
38 import org
.jpc
.pluginsbase
.Plugins
;
39 import org
.jpc
.pluginsbase
.Plugin
;
40 import static org
.jpc
.Misc
.errorDialog
;
41 import static org
.jpc
.Misc
.parseStringToComponents
;
43 public class RAWDumper
implements Plugin
45 class DumpFrameFilter
implements OutputStatic
.FrameFilter
47 OutputFrameImage lastVideoFrame
;
52 public DumpFrameFilter()
56 public OutputFrame
doFilter(OutputFrame f
, short channel
)
59 lastTimestamp
= f
.getTime();
60 if(!(f
instanceof OutputFrameImage
))
62 //This is video frame. Save and cancel it.
63 lastVideoFrame
= (OutputFrameImage
)f
;
64 videoChannel
= channel
;
70 private volatile OutputClient videoOut
;
71 private volatile OutputStatic connector
;
72 private volatile boolean shuttingDown
;
73 private volatile boolean shutDown
;
74 private volatile boolean pcRunStatus
;
76 private Thread worker
;
77 private OutputStream rawOutputStream
;
78 private DumpFrameFilter filter
;
79 private HUDRenderer renderer
;
81 public RAWDumper(Plugins pluginManager
, String args
) throws IOException
83 Map
<String
, String
> params
= parseStringToComponents(args
);
84 String rawOutput
= params
.get("rawoutput");
86 throw new IOException("Raw output setting (rawoutput) required for PNGDumper");
87 if(rawOutput
!= null) {
89 rawOutputStream
= new FileOutputStream(rawOutput
);
90 } catch(Exception e
) {
91 System
.err
.println("Error: Failed to open raw output file.");
92 throw new IOException("Can't open dumpfile '" + rawOutput
+ "':" + e
.getMessage());
98 connector
= pluginManager
.getOutputConnector();
99 videoOut
= new OutputClient(connector
);
100 filter
= new DumpFrameFilter();
101 renderer
= new HUDRenderer();
105 public void eci_hud_left_gap(Integer flags
, Integer gap
)
107 if((flags
.intValue() & 2) != 0)
108 renderer
.setLeftGap(gap
);
111 public void eci_hud_top_gap(Integer flags
, Integer gap
)
113 if((flags
.intValue() & 2) != 0)
114 renderer
.setTopGap(gap
);
117 public void eci_hud_right_gap(Integer flags
, Integer gap
)
119 if((flags
.intValue() & 2) != 0)
120 renderer
.setRightGap(gap
);
123 public void eci_hud_bottom_gap(Integer flags
, Integer gap
)
125 if((flags
.intValue() & 2) != 0)
126 renderer
.setBottomGap(gap
);
129 public void eci_hud_white_solid_box(Integer flags
, Integer x
, Integer y
, Integer w
, Integer h
)
131 if((flags
.intValue() & 2) != 0)
132 renderer
.whiteSolidBox(x
.intValue(), y
.intValue(), w
.intValue(), h
.intValue());
135 public void eci_hud_box(Integer flags
, Integer x
, Integer y
, Integer w
, Integer h
, Integer thick
, Integer lr
,
136 Integer lg
, Integer lb
, Integer la
, Integer fr
, Integer fg
, Integer fb
, Integer fa
)
138 if((flags
.intValue() & 2) != 0)
139 renderer
.box(x
, y
, w
, h
, thick
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
);
142 public void eci_hud_circle(Integer flags
, Integer x
, Integer y
, Integer r
, Integer thick
, Integer lr
,
143 Integer lg
, Integer lb
, Integer la
, Integer fr
, Integer fg
, Integer fb
, Integer fa
)
145 if((flags
.intValue() & 2) != 0)
146 renderer
.circle(x
, y
, r
, thick
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
);
149 public void eci_hud_bitmap(Integer flags
, Integer x
, Integer y
, String bmap
, Integer lr
,
150 Integer lg
, Integer lb
, Integer la
, Integer fr
, Integer fg
, Integer fb
, Integer fa
)
152 if((flags
.intValue() & 2) != 0)
153 renderer
.bitmap(x
, y
, bmap
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
);
156 public void eci_hud_bitmap_binary(Integer flags
, Integer x
, Integer y
, String bmap
, Integer lr
,
157 Integer lg
, Integer lb
, Integer la
, Integer fr
, Integer fg
, Integer fb
, Integer fa
)
159 if((flags
.intValue() & 2) != 0)
160 renderer
.bitmapBinary(x
, y
, bmap
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
);
163 public void eci_hud_vga_chargen(Integer flags
, Integer x
, Integer y
, String text
, Integer lr
,
164 Integer lg
, Integer lb
, Integer la
, Integer fr
, Integer fg
, Integer fb
, Integer fa
)
166 if((flags
.intValue() & 2) != 0)
167 renderer
.vgaChargen(x
, y
, text
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
, pc
);
170 public void eci_hud_set_vga_chargen(Integer flags
, Integer addr
)
172 if((flags
.intValue() & 2) != 0)
173 renderer
.setVGAChargen(addr
);
176 public boolean systemShutdown()
179 return false; //Don't shut down until after PC.
189 } catch(Exception e
) {
196 public void reconnect(PC _pc
)
202 public void pcStarting()
207 public void pcStopping()
215 worker
= Thread
.currentThread();
216 boolean first
= true;
217 while(!shuttingDown
) {
221 if(videoOut
.aquire()) {
226 rawOutputStream
.write(connector
.makeChannelTable());
228 base
= connector
.writeFrames(rawOutputStream
, filter
);
229 OutputFrameImage lastFrame
= filter
.lastVideoFrame
;
230 if(lastFrame
== null) {
231 videoOut
.releaseWaitAll();
234 int w
= lastFrame
.getWidth();
235 int h
= lastFrame
.getHeight();
236 renderer
.setBackground(lastFrame
.getImageData(), w
, h
);
237 videoOut
.releaseWaitAll();
238 w
= renderer
.getRenderWidth();
239 h
= renderer
.getRenderHeight();
240 int[] saveBuffer
= renderer
.getFinishedAndReset();
242 long time
= filter
.lastTimestamp
;
245 lastFrame
= new OutputFrameImage(time
, (short)w
, (short)h
, saveBuffer
);
246 rawOutputStream
.write(lastFrame
.dump(filter
.videoChannel
, base
));
247 System
.err
.println("Informational: Saved frame #" + frame
+ ": " + w
+ "x" + h
+ " <" +
249 } catch(IOException e
) {
250 System
.err
.println("Warning: Failed to save screenshot image!");
251 errorDialog(e
, "Failed to save screenshot", null, "Dismiss");
260 connector
.writeFrames(rawOutputStream
, null);
261 } catch(IOException e
) {
262 System
.err
.println("Warning: Failed to close video output stream!");
263 errorDialog(e
, "Failed to close video output", null, "Dismiss");
269 if(rawOutputStream
!= null) {
271 rawOutputStream
.flush();
272 rawOutputStream
.close();
273 } catch(IOException e
) {
274 System
.err
.println("Warning: Failed to close video output stream!");
275 errorDialog(e
, "Failed to close video output", null, "Dismiss");