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
29 package org
.jpc
.pluginsaux
;
33 public class HUDRenderer
35 int[] backgroundBuffer
;
36 int elementsAllocated
;
39 volatile int lightAmp
;
42 volatile int gapBottom
;
43 volatile int gapRight
;
44 List
<RenderObject
> renderObjects
;
46 private abstract class RenderObject
48 abstract void render(int[] buffer
, int w
, int h
);
53 renderObjects
= new LinkedList
<RenderObject
>();
57 public synchronized void setBackground(int[] bg
, int w
, int h
)
59 if(elementsAllocated
< w
* h
) {
60 backgroundBuffer
= new int[w
* h
];
61 elementsAllocated
= w
* h
;
64 System
.arraycopy(bg
, 0, backgroundBuffer
, 0, w
* h
);
69 public synchronized int getRenderWidth()
71 return gapLeft
+ backgroundWidth
+ gapRight
;
74 public synchronized int getRenderHeight()
76 return gapTop
+ backgroundHeight
+ gapBottom
;
79 public synchronized void setLeftGap(int gap
)
87 public synchronized void setTopGap(int gap
)
95 public synchronized void setRightGap(int gap
)
103 public synchronized void setBottomGap(int gap
)
111 public synchronized void setLightAmplification(int factor
)
116 public synchronized int[] getFinishedAndReset()
119 int w
= getRenderWidth();
120 int h
= getRenderHeight();
122 ret
= new int[w
* h
];
125 for(int y
= 0; y
< backgroundHeight
; y
++)
126 System
.arraycopy(backgroundBuffer
, y
* backgroundWidth
, ret
, (y
+ gapTop
) * w
+ gapLeft
,
129 for(int y
= 0; y
< backgroundHeight
; y
++)
130 for(int x
= 0; x
< backgroundWidth
; x
++)
131 ret
[(y
+ gapTop
) * w
+ gapLeft
+ x
] = backgroundBuffer
[y
* backgroundWidth
+ x
] * lightAmp
;
134 for(RenderObject obj
: renderObjects
)
136 obj
.render(ret
, w
, h
);
137 renderObjects
.clear();
139 gapLeft
= gapRight
= gapTop
= gapBottom
= 0;
143 private class WhiteSolidBox
extends RenderObject
149 WhiteSolidBox(int _x
, int _y
, int _w
, int _h
)
157 void render(int[] buffer
, int bw
, int bh
)
159 for(int j
= y
; j
< y
+ h
; j
++) {
162 for(int i
= x
; i
< x
+ w
; i
++) {
165 buffer
[j
* bw
+ i
] = 0xFFFFFF;
171 public synchronized void whiteSolidBox(int x
, int y
, int w
, int h
)
173 renderObjects
.add(new WhiteSolidBox(x
, y
, w
, h
));
176 private class Box
extends RenderObject
191 Box(int _x
, int _y
, int _w
, int _h
, int _thick
, int lr
, int lg
, int lb
, int la
, int fr
, int fg
, int fb
,
209 void render(int[] buffer
, int bw
, int bh
)
211 for(int j
= y
; j
< y
+ h
&& j
< bh
; j
++) {
214 for(int i
= x
; i
< x
+ w
&& i
< bw
; i
++) {
224 if(x
+ w
- i
- 1 < dist
)
225 dist
= x
+ w
- i
- 1;
226 if(y
+ h
- j
- 1 < dist
)
227 dist
= y
+ h
- j
- 1;
241 } else if(useA
== 255) {
242 buffer
[j
* bw
+ i
] = (useR
<< 16) | (useG
<< 8) | useB
;
244 int oldpx
= buffer
[j
* bw
+ i
];
245 float oldR
= (oldpx
>>> 16) & 0xFF;
246 float oldG
= (oldpx
>>> 8) & 0xFF;
247 float oldB
= oldpx
& 0xFF;
248 float fA
= (float)useA
/ 255;
249 useR
= (int)(useR
* fA
+ oldR
* (1 - fA
));
250 useG
= (int)(useG
* fA
+ oldG
* (1 - fA
));
251 useB
= (int)(useB
* fA
+ oldB
* (1 - fA
));
252 buffer
[j
* bw
+ i
] = (useR
<< 16) | (useG
<< 8) | useB
;
259 public synchronized void box(int _x
, int _y
, int _w
, int _h
, int _thick
, int lr
, int lg
, int lb
, int la
, int fr
,
260 int fg
, int fb
, int fa
)
262 renderObjects
.add(new Box(_x
, _y
, _w
, _h
, _thick
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
));
265 private class Circle
extends RenderObject
280 Circle(int _x
, int _y
, int _r
, int _thick
, int lr
, int lg
, int lb
, int la
, int fr
, int fg
, int fb
,
286 r2outer
= (long)_r
* _r
;
290 r2inner
= (long)(_r
- _thick
) * (_r
- _thick
);
301 void render(int[] buffer
, int bw
, int bh
)
303 for(int j
= y
- r
; j
< y
+ r
&& j
< bh
; j
++) {
306 for(int i
= x
- r
; i
< x
+ r
&& i
< bw
; i
++) {
315 long d
= ox
* ox
+ oy
* oy
;
331 } else if(useA
== 255) {
332 buffer
[j
* bw
+ i
] = (useR
<< 16) | (useG
<< 8) | useB
;
334 int oldpx
= buffer
[j
* bw
+ i
];
335 float oldR
= (oldpx
>>> 16) & 0xFF;
336 float oldG
= (oldpx
>>> 8) & 0xFF;
337 float oldB
= oldpx
& 0xFF;
338 float fA
= (float)useA
/ 255;
339 useR
= (int)(useR
* fA
+ oldR
* (1 - fA
));
340 useG
= (int)(useG
* fA
+ oldG
* (1 - fA
));
341 useB
= (int)(useB
* fA
+ oldB
* (1 - fA
));
342 buffer
[j
* bw
+ i
] = (useR
<< 16) | (useG
<< 8) | useB
;
349 public synchronized void circle(int _x
, int _y
, int _r
, int _thick
, int lr
, int lg
, int lb
, int la
, int fr
,
350 int fg
, int fb
, int fa
)
352 renderObjects
.add(new Circle(_x
, _y
, _r
, _thick
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
));
355 private class Bitmap
extends RenderObject
357 private static final int PIXELS_PER_ELEMENT
= 31;
373 Bitmap(int _x
, int _y
, String bmap
, int lr
, int lg
, int lb
, int la
, int fr
, int fg
, int fb
,
374 int fa
, boolean dummy
)
390 w
= bmap
.charAt(i
++);
392 w
= (w
& 0x7F) | (bmap
.charAt(i
++) << 7);
393 stride
= (w
+ PIXELS_PER_ELEMENT
- 1) / PIXELS_PER_ELEMENT
;
394 int rawbytes
= 4 * (w
/ PIXELS_PER_ELEMENT
);
395 rawbytes
+= ((w
% PIXELS_PER_ELEMENT
) + 7) / 8;
396 h
= (bmap
.length() - i
) / rawbytes
;
397 bitmapData
= new int[h
* stride
+ 2];
398 for(int j
= 0; j
< h
; j
++)
399 for(int k
= 0; k
< rawbytes
; k
++)
400 bitmapData
[j
* stride
+ k
/ 4] |= ((int)bmap
.charAt(i
++) << (8 * (k
% 4)));
401 } catch(Exception e
) {
402 System
.err
.println("Bitmap: Failed to parse bitmap: " + e
.getMessage());
407 Bitmap(int _x
, int _y
, String bmap
, int lr
, int lg
, int lb
, int la
, int fr
, int fg
, int fb
,
422 boolean newLine
= true;
423 for(int i
= 0; i
< bmap
.length(); i
++) {
424 char ch
= bmap
.charAt(i
);
443 stride
= (w
+ PIXELS_PER_ELEMENT
- 1) / PIXELS_PER_ELEMENT
;
444 bitmapData
= new int[h
* stride
+ 2];
448 for(int i
= 0; i
< bmap
.length(); i
++) {
449 char ch
= bmap
.charAt(i
);
464 bitmapData
[cy
* stride
+ cx
/ PIXELS_PER_ELEMENT
] |=
465 (1 << (cx
% PIXELS_PER_ELEMENT
));
473 void render(int[] buffer
, int bw
, int bh
)
475 if(bitmapData
== null)
478 int pixel
= bitmapData
[counter
];
479 int pixelModulus
= 0;
480 for(int j
= y
; j
< y
+ h
&& j
< bh
; j
++) {
481 for(int i
= x
; i
< x
+ w
; i
++) {
487 if(((pixel
>> pixelModulus
) & 1) != 0) {
500 } else if(useA
== 255) {
501 if(j
>= 0 && i
>= 0 && i
< bw
)
502 buffer
[j
* bw
+ i
] = (useR
<< 16) | (useG
<< 8) | useB
;
504 if(j
>= 0 && i
>= 0 && i
< bw
) {
505 int oldpx
= buffer
[j
* bw
+ i
];
506 float oldR
= (oldpx
>>> 16) & 0xFF;
507 float oldG
= (oldpx
>>> 8) & 0xFF;
508 float oldB
= oldpx
& 0xFF;
509 float fA
= (float)useA
/ 255;
510 useR
= (int)(useR
* fA
+ oldR
* (1 - fA
));
511 useG
= (int)(useG
* fA
+ oldG
* (1 - fA
));
512 useB
= (int)(useB
* fA
+ oldB
* (1 - fA
));
513 buffer
[j
* bw
+ i
] = (useR
<< 16) | (useG
<< 8) | useB
;
517 if(pixelModulus
== PIXELS_PER_ELEMENT
) {
518 pixel
= bitmapData
[++counter
];
522 if(pixelModulus
> 0) {
523 pixel
= bitmapData
[++counter
];
531 public synchronized void bitmap(int _x
, int _y
, String bmap
, int lr
, int lg
, int lb
, int la
, int fr
,
532 int fg
, int fb
, int fa
)
534 renderObjects
.add(new Bitmap(_x
, _y
, bmap
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
));
537 public synchronized void bitmapBinary(int _x
, int _y
, String bmap
, int lr
, int lg
, int lb
, int la
, int fr
,
538 int fg
, int fb
, int fa
)
540 renderObjects
.add(new Bitmap(_x
, _y
, bmap
, lr
, lg
, lb
, la
, fr
, fg
, fb
, fa
, true));