/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 2000-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine is distributed in the hope that it will * * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.game; import totalcross.io.*; import totalcross.util.Properties; /** * The game options management class. <br> * <br> * The options are stored in a waba PDBFile object which is linked to the * application through the software creatorID. This causes the options database * deletion when the game with the same creatorID is erased. * <p> * The complete database name is composed by the game name 'appl' and its * creatorID, both provided during the engine initialization via the * GameEngineClient interface.<br> * The options database name is : ${appl}_OPT.${creatorID}.DATA * <p> * You can find a complete game API sample named 'Scape' in the TotalCross samples * folder.<br> * Here is some sample code: * * <pre> * import totalcross.game.*; * import totalcross.util.props.*; * ... * * <i>public class Ping extends <U>GameEngine</U></i> { * * // constructor * public Ping() * { * totalcross.sys.Settings.setPalmOSStyle(true); * * // define the game API setup attributes * * gameName = "Ping"; * * // when not run on device, appCreatorId does not always return the same value. * * gameCreatorID = Settings.onJavaSE ? totalcross.sys.Settings.appCreatorId:"PiNg"; * * gameVersion = 100; // v1.00 * gameHighscoresSize = 7; // store the best 7 highscores * gameRefreshPeriod = 75; // 75 ms refresh periods * gameIsDoubleBuffered = true; // used double buffering to prevent flashing display * gameDoClearScreen = true; // screen is cleared before each frame display * gameHasUI = false; // no UI elements, frame displays are optimized * ... * } * * // declare 2 game settings * * protected <B>Properties.Str</B> optUserName; * protected <B>Properties.Boolean</B> optSound; * * //--------------------------------------------------------- * // overload the API's game init event. * // this function is called when the game is launched. * //--------------------------------------------------------- * * <i>public void onGameInit()</i> { * * // access the game settings: 'username' & 'sound' * // if the properties do not yet exist, the default values are used * * <B>Options</B> settings=<U>getOptions</U>(); * * optUserName = settings.<B>declareString</B> ("userName","noname"); * optSound = settings.<B>declareBoolean</B> ("sound",false); * ... * * if (optSound.<B>value</B>) Sound.tone(1520,10); * * } * } * </pre> * * @author Frank Diebolt * @version 1.0 */ public class Options extends Properties { private PDBFile cat; private final static String dbName_suffix = "_OPT."; private final static String dbType = ".DATA"; private static final String duplicatedProperty = "OPT:duplicated:"; protected Options(GameEngine engine) { try { try { cat = new PDBFile(engine.gameName + dbName_suffix + engine.gameCreatorID + dbType, PDBFile.READ_WRITE); } catch (FileNotFoundException fnfe) { cat = new PDBFile(engine.gameName + dbName_suffix + engine.gameCreatorID + dbType, PDBFile.CREATE_EMPTY); cat.addRecord(100); } newVersion = engine.gameVersion; cat.setRecordPos(0); DataStream ds = new DataStream(cat); oldVersion = ds.readInt(); load(ds); } catch (Exception e) { e.printStackTrace(); } } /** * Declare a boolean option.<br> * This function tries to lookup the property in the Options database.<br> * If it fails, a new property with the default value specified is created. * * @param name * the property name. * @param value * the property default value. * @return a boolean property object. */ public Boolean declareBoolean(String name, boolean value) { Value v = get(name); if (v != null) { if (v.type == Boolean.TYPE) return (Boolean) v; throw new GameEngineException(duplicatedProperty + name); } Boolean b = new Boolean(value); put(name, b); return b; } /** * Declare a long option.<br> * This function tries to lookup the property in the Options database.<br> * If it fails, a new property with the default value specified is created. * * @param name * the property name. * @param value * the property default value. * @return a long property object. */ public Long declareLong(String name, long value) { Value v = get(name); if (v != null) { if (v.type == Long.TYPE) return (Long) v; throw new GameEngineException(duplicatedProperty + name); } Long b = new Long(value); put(name, b); return b; } /** * Declare an integer option.<br> * This function tries to lookup the property in the Options database.<br> * If it fails, a new property with the default value specified is created. * * @param name * the property name. * @param value * the property default value. * @return an integer property object. */ public Int declareInteger(String name, int value) { Value v = get(name); if (v != null) { if (v.type == Int.TYPE) return (Int) v; throw new GameEngineException(duplicatedProperty + name); } Int i = new Int(value); put(name, i); return i; } /** * Declare a double option.<br> * This function tries to lookup the property in the Options database.<br> * If it fails, a new property with the default value specified is created. * * @param name * the property name. * @param value * the property default value. * @return a double property object. */ public Double declareDouble(String name, double value) { Value v = get(name); if (v != null) { if (v.type == Double.TYPE) return (Double) v; throw new GameEngineException(duplicatedProperty + name); } Double d = new Double(value); put(name, d); return d; } /** * Declare a string option.<br> * This function tries to lookup the property in the Options database.<br> * If it fails, a new property with the default value specified is created. * * @param name * the property name. * @param value * the property default value. * @return a string property object. */ public Str declareString(String name, String value) { Value v = get(name); if (v != null) { if (v.type == Str.TYPE) return (Str) v; throw new GameEngineException(duplicatedProperty + name); } Str s = new Str(value); put(name, s); return s; } /** * The options database new version number. */ public int newVersion; /** * The options database old version number. */ public int oldVersion; /** * Get a property value given the key. * * @param key * name of the property * @return Value that can be casted to Properties.Str, Properties.Int,... * depending on the value type, that can be retrieved with the * <code>type</code> read-only property. */ public Properties.Value getProp(String key) { return get(key); } /** * stores the settings database. <br> * * @return false if an error occurs */ public boolean save() { // use this nice object to resize the options record try { ResizeRecord rs = new ResizeRecord(cat, 100); rs.restartRecord(0); DataStream ds = new DataStream(rs); ds.writeInt(newVersion); save(ds); } catch (totalcross.io.IOException e) { return false; } return true; } /** * closes the settings database. * * @throws IOException */ public void close() throws IOException { if (save()) cat.close(); } }