Created
April 17, 2012 04:21
-
-
Save namuol/2403425 to your computer and use it in GitHub Desktop.
Decompiled code from http://dcpu.com/highnerd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package computer; | |
// Referenced classes of package computer: | |
// KeyMapping | |
public class AWTKeyMapping extends KeyMapping | |
{ | |
public AWTKeyMapping() | |
{ | |
map(38, 128); | |
map(40, 129); | |
map(37, 130); | |
map(39, 131); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package computer; | |
import java.awt.*; | |
import java.awt.event.KeyEvent; | |
import java.awt.event.KeyListener; | |
import java.awt.image.*; | |
import java.io.*; | |
import javax.swing.JFrame; | |
// Referenced classes of package computer: | |
// VirtualMonitor, VirtualKeyboard, AWTKeyMapping | |
public class DCPU { | |
public DCPU() { | |
ram = new char[0x10000]; | |
registers = new char[8]; | |
} | |
public int getAddr(int type) { | |
if (type >= 32) | |
return 0x20000 | type & 0x1f; | |
switch (type & 0xf8) { | |
case 0: // '\0' | |
return 0x10000 + (type & 7); | |
case 8: // '\b' | |
return registers[type & 7]; | |
case 16: // '\020' | |
cycles++; | |
return ram[pc++] + registers[type & 7] & 0xffff; | |
case 24: // '\030' | |
switch (type & 7) { | |
case 0: // '\0' | |
return sp++ & 0xffff; | |
case 1: // '\001' | |
return sp & 0xffff; | |
case 2: // '\002' | |
return --sp & 0xffff; | |
case 3: // '\003' | |
return 0x10008; | |
case 4: // '\004' | |
return 0x10009; | |
case 5: // '\005' | |
return 0x10010; | |
case 6: // '\006' | |
cycles++; | |
return ram[pc++]; | |
} | |
cycles++; | |
return 0x20000 | ram[pc++]; | |
} | |
throw new IllegalStateException((new StringBuilder( | |
"Illegal value type ")).append(type) | |
.append("! How did you manage that!?").toString()); | |
} | |
public char get(int addr) { | |
if (addr < 0x10000) | |
return ram[addr & 0xffff]; | |
if (addr < 0x10008) | |
return registers[addr & 7]; | |
if (addr >= 0x20000) | |
return (char) addr; | |
if (addr == 0x10008) | |
return sp; | |
if (addr == 0x10009) | |
return pc; | |
if (addr == 0x10010) | |
return o; | |
else | |
throw new IllegalStateException((new StringBuilder( | |
"Illegal address ")).append(Integer.toHexString(addr)) | |
.append("! How did you manage that!?").toString()); | |
} | |
public void set(int addr, char val) { | |
if (addr < 0x10000) | |
ram[addr & 0xffff] = val; | |
else if (addr < 0x10008) | |
registers[addr & 7] = val; | |
else if (addr < 0x20000) | |
if (addr == 0x10008) | |
sp = val; | |
else if (addr == 0x10009) | |
pc = val; | |
else if (addr == 0x10010) | |
o = val; | |
else | |
throw new IllegalStateException((new StringBuilder( | |
"Illegal address ")).append(Integer.toHexString(addr)) | |
.append("! How did you manage that!?").toString()); | |
} | |
public static int getInstructionLength(char opcode) { | |
int len = 1; | |
int cmd = opcode & 0xf; | |
if (cmd == 0) { | |
cmd = opcode >> 4 & 0xf; | |
if (cmd > 0) { | |
int atype = opcode >> 10 & 0x3f; | |
if ((atype & 0xf8) == 16 || atype == 31 || atype == 30) | |
len++; | |
} | |
} else { | |
int atype = opcode >> 4 & 0x3f; | |
int btype = opcode >> 10 & 0x3f; | |
if ((atype & 0xf8) == 16 || atype == 31 || atype == 30) | |
len++; | |
if ((btype & 0xf8) == 16 || btype == 31 || btype == 30) | |
len++; | |
} | |
return len; | |
} | |
public void skip() { | |
cycles++; | |
pc += getInstructionLength(ram[pc++]); | |
} | |
public void tick() { | |
cycles++; | |
char opcode = ram[pc++]; | |
int cmd = opcode & 0xf; | |
if (cmd == 0) { | |
cmd = opcode >> 4 & 0xf; | |
if (cmd != 0) { | |
int atype = opcode >> 10 & 0x3f; | |
int aaddr = getAddr(atype); | |
char a = get(aaddr); | |
switch (cmd) { | |
case 1: // '\001' | |
ram[--sp & 0xffff] = (char) ((pc - 2) + getInstructionLength(opcode)); | |
pc = a; | |
break; | |
} | |
} | |
} else { | |
int atype = opcode >> 4 & 0x3f; | |
int btype = opcode >> 10 & 0x3f; | |
int aaddr = getAddr(atype); | |
char a = get(aaddr); | |
int baddr = getAddr(btype); | |
char b = get(baddr); | |
switch (cmd) { | |
default: | |
break; | |
case 1: // '\001' | |
{ | |
a = b; | |
break; | |
} | |
case 2: // '\002' | |
{ | |
cycles++; | |
int val = a + b; | |
a = (char) val; | |
o = (char) (val >> 16); | |
break; | |
} | |
case 3: // '\003' | |
{ | |
cycles++; | |
int val = a - b; | |
a = (char) val; | |
o = (char) (val >> 16); | |
break; | |
} | |
case 4: // '\004' | |
{ | |
cycles++; | |
int val = a * b; | |
a = (char) val; | |
o = (char) (val >> 16); | |
break; | |
} | |
case 5: // '\005' | |
{ | |
cycles += 2; | |
if (b == 0) { | |
a = o = '\0'; | |
} else { | |
long val = ((long) a << 16) / (long) b; | |
a = (char) (int) (val >> 16); | |
o = (char) (int) val; | |
} | |
break; | |
} | |
case 6: // '\006' | |
{ | |
cycles += 2; | |
if (b == 0) | |
a = '\0'; | |
else | |
a %= b; | |
break; | |
} | |
case 7: // '\007' | |
{ | |
cycles++; | |
long val = (long) a << b; | |
a = (char) (int) val; | |
o = (char) (int) (val >> 16); | |
break; | |
} | |
case 8: // '\b' | |
{ | |
cycles++; | |
long val = (long) a << 16 - b; | |
a = (char) (int) (val >> 16); | |
o = (char) (int) val; | |
break; | |
} | |
case 9: // '\t' | |
{ | |
a &= b; | |
break; | |
} | |
case 10: // '\n' | |
{ | |
a |= b; | |
break; | |
} | |
case 11: // '\013' | |
{ | |
a ^= b; | |
break; | |
} | |
case 12: // '\f' | |
{ | |
cycles++; | |
if (a != b) | |
skip(); | |
return; | |
} | |
case 13: // '\r' | |
{ | |
cycles++; | |
if (a == b) | |
skip(); | |
return; | |
} | |
case 14: // '\016' | |
{ | |
cycles++; | |
if (a <= b) | |
skip(); | |
return; | |
} | |
case 15: // '\017' | |
{ | |
cycles++; | |
if ((a & b) == 0) | |
skip(); | |
return; | |
} | |
} | |
set(aaddr, a); | |
} | |
} | |
private static void testCpus(int cpuCount, char ram[]) { | |
DCPU cpus[] = new DCPU[cpuCount]; | |
for (int i = 0; i < cpuCount; i++) { | |
cpus[i] = new DCPU(); | |
for (int j = 0; j < 0x10000; j++) | |
cpus[i].ram[j] = ram[j]; | |
} | |
long ops = 0L; | |
int hz = 0x186a0; | |
int cyclesPerFrame = hz / 60; | |
long nsPerFrame = 0xfe502aL; | |
long nextTime = System.nanoTime(); | |
double tick = 0.0D; | |
double total = 0.0D; | |
long startTime = System.currentTimeMillis(); | |
while (!stop) { | |
long a = System.nanoTime(); | |
while (System.nanoTime() < nextTime) | |
try { | |
Thread.sleep(1L); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
long b = System.nanoTime(); | |
for (int j = 0; j < cpuCount; j++) { | |
while (cpus[j].cycles < cyclesPerFrame) | |
cpus[j].tick(); | |
cpus[j].cycles -= cyclesPerFrame; | |
} | |
long c = System.nanoTime(); | |
ops += cyclesPerFrame; | |
nextTime += nsPerFrame; | |
tick += (double) (c - b) / 1000000000D; | |
total += (double) (c - a) / 1000000000D; | |
} | |
long passedTime = System.currentTimeMillis() - startTime; | |
System.out.println((new StringBuilder(String.valueOf(cpuCount))) | |
.append(" DCPU at ").append((double) ops / (double) passedTime) | |
.append(" khz, ").append((tick * 100D) / total) | |
.append("% cpu use").toString()); | |
} | |
private static void attachDisplay(DCPU cpu) { | |
final VirtualMonitor display = new VirtualMonitor(cpu.ram, 32768); | |
final VirtualKeyboard keyboard = new VirtualKeyboard(cpu.ram, 36864, | |
new AWTKeyMapping()); | |
Thread t = new Thread() { | |
public void run() { | |
try { | |
int SCALE = 3; | |
JFrame frame = new JFrame(); | |
Canvas canvas = new Canvas(); | |
canvas.setPreferredSize(new Dimension(160 * SCALE, | |
128 * SCALE)); | |
canvas.setMinimumSize(new Dimension(160 * SCALE, | |
128 * SCALE)); | |
canvas.setMaximumSize(new Dimension(160 * SCALE, | |
128 * SCALE)); | |
canvas.setFocusable(true); | |
canvas.addKeyListener(new KeyListener() { | |
public void keyPressed(KeyEvent ke) { | |
keyboard.keyPressed(ke.getKeyCode()); | |
} | |
public void keyReleased(KeyEvent ke) { | |
keyboard.keyReleased(ke.getKeyCode()); | |
} | |
public void keyTyped(KeyEvent ke) { | |
keyboard.keyTyped(ke.getKeyChar()); | |
} | |
}); | |
frame.add(canvas); | |
frame.pack(); | |
frame.setLocationRelativeTo(null); | |
frame.setResizable(false); | |
frame.setDefaultCloseOperation(3); | |
frame.setVisible(true); | |
BufferedImage img2 = new BufferedImage(160, 128, 2); | |
BufferedImage img = new BufferedImage(128, 128, 2); | |
display.setPixels(((DataBufferInt) img.getRaster() | |
.getDataBuffer()).getData()); | |
canvas.requestFocus(); | |
do { | |
display.render(); | |
Graphics g = img2.getGraphics(); | |
g.setColor(new Color(display.getBackgroundColor())); | |
g.fillRect(0, 0, 160, 128); | |
g.drawImage(img, 16, 16, 128, 128, null); | |
g.dispose(); | |
g = canvas.getGraphics(); | |
g.drawImage(img2, 0, 0, 160 * SCALE, 128 * SCALE, null); | |
g.dispose(); | |
Thread.sleep(1L); | |
} while (true); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
}; | |
t.start(); | |
} | |
private static void testCpu(char ram[]) { | |
DCPU cpu = new DCPU(); | |
for (int j = 0; j < 0x10000; j++) | |
cpu.ram[j] = ram[j]; | |
attachDisplay(cpu); | |
long ops = 0L; | |
int hz = 0x186a0; | |
int cyclesPerFrame = hz / 60; | |
long nsPerFrame = 0xfe502aL; | |
long nextTime = System.nanoTime(); | |
double tick = 0.0D; | |
double total = 0.0D; | |
long time = System.currentTimeMillis(); | |
while (!stop) { | |
long a = System.nanoTime(); | |
while (System.nanoTime() < nextTime) | |
try { | |
Thread.sleep(1L); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
long b = System.nanoTime(); | |
while (cpu.cycles < cyclesPerFrame) | |
cpu.tick(); | |
cpu.cycles -= cyclesPerFrame; | |
long c = System.nanoTime(); | |
ops += cyclesPerFrame; | |
nextTime += nsPerFrame; | |
tick += (double) (c - b) / 1000000000D; | |
total += (double) (c - a) / 1000000000D; | |
while (System.currentTimeMillis() > time) { | |
time += 1000L; | |
System.out.println((new StringBuilder("1 DCPU at ")) | |
.append((double) ops / 1000D).append(" khz, ") | |
.append((tick * 100D) / total).append("% cpu use") | |
.toString()); | |
tick = total = ops = 0L; | |
} | |
} | |
} | |
public static void main(String args[]) throws Exception { | |
final DCPU cpu = new DCPU(); | |
DataInputStream dis = new DataInputStream( | |
DCPU.class.getResourceAsStream("mem.dmp")); | |
try { | |
int i = 0; | |
do { | |
char ch = dis.readChar(); | |
cpu.ram[i] = ch; | |
i++; | |
} while (true); | |
} catch (EOFException e) { | |
e.printStackTrace(); | |
} | |
dis.close(); | |
dump(cpu.ram, 0, 768); | |
if (args.length == 0) { | |
testCpu(cpu.ram); | |
return; | |
} | |
int threads = args.length <= 0 ? 1 : Integer.parseInt(args[0]); | |
final int cpusPerCore = args.length <= 1 ? 100 : Integer | |
.parseInt(args[1]); | |
int seconds = args.length <= 2 ? 5 : Integer.parseInt(args[2]); | |
System.out.println((new StringBuilder("Aiming at 100 khz, with ")) | |
.append(cpusPerCore).append(" DCPUs per thread, on ") | |
.append(threads).append(" threads.").toString()); | |
System.out.println(""); | |
System.out.println((new StringBuilder("Running test for ")) | |
.append(seconds).append(" seconds..").toString()); | |
for (int i = 0; i < threads; i++) { | |
(new Thread() { | |
public void run() { | |
DCPU.testCpus(cpusPerCore, cpu.ram); | |
} | |
}).start(); | |
} | |
for (int i = seconds; i > 0; i--) { | |
System.out.println((new StringBuilder(String.valueOf(i))).append( | |
"..").toString()); | |
Thread.sleep(1000L); | |
} | |
stop = true; | |
} | |
private static void dump(char ram[], int start, int len) { | |
for (int i = 0; i < len;) { | |
String str; | |
for (str = Integer.toHexString(i); str.length() < 4; str = (new StringBuilder( | |
"0")).append(str).toString()) | |
; | |
System.out.print((new StringBuilder(String.valueOf(str))).append( | |
":").toString()); | |
for (int j = 0; j < 8 && i < len; i++) { | |
for (str = Integer.toHexString(ram[i]); str.length() < 4; str = (new StringBuilder( | |
"0")).append(str).toString()) | |
; | |
System.out.print((new StringBuilder(" ")).append(str) | |
.toString()); | |
j++; | |
} | |
System.out.println(); | |
} | |
} | |
public char ram[]; | |
public char pc; | |
public char sp; | |
public char o; | |
public char registers[]; | |
public int cycles; | |
private static volatile boolean stop = false; | |
private static final int khz = 100; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package computer; | |
import java.applet.Applet; | |
import java.awt.Color; | |
import java.awt.Graphics; | |
import java.awt.event.KeyEvent; | |
import java.awt.event.KeyListener; | |
import java.awt.image.*; | |
import java.io.*; | |
// Referenced classes of package computer: | |
// DCPU, VirtualMonitor, VirtualKeyboard, AWTKeyMapping | |
public class DCPUApplet extends Applet | |
implements Runnable | |
{ | |
public DCPUApplet() | |
{ | |
running = false; | |
} | |
public void start() | |
{ | |
running = true; | |
(new Thread(this)).start(); | |
} | |
public void paint(Graphics g1) | |
{ | |
} | |
public void update(Graphics g1) | |
{ | |
} | |
public void stop() | |
{ | |
running = false; | |
} | |
public void run() | |
{ | |
try | |
{ | |
DCPU cpu = new DCPU(); | |
DataInputStream dis = new DataInputStream(DCPU.class.getResourceAsStream("mem.dmp")); | |
try | |
{ | |
int i = 0; | |
do | |
{ | |
char ch = dis.readChar(); | |
cpu.ram[i] = ch; | |
i++; | |
} while(true); | |
} | |
catch(EOFException eofexception) | |
{ | |
dis.close(); | |
} | |
emulate(cpu); | |
} | |
catch(Exception e) | |
{ | |
e.printStackTrace(); | |
} | |
} | |
private void emulate(DCPU cpu) | |
{ | |
display = new VirtualMonitor(cpu.ram, 32768); | |
keyboard = new VirtualKeyboard(cpu.ram, 36864, new AWTKeyMapping()); | |
addKeyListener(new KeyListener() { | |
public void keyPressed(KeyEvent ke) | |
{ | |
keyboard.keyPressed(ke.getKeyCode()); | |
} | |
public void keyReleased(KeyEvent ke) | |
{ | |
keyboard.keyReleased(ke.getKeyCode()); | |
} | |
public void keyTyped(KeyEvent ke) | |
{ | |
keyboard.keyTyped(ke.getKeyChar()); | |
} | |
}); | |
long ops = 0L; | |
int hz = 0x186a0; | |
int cyclesPerFrame = hz / 60; | |
long nsPerFrame = 0xfe502aL; | |
long nextTime = System.nanoTime(); | |
double tick = 0.0D; | |
double total = 0.0D; | |
long time = System.currentTimeMillis(); | |
while(running) | |
{ | |
long a = System.nanoTime(); | |
while(System.nanoTime() < nextTime) | |
try | |
{ | |
Thread.sleep(1L); | |
} | |
catch(InterruptedException e) | |
{ | |
e.printStackTrace(); | |
} | |
long b = System.nanoTime(); | |
while(cpu.cycles < cyclesPerFrame) | |
cpu.tick(); | |
BufferedImage img2 = new BufferedImage(160, 128, 2); | |
BufferedImage img = new BufferedImage(128, 128, 2); | |
display.setPixels(((DataBufferInt)img.getRaster().getDataBuffer()).getData()); | |
display.render(); | |
Graphics g = img2.getGraphics(); | |
g.setColor(new Color(display.getBackgroundColor())); | |
g.fillRect(0, 0, 160, 128); | |
g.drawImage(img, 16, 16, 128, 128, null); | |
g.dispose(); | |
g = getGraphics(); | |
g.drawImage(img2, 0, 0, 480, 384, null); | |
g.dispose(); | |
cpu.cycles -= cyclesPerFrame; | |
long c = System.nanoTime(); | |
ops += cyclesPerFrame; | |
nextTime += nsPerFrame; | |
tick += (double)(c - b) / 1000000000D; | |
total += (double)(c - a) / 1000000000D; | |
while(System.currentTimeMillis() > time) | |
{ | |
time += 1000L; | |
System.out.println((new StringBuilder("1 DCPU at ")).append((double)ops / 1000D).append(" khz, ").append((tick * 100D) / total).append("% cpu use").toString()); | |
tick = total = ops = 0L; | |
} | |
} | |
} | |
private static final int khz = 100; | |
private static final int SCALE = 3; | |
private boolean running; | |
private VirtualMonitor display; | |
private VirtualKeyboard keyboard; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package computer; | |
import java.util.HashMap; | |
import java.util.Map; | |
public class KeyMapping | |
{ | |
public KeyMapping() | |
{ | |
keyMap = new HashMap(); | |
} | |
public int getKey(int key) | |
{ | |
if(keyMap.containsKey(Integer.valueOf(key))) | |
return ((Integer)keyMap.get(Integer.valueOf(key))).intValue(); | |
else | |
return -1; | |
} | |
protected void map(int key, int c) | |
{ | |
keyMap.put(Integer.valueOf(key), Integer.valueOf(c)); | |
} | |
public Map keyMap; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package computer; | |
// Referenced classes of package computer: | |
// KeyMapping | |
public class VirtualKeyboard | |
{ | |
public VirtualKeyboard(char ram[], int offset, KeyMapping keyMapping) | |
{ | |
pp = 0; | |
this.ram = ram; | |
this.offset = offset; | |
this.keyMapping = keyMapping; | |
} | |
public void keyTyped(int i) | |
{ | |
if(i <= 0 || i > 127) | |
return; | |
if(ram[offset + pp] != 0) | |
{ | |
return; | |
} else | |
{ | |
ram[offset + pp] = (char)i; | |
pp = pp + 1 & 0xf; | |
return; | |
} | |
} | |
public void keyPressed(int key) | |
{ | |
int i = keyMapping.getKey(key); | |
if(i < 80 || i > 255) | |
return; | |
if(ram[offset + pp] != 0) | |
{ | |
return; | |
} else | |
{ | |
ram[offset + pp] = (char)i; | |
pp = pp + 1 & 0xf; | |
return; | |
} | |
} | |
public void keyReleased(int key) | |
{ | |
int i = keyMapping.getKey(key); | |
if(i < 80 || i > 255) | |
return; | |
if(ram[offset + pp] != 0) | |
{ | |
return; | |
} else | |
{ | |
ram[offset + pp] = (char)(i | 0x100); | |
pp = pp + 1 & 0xf; | |
return; | |
} | |
} | |
public static final int KEY_UP = 128; | |
public static final int KEY_DOWN = 129; | |
public static final int KEY_LEFT = 130; | |
public static final int KEY_RIGHT = 131; | |
private final char ram[]; | |
private final int offset; | |
private int pp; | |
private KeyMapping keyMapping; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package computer; | |
import java.awt.image.BufferedImage; | |
import java.io.IOException; | |
import javax.imageio.ImageIO; | |
public class VirtualMonitor | |
{ | |
public VirtualMonitor(char ram[], int offset) | |
{ | |
this.pixels = new int[16384]; | |
this.ram = ram; | |
this.offset = offset; | |
charOffset = offset + 384; | |
miscDataOffset = charOffset + 256; | |
for(int i = 0; i < 256; i++) | |
{ | |
int bg = genColor(i % 16); | |
int fg = genColor(i / 16); | |
colorBase[i] = bg; | |
colorOffs[i] = fg - bg; | |
} | |
int pixels[] = new int[4096]; | |
try | |
{ | |
ImageIO.read(getClass().getResource("font.png")).getRGB(0, 0, 128, 32, pixels, 0, 128); | |
} | |
catch(IOException e) | |
{ | |
e.printStackTrace(); | |
} | |
for(int c = 0; c < 128; c++) | |
{ | |
int ro = charOffset + c * 2; | |
int xo = (c % 32) * 4; | |
int yo = (c / 32) * 8; | |
ram[ro + 0] = '\0'; | |
ram[ro + 1] = '\0'; | |
for(int xx = 0; xx < 4; xx++) | |
{ | |
int bb = 0; | |
for(int yy = 0; yy < 8; yy++) | |
if((pixels[xo + xx + (yo + yy) * 128] & 0xff) > 128) | |
bb |= 1 << yy; | |
ram[ro + xx / 2] |= bb << (xx + 1 & 1) * 8; | |
} | |
} | |
} | |
private static int genColor(int i) | |
{ | |
int b = (i >> 0 & 1) * 170; | |
int g = (i >> 1 & 1) * 170; | |
int r = (i >> 2 & 1) * 170; | |
if(i == 6) | |
b += 85; | |
else | |
if(i >= 8) | |
{ | |
r += 85; | |
g += 85; | |
b += 85; | |
} | |
return 0xff000000 | r << 16 | g << 8 | b; | |
} | |
public void render() | |
{ | |
long time = System.currentTimeMillis() / 16L; | |
boolean blink = (time / 20L) % 2L == 0L; | |
long reds = 0L; | |
long greens = 0L; | |
long blues = 0L; | |
for(int y = 0; y < 12; y++) | |
{ | |
for(int x = 0; x < 32; x++) | |
{ | |
char dat = ram[offset + x + y * 32]; | |
int ch = dat & 0x7f; | |
int colorIndex = dat >> 8 & 0xff; | |
int co = charOffset + ch * 2; | |
int color = colorBase[colorIndex]; | |
int colorAdd = colorOffs[colorIndex]; | |
if(blink && (dat & 0x80) > 0) | |
colorAdd = 0; | |
int pixelOffs = x * 4 + y * 8 * 128; | |
for(int xx = 0; xx < 4; xx++) | |
{ | |
int bits = ram[co + (xx >> 1)] >> (xx + 1 & 1) * 8 & 0xff; | |
for(int yy = 0; yy < 8; yy++) | |
{ | |
int col = color + colorAdd * (bits >> yy & 1); | |
pixels[pixelOffs + xx + yy * 128] = col; | |
reds += col & 0xff0000; | |
greens += col & 0xff00; | |
blues += col & 0xff; | |
} | |
} | |
} | |
} | |
int color = colorBase[ram[miscDataOffset] & 0xf]; | |
for(int y = 96; y < 128; y++) | |
{ | |
for(int x = 0; x < 128; x++) | |
pixels[x + y * 128] = color; | |
} | |
int borderPixels = 100; | |
reds += (color & 0xff0000) * borderPixels; | |
greens += (color & 0xff00) * borderPixels; | |
blues += (color & 0xff) * borderPixels; | |
reds = reds / (long)(12288 + borderPixels) & 0xff0000L; | |
greens = greens / (long)(12288 + borderPixels) & 65280L; | |
blues = blues / (long)(12288 + borderPixels) & 255L; | |
lightColor = (int)(reds | greens | blues); | |
} | |
public int getBackgroundColor() | |
{ | |
return colorBase[ram[miscDataOffset] & 0xf]; | |
} | |
public void setPixels(int pixels[]) | |
{ | |
this.pixels = pixels; | |
} | |
public int getLightColor() | |
{ | |
return lightColor; | |
} | |
public static final int WIDTH_CHARS = 32; | |
public static final int HEIGHT_CHARS = 12; | |
public static final int WIDTH_PIXELS = 128; | |
public static final int HEIGHT_PIXELS = 96; | |
private final char ram[]; | |
private final int offset; | |
private final int charOffset; | |
private final int miscDataOffset; | |
private final int colorBase[] = new int[256]; | |
private final int colorOffs[] = new int[256]; | |
private int lightColor; | |
public int pixels[]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment