// Copyright 2011-2012 Paulo Augusto Peccin. See licence.txt distributed with this file.
package org.javatari.pc.room;
import java.awt.Component;
import java.security.AccessControlException;
import java.util.ArrayList;
import org.javatari.atari.cartridge.Cartridge;
import org.javatari.atari.console.Console;
import org.javatari.atari.network.ClientConsole;
import org.javatari.atari.network.RemoteReceiver;
import org.javatari.atari.network.RemoteTransmitter;
import org.javatari.atari.network.ServerConsole;
import org.javatari.parameters.Parameters;
import org.javatari.pc.cartridge.BuiltInROM;
import org.javatari.pc.cartridge.ROMLoader;
import org.javatari.pc.controls.AWTConsoleControls;
import org.javatari.pc.controls.JoystickConsoleControls;
import org.javatari.pc.room.settings.SettingsDialog;
import org.javatari.pc.savestate.FileSaveStateMedia;
import org.javatari.pc.screen.DesktopScreenWindow;
import org.javatari.pc.screen.Screen;
import org.javatari.pc.speaker.Speaker;
import org.javatari.utils.Terminator;
public class Room {
protected Room() {
super();
}
public void powerOn() {
screen.powerOn();
speaker.powerOn();
awtControls.powerOn();
insertCartridgeProvidedIfNoneInserted(); // Will power Console ON if Cartridge is provided
if (currentConsole.cartridgeSocket().inserted() != null && !currentConsole.powerOn) currentConsole.powerOn();
}
public void powerOff() {
if (currentConsole != null) currentConsole.extendedPowerOff();
awtControls.powerOff();
speaker.powerOff();
screen.powerOff();
}
public Console currentConsole() {
return currentConsole;
}
public Console standaloneCurrentConsole() {
if (currentConsole != standaloneConsole) throw new IllegalStateException("Not a Standalone Room");
return standaloneConsole;
}
public ServerConsole serverCurrentConsole() {
if (currentConsole != serverConsole) throw new IllegalStateException("Not a Server Room");
return serverConsole;
}
public ClientConsole clientCurrentConsole() {
if (currentConsole != clientConsole) throw new IllegalStateException("Not a Client Room");
return clientConsole;
}
public Screen screen() {
return screen;
}
public Speaker speaker() {
return speaker;
}
public AWTConsoleControls awtControls() {
return awtControls;
}
public JoystickConsoleControls joystickControls() {
return awtControls.joystickControls();
}
public FileSaveStateMedia stateMedia() {
return stateMedia;
}
public boolean isStandaloneMode() {
return currentConsole == standaloneConsole;
}
public boolean isServerMode() {
return currentConsole == serverConsole;
}
public boolean isClientMode() {
return currentConsole == clientConsole;
}
public void morphToStandaloneMode() {
if (isStandaloneMode()) return;
powerOff();
Cartridge lastCartridge = isClientMode() ? cartridgeProvided : currentConsole.cartridgeSocket().inserted();
if (standaloneConsole == null) buildAndPlugStandaloneConsole();
else plugConsole(standaloneConsole);
adjustPeripheralsToStandaloneOrServerOperation();
currentConsole.cartridgeSocket().insert(lastCartridge, false);
powerOn();
}
public void morphToServerMode() {
if (isServerMode()) return;
powerOff();
Cartridge lastCartridge = isClientMode() ? cartridgeProvided : currentConsole.cartridgeSocket().inserted();
if (serverConsole == null) buildAndPlugServerConsole();
else plugConsole(serverConsole);
adjustPeripheralsToStandaloneOrServerOperation();
currentConsole.cartridgeSocket().insert(lastCartridge, false);
powerOn();
}
public void morphToClientMode() {
if (isClientMode()) return;
powerOff();
if (clientConsole == null) buildAndPlugClientConsole();
else plugConsole(clientConsole);
adjustPeripheralsToClientOperation();
powerOn();
}
public void openSettings(Component parent) {
if (settingsDialog == null) settingsDialog = new SettingsDialog(this);
settingsDialog.open(parent);
}
public void destroy() {
powerOff();
if (standaloneConsole != null) standaloneConsole.destroy();
if (serverConsole != null) serverConsole.destroy();
if (clientConsole != null) clientConsole.destroy();
screen.destroy();
speaker.destroy();
awtControls.destroy();
if (settingsDialog != null) {
settingsDialog.setVisible(false);
settingsDialog.dispose();
}
currentRoom = null;
}
protected void buildPeripherals() {
// PC interfaces for Video, Audio, Controls, Cartridge and SaveState
if (screen != null) throw new IllegalStateException();
screen = buildScreenPeripheral();
speaker = new Speaker();
awtControls = new AWTConsoleControls();
awtControls.connectScreen(screen);
stateMedia = new FileSaveStateMedia();
}
protected Screen buildScreenPeripheral() {
return buildDesktopScreenPeripheral();
}
public DesktopScreenWindow buildDesktopScreenPeripheral() {
return new DesktopScreenWindow();
}
private void plugConsole(Console console) {
if (currentConsole == console) return;
currentConsole = console;
screen.connect(currentConsole.videoOutput(), currentConsole.controlsSocket(), currentConsole.cartridgeSocket(), currentConsole.saveStateSocket());
speaker.connect(currentConsole.audioOutput());
awtControls.connect(currentConsole.controlsSocket(), currentConsole.cartridgeSocket());
stateMedia.connect(currentConsole.saveStateSocket());
}
private void insertCartridgeProvidedIfNoneInserted() {
if (currentConsole.cartridgeSocket().inserted() != null) return;
loadCartridgeProvided();
if (cartridgeProvided != null) currentConsole.cartridgeSocket().insert(cartridgeProvided, true);
}
private void loadCartridgeProvided() {
if (triedToLoadCartridgeProvided) return;
triedToLoadCartridgeProvided = true;
if (isClientMode()) return;
// First try to load the first built-in ROM
ArrayList<BuiltInROM> builtInROMs = BuiltInROM.all();
if (builtInROMs.size() > 0) {
cartridgeProvided = ROMLoader.load(builtInROMs.get(0));
if (cartridgeProvided == null) Terminator.terminate(); // Error loading Cartridge
Parameters.SCREEN_CARTRIDGE_CHANGE = false; // Disable manual Cartridge change
screen.monitor().setCartridgeChangeEnabled(false);
} else {
// If none try to load the Cartridge passed as argument
if (Parameters.mainArg != null) {
cartridgeProvided = ROMLoader.load(Parameters.mainArg, true);
if (cartridgeProvided == null) Terminator.terminate(); // Error loading Cartridge
}
}
}
protected Console buildAndPlugStandaloneConsole() {
if (standaloneConsole != null) throw new IllegalStateException();
standaloneConsole = new Console();
plugConsole(standaloneConsole);
return standaloneConsole;
}
protected ServerConsole buildAndPlugServerConsole() {
if (serverConsole != null) throw new IllegalStateException();
RemoteTransmitter remoteTransmitter = new RemoteTransmitter();
serverConsole = new ServerConsole(remoteTransmitter);
plugConsole(serverConsole);
return serverConsole;
}
protected ClientConsole buildAndPlugClientConsole() {
RemoteReceiver remoteReceiver = new RemoteReceiver();
clientConsole = new ClientConsole(remoteReceiver);
plugConsole(clientConsole);
return clientConsole;
}
protected void adjustPeripheralsToStandaloneOrServerOperation() {
awtControls.p1ControlsMode(false);
screen.monitor().setCartridgeChangeEnabled(Parameters.SCREEN_CARTRIDGE_CHANGE);
}
protected void adjustPeripheralsToClientOperation() {
awtControls.p1ControlsMode(true);
screen.monitor().setCartridgeChangeEnabled(false);
}
public static Room currentRoom() {
return currentRoom;
}
public static Room buildStandaloneRoom() {
if (currentRoom != null) throw new IllegalStateException("Room already built");
currentRoom = new Room();
currentRoom.buildPeripherals();
currentRoom.adjustPeripheralsToStandaloneOrServerOperation();
currentRoom.buildAndPlugStandaloneConsole();
return currentRoom;
}
public static Room buildServerRoom() {
if (currentRoom != null) throw new IllegalStateException("Room already built");
currentRoom = new Room();
currentRoom.buildPeripherals();
currentRoom.adjustPeripheralsToStandaloneOrServerOperation();
currentRoom.buildAndPlugServerConsole();
return currentRoom;
}
public static Room buildClientRoom() {
if (currentRoom != null) throw new IllegalStateException("Room already built");
currentRoom = new Room();
currentRoom.buildPeripherals();
currentRoom.adjustPeripheralsToClientOperation();
currentRoom.buildAndPlugClientConsole();
return currentRoom;
}
public void exit() {
try {
System.out.print("Terminating Javatari... ");
destroy();
System.out.println("Terminated.");
System.exit(0);
} catch(AccessControlException ex) {
// Ignore
}
}
protected Console currentConsole;
protected Console standaloneConsole;
protected ServerConsole serverConsole;
protected ClientConsole clientConsole;
protected Screen screen;
protected Speaker speaker;
protected AWTConsoleControls awtControls;
protected FileSaveStateMedia stateMedia;
protected Cartridge cartridgeProvided;
protected boolean triedToLoadCartridgeProvided = false;
protected SettingsDialog settingsDialog;
protected static Room currentRoom;
}