import java.io.DataInputStream; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.URL; class KeyEvent { static final int VK_LEFT = -12345678; static final int VK_RIGHT = -12345678; static final int VK_UP = -12345678; static final int VK_DOWN = -12345678; static final int VK_SPACE = -12345678; static final int VK_F1 = -12345678; static final int VK_BACK_SPACE = -12345678; static final int VK_ENTER = -12345678; } public class GameShell implements Runnable { public static GameFrame gameFrame = null; private static String charMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"\243$%^&*()-_=+[{]};:'@#~,<.>/?\\| "; public int mouseActionTimeout; public int loadingStep; public String logoHeaderText; public boolean keyLeft; public boolean keyRight; public boolean keyUp; public boolean keyDown; public boolean keySpace; public int threadSleep; public int mouseX; public int mouseY; public int mouseButtonDown; public int lastMouseButtonDown; public boolean interlace; public String inputTextCurrent; public String inputTextFinal; public String inputPmCurrent; public String inputPmFinal; public int appletWidth; public int appletHeight; private Thread appletThread; private int targetFps; private int maxDrawTime; private long timings[]; private boolean startedAsApplet; private int stopTimeout; private int interlaceTimer; private boolean hasRefererLogoNotused; private int loadingProgressPercent; private String loadingProgessText; /* private Font fontTimesRoman15; private Font fontHelvetica13b; private Font fontHelvetica12; private Image imageLogo;*/ protected int fps; public GameShell() { appletWidth = 512; appletHeight = 344; targetFps = 20; maxDrawTime = 1000; timings = new long[10]; loadingStep = 1; hasRefererLogoNotused = false; loadingProgessText = "Loading"; /* fontTimesRoman15 = new Font("TimesRoman", 0, 15); fontHelvetica13b = new Font("Helvetica", Font.BOLD, 13); fontHelvetica12 = new Font("Helvetica", 0, 12);*/ keyLeft = false; keyRight = false; keyUp = false; keyDown = false; keySpace = false; threadSleep = 1; interlace = false; inputTextCurrent = ""; inputTextFinal = ""; inputPmCurrent = ""; inputPmFinal = ""; } private void dummy() { this.keyPressed('A', 97); this.keyReleased(97); this.mouseMoved(0, 0); this.mouseReleased(0, 0); this.mousePressed(0, 0, 0); this.mouseDragged(0, 0, 0); } protected void startGame() { } protected synchronized void handleInputs() { } protected void onClosing() { } protected synchronized void draw() { } protected void startApplication(int width, int height, String title, boolean resizeable) { startedAsApplet = false; System.out.println("Started application"); appletWidth = width; appletHeight = height; gameFrame = new GameFrame(this, width, height, title, resizeable, false); loadingStep = 1; appletThread = new Thread(this); appletThread.start(); appletThread.setPriority(1); dummy(); } protected void setTargetFps(int i) { targetFps = 1000 / i; } protected void resetTimings() { for (int i = 0; i < 10; i++) { timings[i] = 0L; } } public synchronized void keyPressed(char chr, int code) { handleKeyPress(chr); mouseActionTimeout = 0; if (code == KeyEvent.VK_LEFT) { keyLeft = true; } else if (code == KeyEvent.VK_RIGHT) { keyRight = true; } else if (code == KeyEvent.VK_UP) { keyUp = true; } else if (code == KeyEvent.VK_DOWN) { keyDown = true; } else if (code == KeyEvent.VK_SPACE) { keySpace = true; } else if (code == KeyEvent.VK_F1) { interlace = !interlace; } else { boolean foundText = false; for (int i = 0; i < charMap.length(); i++) { if (charMap.charAt(i) == chr) { foundText = true; break; } } if (foundText) { if (inputTextCurrent.length() < 20) { inputTextCurrent += chr; } if (inputPmCurrent.length() < 80) { inputPmCurrent += chr; } } } if (code == KeyEvent.VK_BACK_SPACE) { if (inputTextCurrent.length() > 0) { inputTextCurrent = inputTextCurrent.substring(0, inputTextCurrent.length() - 1); } if (inputPmCurrent.length() > 0) { inputPmCurrent = inputPmCurrent.substring(0, inputPmCurrent.length() - 1); } } if (code == KeyEvent.VK_ENTER) { inputTextFinal = inputTextCurrent; inputPmFinal = inputPmCurrent; } } protected void handleKeyPress(int i) { } public synchronized void keyReleased(int code) { if (code == KeyEvent.VK_LEFT) { keyLeft = false; } else if (code == KeyEvent.VK_RIGHT) { keyRight = false; } else if (code == KeyEvent.VK_UP) { keyUp = false; } else if (code == KeyEvent.VK_DOWN) { keyDown = false; } else if (code == KeyEvent.VK_SPACE) { keySpace = false; } } public synchronized void mouseMoved(int x, int y) { mouseX = x; mouseY = y; mouseButtonDown = 0; mouseActionTimeout = 0; } public synchronized void mouseReleased(int x, int y) { mouseX = x; mouseY = y; mouseButtonDown = 0; } public synchronized void mousePressed(int x, int y, int button) { mouseX = x; mouseY = y; mouseButtonDown = button; lastMouseButtonDown = mouseButtonDown; mouseActionTimeout = 0; handleMouseDown(mouseButtonDown, x, y); } public synchronized void mouseDragged(int x, int y, int button) { mouseX = x; mouseY = y; mouseButtonDown = button; } protected void handleMouseDown(int i, int j, int k) { } public void init() { startedAsApplet = true; System.out.println("Started applet"); /* appletWidth = 512; appletHeight = 344;*/ loadingStep = 1; /* Utility.appletCodeBase = getCodeBase(); addMouseListener(this); addMouseMotionListener(this); addKeyListener(this);*/ startThread(this); } public void start() { if (stopTimeout >= 0) stopTimeout = 0; } public void stop() { if (stopTimeout >= 0) stopTimeout = 4000 / targetFps; } public void destroy() { stopTimeout = -1; try { Thread.sleep(5000L); } catch (Exception ignored) { } if (stopTimeout == -1) { System.out.println("5 seconds expired, forcing kill"); closeProgram(); } } private void closeProgram() { stopTimeout = -2; System.out.println("Closing program"); onClosing(); try { Thread.sleep(1000L); } catch (Exception ignored) { } System.exit(0); } public void run() { if (loadingStep == 1) { loadingStep = 2; //graphics = getGraphics(); loadJagex(); drawLoadingScreen(0, "Loading..."); startGame(); loadingStep = 0; } int i = 0; int j = 256; int sleep = 1; int i1 = 0; for (int j1 = 0; j1 < 10; j1++) { timings[j1] = System.currentTimeMillis(); } while (stopTimeout >= 0) { if (stopTimeout > 0) { stopTimeout--; if (stopTimeout == 0) { closeProgram(); appletThread = null; return; } } int k1 = j; int lastSleep = sleep; j = 300; sleep = 1; long time = System.currentTimeMillis(); if (timings[i] == 0L) { j = k1; sleep = lastSleep; } else if (time > timings[i]) j = (int) ((long) (2560 * targetFps) / (time - timings[i])); if (j < 25) j = 25; if (j > 256) { j = 256; sleep = (int) ((long) targetFps - (time - timings[i]) / 10L); if (sleep < threadSleep) sleep = threadSleep; } try { Thread.sleep(sleep); } catch (InterruptedException ignored) { } timings[i] = time; i = (i + 1) % 10; if (sleep > 1) { for (int j2 = 0; j2 < 10; j2++) if (timings[j2] != 0L) timings[j2] += sleep; } int k2 = 0; while (i1 < 256) { handleInputs(); i1 += j; if (++k2 > maxDrawTime) { i1 = 0; interlaceTimer += 6; if (interlaceTimer > 25) { interlaceTimer = 0; interlace = true; } break; } } interlaceTimer--; i1 &= 0xff; draw(); this.fps = (1000 * j) / (this.targetFps * 256); } if (stopTimeout == -1) closeProgram(); appletThread = null; } /* public void update(Graphics g) { paint(g); } public void paint(Graphics g) { if (loadingStep == 2 && imageLogo != null) { drawLoadingScreen(loadingProgressPercent, loadingProgessText); } }*/ private void loadJagex() { //graphics.setColor(Color.black); //graphics.fillRect(0, 0, appletWidth, appletHeight); byte buff[] = readDataFile("jagex.jag", "Jagex library", 0); if (buff != null) { byte logo[] = Utility.loadData("logo.tga", 0, buff); //imageLogo = createImage(logo); } buff = readDataFile("fonts" + Version.FONTS + ".jag", "Game fonts", 5); if (buff != null) { Surface.createFont(Utility.loadData("h11p.jf", 0, buff), 0); Surface.createFont(Utility.loadData("h12b.jf", 0, buff), 1); Surface.createFont(Utility.loadData("h12p.jf", 0, buff), 2); Surface.createFont(Utility.loadData("h13b.jf", 0, buff), 3); Surface.createFont(Utility.loadData("h14b.jf", 0, buff), 4); Surface.createFont(Utility.loadData("h16b.jf", 0, buff), 5); Surface.createFont(Utility.loadData("h20b.jf", 0, buff), 6); Surface.createFont(Utility.loadData("h24b.jf", 0, buff), 7); } } private void drawLoadingScreen(int percent, String text) { /* try { int midx = (appletWidth - 281) / 2; int midy = (appletHeight - 148) / 2; graphics.setColor(Color.black); graphics.fillRect(0, 0, appletWidth, appletHeight); if (!hasRefererLogoNotused) { graphics.drawImage(imageLogo, midx, midy, this); } midx += 2; midy += 90; loadingProgressPercent = percent; loadingProgessText = text; graphics.setColor(new Color(132, 132, 132)); if (hasRefererLogoNotused) { graphics.setColor(new Color(220, 0, 0)); } graphics.drawRect(midx - 2, midy - 2, 280, 23); graphics.fillRect(midx, midy, (277 * percent) / 100, 20); graphics.setColor(new Color(198, 198, 198)); if (hasRefererLogoNotused) { graphics.setColor(new Color(255, 255, 255)); } drawString(graphics, text, fontTimesRoman15, midx + 138, midy + 10); if (!hasRefererLogoNotused) { drawString(graphics, "Created by JAGeX - visit www.jagex.com", fontHelvetica13b, midx + 138, midy + 30); drawString(graphics, "\2512001-2002 Andrew Gower and Jagex Ltd", fontHelvetica13b, midx + 138, midy + 44); } else { graphics.setColor(new Color(132, 132, 152)); drawString(graphics, "\2512001-2002 Andrew Gower and Jagex Ltd", fontHelvetica12, midx + 138, appletHeight - 20); } if (logoHeaderText != null) { graphics.setColor(Color.white); drawString(graphics, logoHeaderText, fontHelvetica13b, midx + 138, midy - 120); } } catch (Exception ignored) { }*/ } protected void showLoadingProgress(int i, String s) { /* try { int j = (appletWidth - 281) / 2; int k = (appletHeight - 148) / 2; j += 2; k += 90; loadingProgressPercent = i; loadingProgessText = s; int l = (277 * i) / 100; graphics.setColor(new Color(132, 132, 132)); if (hasRefererLogoNotused) graphics.setColor(new Color(220, 0, 0)); graphics.fillRect(j, k, l, 20); graphics.setColor(Color.black); graphics.fillRect(j + l, k, 277 - l, 20); graphics.setColor(new Color(198, 198, 198)); if (hasRefererLogoNotused) graphics.setColor(new Color(255, 255, 255)); drawString(graphics, s, fontTimesRoman15, j + 138, k + 10); } catch (Exception ignored) { }*/ } /* protected void drawString(Graphics g, String s, Font font, int i, int j) { Object obj; if (gameFrame == null) obj = this; else obj = gameFrame; FontMetrics fontmetrics = ((Component) (obj)).getFontMetrics(font); fontmetrics.stringWidth(s); g.setFont(font); g.drawString(s, i - fontmetrics.stringWidth(s) / 2, j + fontmetrics.getHeight() / 4); } private Image createImage(byte buff[]) { int i = buff[13] * 256 + buff[12]; int j = buff[15] * 256 + buff[14]; byte abyte1[] = new byte[256]; byte abyte2[] = new byte[256]; byte abyte3[] = new byte[256]; for (int k = 0; k < 256; k++) { abyte1[k] = buff[20 + k * 3]; abyte2[k] = buff[19 + k * 3]; abyte3[k] = buff[18 + k * 3]; } IndexColorModel indexcolormodel = new IndexColorModel(8, 256, abyte1, abyte2, abyte3); byte abyte4[] = new byte[i * j]; int l = 0; for (int i1 = j - 1; i1 >= 0; i1--) { for (int j1 = 0; j1 < i; j1++) abyte4[l++] = buff[786 + j1 + i1 * i]; } MemoryImageSource memoryimagesource = new MemoryImageSource(i, j, indexcolormodel, abyte4, 0, i); return createImage(memoryimagesource); }*/ protected byte[] readDataFile(String file, String description, int percent) { file = "./data204/" + file; int archiveSize = 0; int archiveSizeCompressed = 0; byte archiveData[] = null; try { showLoadingProgress(percent, "Loading " + description + " - 0%"); java.io.InputStream inputstream = Utility.openFile(file); DataInputStream datainputstream = new DataInputStream(inputstream); byte header[] = new byte[6]; datainputstream.readFully(header, 0, 6); archiveSize = ((header[0] & 0xff) << 16) + ((header[1] & 0xff) << 8) + (header[2] & 0xff); archiveSizeCompressed = ((header[3] & 0xff) << 16) + ((header[4] & 0xff) << 8) + (header[5] & 0xff); showLoadingProgress(percent, "Loading " + description + " - 5%"); int read = 0; archiveData = new byte[archiveSizeCompressed]; while (read < archiveSizeCompressed) { int length = archiveSizeCompressed - read; if (length > 1000) length = 1000; datainputstream.readFully(archiveData, read, length); read += length; showLoadingProgress(percent, "Loading " + description + " - " + (5 + (read * 95) / archiveSizeCompressed) + "%"); } datainputstream.close(); } catch (IOException ignored) { } showLoadingProgress(percent, "Unpacking " + description); if (archiveSizeCompressed != archiveSize) { byte decompressed[] = new byte[archiveSize]; BZLib.decompress(decompressed, archiveSize, archiveData, archiveSizeCompressed, 0); return decompressed; } else { return archiveData; } } protected Socket createSocket(String s, int i) throws IOException { Socket socket = new Socket(InetAddress.getByName(s), i); socket.setSoTimeout(30000); socket.setTcpNoDelay(true); return socket; } protected void startThread(Runnable runnable) { Thread thread = new Thread(runnable); thread.setDaemon(true); thread.start(); } }