Package org.javatari.pc.cartridge

Source Code of org.javatari.pc.cartridge.ROMLoader

// Copyright 2011-2012 Paulo Augusto Peccin. See licence.txt distributed with this file.

package org.javatari.pc.cartridge;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.AccessControlException;
import java.util.Arrays;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.jnlp.FileContents;
import javax.swing.JOptionPane;

import org.javatari.atari.cartridge.Cartridge;
import org.javatari.atari.cartridge.CartridgeCreator;
import org.javatari.atari.cartridge.CartridgeDatabase;
import org.javatari.atari.cartridge.ROM;
import org.javatari.atari.cartridge.ROMFormatUnsupportedException;
import org.javatari.parameters.Parameters;


public final class ROMLoader {

  public static Cartridge load(String url, boolean provided) {
    try {
      return load(new URL(url), provided);
    } catch (MalformedURLException ex) {
      generalErrorMessage(ex, url);
    }
    return null;
  }

  public static Cartridge load(File file) {
    try {
      return load(file.toURI().toURL(), false);
    } catch (MalformedURLException ex) {
      generalErrorMessage(ex, file.getPath());
    } catch (AccessControlException ex) {
      generalErrorMessage(ex, file.getPath());
    }
    return null;
  }

  public static Cartridge load(URL url, boolean provided) {
    InputStream stream = null;
    try {
      URLConnection conn = url.openConnection();
      conn.setConnectTimeout(5000);
      stream = conn.getInputStream();
      return createFromExternalURL(stream, url.toString(), provided);
    } catch (AccessControlException ex) {
      generalErrorMessage(ex, url.toString());
    } catch (IOException ex) {
      generalErrorMessage(ex, url.toString());
    }
    return null;
  }

  public static Cartridge load(FileContents fileContents) {
    String fileName = "<unknown>";
    try {
      fileName = fileContents.getName();
      InputStream stream = fileContents.getInputStream();
      return createFromExternalURL(stream, fileName, false);
    } catch (IOException ex) {
      generalErrorMessage(ex, fileName);
      return null;
    }
  }
 
  public static Cartridge load(BuiltInROM builtInROM) {
    if (builtInROM.label != null) Parameters.CARTRIDGE_LABEL = builtInROM.label;
    if (builtInROM.labelColors != null) Parameters.setCartridgeLabelColors(builtInROM.labelColors);
    return load(builtInROM.url, true);
  }

  private static Cartridge createFromExternalURL(InputStream stream, String romURL, boolean provided) {
    System.out.println("Loading Cartridge from: " + romURL);
    BufferedInputStream buffer = bufferedStream(stream);
    try {
      try {
        // First try reading and creating directly
        return createCartridge(buffer, romURL, provided);
      } catch (ROMFormatUnsupportedException ex) {
        // If it fails, try assuming its a compressed stream (zip)
        buffer.reset();
        InputStream romFromZIP = getFirstROMFromZIP(buffer);
        if (romFromZIP == null) throw ex;  // Probably not zipped either
        return createCartridge(romFromZIP, romURL, provided);
      }
    } catch (ROMFormatUnsupportedException ex) {
      romFormatUnsupportedErrorMessage(ex, romURL);
    } catch (IOException ex) {
      generalErrorMessage(ex, romURL);
    } finally {
      try {
        stream.close();
        buffer.close();
      } catch (IOException e) {}
    }
    return null;
  }

  private static Cartridge createCartridge(InputStream stream, String romURL, boolean provided) throws IOException, ROMFormatUnsupportedException {
    ROM rom = createROM(stream, romURL);
    if (provided) CartridgeDatabase.adjustInfoOfROMProvided(rom);
    return CartridgeCreator.create(rom);
  }

  private static ROM createROM(InputStream stream, String romURL) throws IOException {
    byte[] buffer = new byte[MAX_STREAM_SIZE];
    int totalRead = 0;
    do {
      int read = stream.read(buffer, totalRead, MAX_STREAM_SIZE - totalRead);
      if (read == -1) break// End of Stream
      totalRead += read;
    } while(totalRead < MAX_STREAM_SIZE);
    byte[] content = (totalRead > 0) ? Arrays.copyOf(buffer, totalRead) : new byte[0];
    return new ROM(romURL.trim(), content);
  }

  private static InputStream getFirstROMFromZIP(InputStream stream) throws IOException, ROMFormatUnsupportedException {
    ZipInputStream zipStream = new ZipInputStream(stream);
    while(true) {
      ZipEntry entry = zipStream.getNextEntry();
      if (entry == null) return null;
      String entryName = entry.getName().toUpperCase();
      for (int i = 0; i < VALID_LOAD_FILE_EXTENSIONS.length; i++)
        if (entryName.endsWith(VALID_LOAD_FILE_EXTENSIONS[i].toUpperCase()))
          return zipStream;
    }
  }

  private static BufferedInputStream bufferedStream(InputStream stream) {
    BufferedInputStream buf = new BufferedInputStream(stream, MAX_STREAM_SIZE);
    buf.mark(MAX_STREAM_SIZE);
    return buf;
  }

  private static void generalErrorMessage(Exception ex, String location) {
    System.out.println("Could not load Cartridge from: " + location);
    System.out.println(ex);
    String tLoc = location == null ? "" : location.trim();
    if (tLoc.length() > 80) tLoc = tLoc.substring(0, 79) + "...";
    JOptionPane.showMessageDialog(
      null,
      "Could not load Cartridge from:\n" + tLoc + "\n\n" + ex.getClass().getSimpleName() + ": " + ex.getMessage(),
      "Error loading Cartridge",
      JOptionPane.ERROR_MESSAGE
    );
  }

  private static void romFormatUnsupportedErrorMessage(ROMFormatUnsupportedException ex, String location) {
    System.out.println("Could not load Cartridge from: " + location);
    System.out.println(ex.getMessage());
    String tLoc = location == null ? "" : location.trim();
    if (tLoc.length() > 80) tLoc = tLoc.substring(0, 79) + "...";
    JOptionPane.showMessageDialog(
      null,
      "Could not load Cartridge from:\n" + tLoc + "\n\n" + ex.getMessage(),
      "Error loading Cartridge",
      JOptionPane.ERROR_MESSAGE
    );
  }


  private static final int MAX_ROM_SIZE = 512 * 1024;
  private static final int MAX_STREAM_SIZE = MAX_ROM_SIZE + 1024;

  public static final String   VALID_LOAD_FILES_DESC = "ROM and Savestate files (.bin .rom .a26 .zip .jat)";
  public static final String[] VALID_LOAD_FILE_EXTENSIONS = {"bin", "rom", "a26", "zip", "jat"};
 
  public static final String   VALID_STATE_FILE_DESC = "Javatari Savestate files (.jat)";
  public static final String   VALID_STATE_FILE_EXTENSION = "jat";
 
}
TOP

Related Classes of org.javatari.pc.cartridge.ROMLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.