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
.pluginsaux
;
34 import java
.awt
.event
.ActionListener
;
35 import java
.awt
.event
.MouseListener
;
36 import java
.awt
.event
.ActionEvent
;
37 import java
.awt
.event
.MouseEvent
;
39 import org
.jpc
.pluginsbase
.Plugins
;
40 import org
.jpc
.pluginsbase
.Plugin
;
41 import org
.jpc
.pluginsaux
.HUDRenderer
;
43 import java
.awt
.image
.BufferedImage
;
44 import java
.awt
.image
.DataBufferInt
;
45 import org
.jpc
.emulator
.VGADigitalOut
;
46 import org
.jpc
.emulator
.*;
47 import org
.jpc
.output
.*;
48 import static org
.jpc
.Misc
.errorDialog
;
49 import org
.jpc
.pluginsaux
.PNGSaver
;
55 public class PCMonitorPanel
implements ActionListener
, MouseListener
57 private static final long serialVersionUID
= 6;
58 private OutputStatic outputServer
;
60 private OutputClient outputClient
;
61 private volatile boolean signalCheck
;
62 private BufferedImage buffer
;
64 private int[] renderBuffer
;
65 private int renderBufferW
;
66 private int renderBufferH
;
67 private int[] rawImageData
;
68 private int screenWidth
, screenHeight
;
69 private MonitorPanel monitorPanel
;
70 private Thread monitorThread
;
71 private HUDRenderer renderer
;
72 private PCMonitorPanelEmbedder embedder
;
73 private java
.util
.List
<JMenu
> menusNeeded
;
74 private OutputFrameImage lastFrame
;
76 private volatile boolean clearBackground
;
78 public PCMonitorPanel(PCMonitorPanelEmbedder embedWhere
, OutputStatic serv
)
80 clearBackground
= true;
81 monitorPanel
= new MonitorPanel();
82 monitorPanel
.setDoubleBuffered(false);
83 monitorPanel
.requestFocusInWindow();
85 outputClient
= new OutputClient(serv
);
87 monitorPanel
.setInputMap(JPanel
.WHEN_FOCUSED
, null);
89 embedder
= embedWhere
;
90 renderer
= new HUDRenderer(1);
91 embedder
.notifyRenderer(renderer
);
92 menusNeeded
= new ArrayList
<JMenu
>();
96 menusNeeded
.add(lamp
= new JMenu("Gain"));
98 lampx
= new JMenuItem("1x");
99 lampx
.setActionCommand("LAMP1X");
100 lampx
.addActionListener(this);
103 lampx
= new JMenuItem("2x");
104 lampx
.setActionCommand("LAMP2X");
105 lampx
.addActionListener(this);
108 lampx
= new JMenuItem("4x");
109 lampx
.setActionCommand("LAMP4X");
110 lampx
.addActionListener(this);
113 lampx
= new JMenuItem("8x");
114 lampx
.setActionCommand("LAMP8X");
115 lampx
.addActionListener(this);
118 lampx
= new JMenuItem("16x");
119 lampx
.setActionCommand("LAMP16X");
120 lampx
.addActionListener(this);
123 lampx
= new JMenuItem("32x");
124 lampx
.setActionCommand("LAMP32X");
125 lampx
.addActionListener(this);
128 menusNeeded
.add(lamp
= new JMenu("Screenshot"));
130 lampx
= new JMenuItem("VGA output buffer");
131 lampx
.setActionCommand("SSVGAOUT");
132 lampx
.addActionListener(this);
135 lampx
= new JMenuItem("render buffer");
136 lampx
.setActionCommand("SSRENDER");
137 lampx
.addActionListener(this);
140 monitorPanel
.addMouseListener(this);
141 resizeDisplay(480, 360, true);
144 public void eci_screenshot_vgabuffer()
149 public void eci_screenshot_renderbuffer()
154 public java
.util
.List
<JMenu
> getMenusNeeded()
159 public JPanel
getMonitorPanel()
164 public void startThread()
166 (new Thread(new Runnable() { public void run() { main(); }}, "Monitor Panel Thread")).start();
169 public void setPC(PC _pc
)
176 monitorThread
= Thread
.currentThread();
177 while (true) //JVM will kill us.
180 if(outputClient
.aquire()) {
181 OutputFrame f
= outputServer
.lastFrame(OutputFrameImage
.class);
183 lastFrame
= (OutputFrameImage
)f
;
185 outputClient
.releaseWaitAll();
188 int w
= lastFrame
.getWidth();
189 int h
= lastFrame
.getHeight();
190 embedder
.notifyFrameReceived(w
, h
);
191 int[] buffer
= lastFrame
.getImageData();
192 renderer
.setBackground(buffer
, w
, h
);
193 outputClient
.releaseWaitAll();
194 w
= renderBufferW
= renderer
.getRenderWidth();
195 h
= renderBufferH
= renderer
.getRenderHeight();
196 renderBuffer
= renderer
.getFinishedAndReset();
197 if(w
> 0 && h
> 0 && (w
!= screenWidth
|| h
!= screenHeight
)) {
198 resizeDisplay(w
, h
, false);
199 embedder
.notifySizeChange(w
, h
);
201 if(renderBuffer
== null)
204 for(int y
= 0; y
< h
; y
++) {
207 System
.arraycopy(renderBuffer
, offset
, rawImageData
, offset
, w
);
210 monitorPanel
.repaint(0, 0, w
, h
);
216 public void resizeDisplay(int width
, int height
, boolean repaint
)
218 monitorPanel
.setPreferredSize(new Dimension(width
, height
));
219 monitorPanel
.setMaximumSize(new Dimension(width
, height
));
220 monitorPanel
.setMinimumSize(new Dimension(width
, height
));
222 if(width
> 0 && height
> 0) {
223 buffer
= new BufferedImage(width
, height
, BufferedImage
.TYPE_INT_RGB
);
224 buffer
.setAccelerationPriority(1);
225 DataBufferInt buf
= (DataBufferInt
) buffer
.getRaster().getDataBuffer();
226 rawImageData
= buf
.getData();
229 screenHeight
= height
;
230 clearBackground
= true;
231 monitorPanel
.revalidate();
233 monitorPanel
.repaint(0, 0, screenWidth
, screenHeight
);
236 public void actionPerformed(ActionEvent e
)
238 String command
= e
.getActionCommand();
241 if(command
.equals("LAMP1X"))
242 renderer
.setLightAmplification(1);
243 if(command
.equals("LAMP2X"))
244 renderer
.setLightAmplification(2);
245 if(command
.equals("LAMP4X"))
246 renderer
.setLightAmplification(4);
247 if(command
.equals("LAMP8X"))
248 renderer
.setLightAmplification(8);
249 if(command
.equals("LAMP16X"))
250 renderer
.setLightAmplification(16);
251 if(command
.equals("LAMP32X"))
252 renderer
.setLightAmplification(32);
253 if(command
.equals("SSVGAOUT"))
255 if(command
.equals("SSRENDER"))
259 private void screenShot(boolean asRendered
)
268 buffer
= renderBuffer
;
270 if(lastFrame
!= null) {
271 w
= lastFrame
.getWidth();
272 h
= lastFrame
.getHeight();
273 buffer
= lastFrame
.getImageData();
274 if(w
* h
> buffer
.length
) {
275 System
.err
.println("Error: Can't get stable VGA output buffer.");
280 if(buffer
== null || w
== 0 || h
== 0) {
281 System
.err
.println("Error: No image to screenshot.");
286 String name
= "Screenshot-" + System
.currentTimeMillis() + "-" + (ssSeq
++) + ".png";
288 DataOutputStream out
= new DataOutputStream(new FileOutputStream(name
));
289 PNGSaver
.savePNG(out
, buffer
, w
, h
);
291 } catch(Exception e
) {
292 errorDialog(e
, "Can't save screenshot", null, "Dismiss");
294 System
.err
.println("Informative: Screenshot '" + name
+ "' saved.");
297 public class MonitorPanel
extends JPanel
299 private static final long serialVersionUID
= 9;
300 public void update(Graphics g
)
305 public void paint(Graphics g
)
308 if(screenHeight
> 0 && screenWidth
> 0) {
312 Dimension s1
= getSize();
318 g
.setColor(Color
.white
);
319 Dimension s1
= getSize();
322 g
.fillRect(s2w
, 0, s1
.width
- s2w
, s1
.height
);
324 g
.fillRect(0, s2h
, s1
.width
, s1
.height
- s2h
);
325 clearBackground
= false;
327 g
.drawImage(buffer
, 0, 0, null);
328 Dimension s
= getSize();
329 g
.setColor(getBackground());
330 g
.fillRect(s2w
, 0, s
.width
- s2w
, s2h
);
331 g
.fillRect(0, s2h
, s
.width
, s
.height
- s2h
);
335 private int getButtonNumber(MouseEvent e
)
337 int button
= e
.getButton();
338 if(button
== MouseEvent
.BUTTON1
)
340 else if(button
== MouseEvent
.BUTTON2
)
342 else if(button
== MouseEvent
.BUTTON3
)
347 public void mouseClicked(MouseEvent e
)
349 int button
= getButtonNumber(e
);
352 embedder
.sendMessage("MouseClicked " + button
+ " " + x
+ " " + y
);
355 public void mouseEntered(MouseEvent e
)
359 public void mouseExited(MouseEvent e
)
363 public void mousePressed(MouseEvent e
)
365 int button
= getButtonNumber(e
);
368 embedder
.sendMessage("MousePressed " + button
+ " " + x
+ " " + y
);
371 public void mouseReleased(MouseEvent e
)
373 int button
= getButtonNumber(e
);
376 embedder
.sendMessage("MouseReleased " + button
+ " " + x
+ " " + y
);