import javax.microedition.lcdui.*; import java.util.Random; import java.io.InputStream; import java.io.DataInputStream; import java.io.IOException; public class Emulator extends Canvas { public boolean gameLoaded = false; int scw = 64, sch = 32; byte[][] screen = new byte[scw][sch]; byte[] key = new byte[16]; byte[] mem = new byte[4096]; byte[] V = new byte[16]; short I; byte delay_timer; byte sound_timer; short[] stack = new short[16]; short opcode; short PC; byte SP; int w; int h; long old_time = System.currentTimeMillis(); int sleep = 40; /** * constructor */ public Emulator() { setFullScreenMode(true); w = getWidth(); h = getHeight(); PC = 0x200; SP = 0; I = 0x200; delay_timer = 0; sound_timer = 0; for(int a = 0; a> xpix))!=0){ if((V[X] + xpix)<64&&(V[Y] + yline)<32&&(V[X] + xpix)>=0&&(V[Y] + yline)>=0) { if(screen[V[X] + xpix][V[Y] + yline] == 1) V[0xF] = 1; screen[V[X] + xpix][V[Y] + yline]^=1; } } } } } catch (Throwable t) { Midlet.getInstance().displayError(t.toString().concat(" at Emulator.drawSprite()")); } } public void executeNextOpcode() { try { opcode = (short)((mem[PC]<<8) | mem[PC+1]); PC+=2; int x = (int)((opcode&0x0F00)>>8); int y = (int)((opcode&0x00F0)>>4); byte kk = (byte)(opcode&0x00FF); switch((opcode&0xF000)>>12){ case 0x0: switch(opcode&0x00FF) { case 0xE0: for(int a = 0; a0xF) V[0xF] = 1; else V[0xF] = 0; break; case 0x5: if(V[x]>=V[y]) V[0xF] = 1; else V[0xF] = 0; V[x]-=V[y]; break; case 0x6: if((V[x]&0x000F) == 1) V[0xF] = 1; else V[0xF] = 0; V[x] = (byte)(V[x] >> 1); break; case 0x7: if(V[y]>=V[x]) V[0xF] = 1; else V[0xF] = 0; V[x] = (byte)(V[y] - V[x]); break; case 0xE: if((V[x]&0x000F)==1) V[0xF] = 1; else V[0xF] = 0; V[x] = (byte)(V[x] << 1); break; } break; case 0x9: switch(opcode&0x000F){ case 0x0: if(V[x]!=V[y]) PC+=2; break; } break; case 0xA: I = (short)(opcode&0x0FFF); break; case 0xB: PC = (short)(opcode&0x0FFF + V[0x0]); break; case 0xC: Random rnd = new Random(); V[x] = (byte)(((rnd.nextInt()>>>1)%255)&kk); break; case 0xD: byte varx = (byte)((opcode&0x0F00)>>8); byte vary = (byte)((opcode&0x00F0)>>4); byte n = (byte)(opcode&0x000F); drawSprite(x, y, (int)n); break; case 0xE: switch(opcode&0x00FF){ case 0x9E: if(key[(int)(V[x])] == 1) PC+=2; break; case 0xA1: if(key[(int)(V[x])]==0) PC+=2; break; } break; case 0xF: switch(opcode&0x00FF){ case 0x07: V[x] = delay_timer; break; case 0x0A: for(int i = 0; i<16; i++){ if(key[i] == 1){ V[x] = (byte)i; break; } } break; case 0x15: delay_timer = V[x]; break; case 0x18: sound_timer = V[x]; break; case 0x1E: I = (short)(I + V[x]); break; case 0x29: I = (short)((V[x]-1)*5+1); break; case 0x33: byte a = (byte)(V[x]/100); byte b = (byte)((V[x] - 100*a)/10); byte c = (byte)(V[x] - 100*a - 10*b); mem[I] = (byte)(a&0xF); mem[I+1] = (byte)(b&0xF); mem[I+2] = (byte)(c&0xF); break; case 0x55: for(int i = 0; i<16; i++){ mem[I+i] = V[i]; } break; case 0x65: for(int i = 0; i<16; i++){ V[i] = mem[I+i]; } break; } break; } } catch (Throwable t) { Midlet.getInstance().displayError(t.toString().concat(" at Emulator.executeNextOpcode()")); } } public void decreaseTimers(){ if (System.currentTimeMillis() - old_time >= 1000 / 60) { if(delay_timer > 0) { delay_timer--; } if(sound_timer > 0) { sound_timer--; } old_time = System.currentTimeMillis(); } } /** * paint */ public void paint(Graphics g) { if (gameLoaded && isShown()) { try { g.setColor(0xFFFFFF); g.fillRect(0, 0, w, h); g.setColor(0x000000); g.drawString("0x".concat(Integer.toHexString(opcode)), 5, 5, 0); Image i = Image.createImage(scw, sch); Graphics G = i.getGraphics(); for(int a = 0; a<32; a++){ for(int b = 0; b<64;b++){ if(screen[b][a]==1){ G.setColor(0xFFFFFF); G.fillRect(b, a, 1, 1); } else { G.setColor(0x000000); G.fillRect(b, a, 1, 1); } } } g.drawImage(i, w / 2 - scw / 2, h / 2 - sch / 2, 0); executeNextOpcode(); decreaseTimers(); repaint(); Thread.sleep(sleep); } catch (Throwable t) { Midlet.getInstance().displayError(t.toString().concat(" at Emulator.paint()")); } } } /** * Called when a key is pressed. */ protected void keyPressed(int keyCode) { int ga = getGameAction(keyCode); switch(keyCode){ case KEY_NUM1: key[0x1] = 1; break; case KEY_NUM2: key[0x2] = 1; break; case KEY_NUM3: key[0x3] = 1; break; case KEY_NUM4: key[0x4] = 1; break; case KEY_NUM5: key[0x5] = 1; break; case KEY_NUM6: key[0x6] = 1; break; case KEY_NUM7: key[0x7] = 1; break; case KEY_NUM8: key[0x8] = 1; break; case KEY_NUM9: key[0x9] = 1; break; case KEY_NUM0: key[0x0] = 1; break; case KEY_STAR: key[0xF] = 1; break; case -36: sleep += 10; break; case -37: if (sleep >= 10) sleep -= 10; break; } if(ga==UP&&keyCode!=KEY_NUM2){ key[0xA] = 1; } if(ga==DOWN&&keyCode!=KEY_NUM8){ key[0xB] = 1; } if(ga==LEFT&&keyCode!=KEY_NUM4){ key[0xC] = 1; } if(ga==RIGHT&&keyCode!=KEY_NUM6){ key[0xD] = 1; } if(ga == FIRE&&keyCode!=KEY_NUM5){ key[0xE] = 1; } } }