diff -r 4feced261c68 -r de822cd3df3a project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java --- a/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java Tue Jan 21 22:38:13 2014 +0100 +++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java Tue Jan 21 22:43:06 2014 +0100 @@ -1,1263 +1,1263 @@ -/* - * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game - * Copyright (C) 2012 Simeon Maxein - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program 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. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -package org.hedgewars.hedgeroid.frontlib; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.hedgewars.hedgeroid.Datastructures.Hog; -import org.hedgewars.hedgeroid.Datastructures.MapRecipe; -import org.hedgewars.hedgeroid.Datastructures.MetaScheme; -import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Mod; -import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Setting; -import org.hedgewars.hedgeroid.Datastructures.GameConfig; -import org.hedgewars.hedgeroid.Datastructures.Room; -import org.hedgewars.hedgeroid.Datastructures.Scheme; -import org.hedgewars.hedgeroid.Datastructures.Team; -import org.hedgewars.hedgeroid.Datastructures.TeamInGame; -import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; -import org.hedgewars.hedgeroid.Datastructures.Weaponset; - -import com.sun.jna.Callback; -import com.sun.jna.Library; -import com.sun.jna.Memory; -import com.sun.jna.Pointer; -import com.sun.jna.PointerType; -import com.sun.jna.Structure; - -/** - * Here is an introduction to the most important aspects of the JNA code. - * - * This interface permits access to the Hedgewars frontend library (frontlib) - * from Java. Each function directly contained in the Frontlib interface - * represents a mapped C function. The Structure classes (ending in -Struct) are - * mappings of C structs, and the PointerType classes (ending in -Ptr) represent - * pointers to structs. - * - * Quick notes for USING these classes from outside this package: - * - * Usage should be fairly straightforward, but there are a few surprising - * gotchas. First, when you implement callbacks, YOU are responsible for - * ensuring that the callback objects are not garbage-collected while they might - * still be called! So make sure you keep them in member variables or similar, - * because Java will not know if there are still native references to them. - * - * When using Frontlib from outside its package, you only interact with structs - * via the PointerType classes. They allow you to get at the data of the struct - * with a function called deref(), which creates a plain normal Java object - * representing the data (e.g. SchemePtr.deref() will give you a Scheme object). - * - * Remember that you usually have to destroy structs that you receive from the - * library, because they are owned by the native code, not Java. The recommended - * pattern for most cases is to call deref() on the pointer to get a Java object - * (that you can keep as long as you like), and then immediately destroy the - * struct if it needs destroying. To find out whether and how the struct needs - * to be destroyed, see the library's documentation of the function that you got - * the struct from. - * - * To pass new structs to the library, you can use the static createJavaOwned() - * function in each PointerType, which creates a new struct from the Java object - * you provide, and returns a pointer to that struct that you can pass to - * library functions. This new structure's memory is owned and managed by Java - * code, so do not destroy it with frontlib functions! - * - * There is a slight mismatch between the data model for the game setup. The - * frontlib supports setting initial health and weaponset per-hog, because the - * engine allows for that, but currently neither the networking protocol nor the - * PC frontend support this feature, so the Android version does not take - * advantage of it either and treats both as per-game settings. The initial - * health is contained in the game scheme, the weaponset is explicitly part of - * the GameConfig. When converting GameConfig to a native flib_gamesetup, both - * are automatically copied to all hogs in the game, and for the reverse - * conversion the weaponset of the first hog of the first team is used as the - * GameConfig weaponset. This means that GameConfig.weaponset will be null if - * there are no teams in the game. - * - * When starting a network game, you only need to query the GameSetupPtr from - * the netconn and use it to create the gameconn - this is preferable to using - * your own recreation of the game setup, because that way the same piece of - * code is used to determine the game setup on all platforms. - * - * The "context" parameter of the callbacks is never needed here because JNA - * generates function code for each callback object. Don't worry about it, just - * pass null for context and ignore the context parameter in the callbacks. - * - * Finally, the library functions are documented in the actual library, not - * here, so check the docs there to find out what exactly each function does! - * - * Notes about the structure of this class (for the next one who has to touch - * this...): - * - * Java/C interop is quite fiddly and error-prone, so as long as things work, - * try to stick to the established patterns. - * - * Structure types should always be hidden from the outside world, because they - * can be misused too easily. For example, if you get a Structure from the - * library, change a String value in there and pass it back, JNA will re-write - * that string using Java-owned memory without freeing the old native-owned - * string, which causes a memory leak and possibly a double-free or other Bad - * Things (tm). To avoid problems like this, Structure types are only used - * internally, to map existing structures to Java types (without modifying them) - * or to create brand-new, Java-owned structures. Both operations are exposed to - * the outside through the PointerType classes corresponding to the structures - * in question. - * - * Since all of the struct mapping happens in Java, it is never checked against - * the actual struct declarations in the library. That means strange things can - * start happening at runtime if the frontlib structs are modified without - * changing the mappings here to match. This also applies to the function - * signatures: JNA checks whether the functions actually exist when loading the - * library, but it has no way of knowing whether the signatures are correct. If - * the signatures here deviate from those in the frontlib, you might get stack - * corruption. - * - * In order to check at least the function signatures, take a look at the file - * extra/jnacontrol.c in the frontlib sources. You can validate whether the - * function signatures are still correct by copy-pasting them into jnaControl.c - * and compiling it against the frontlib headers. The typedefs and #defines in - * that file will make the compiler see the Java method signatures as C function - * declarations. Since the same functions are already declared in the frontlib - * headers, the compiler will give you errors if the signatures don't match. - */ -public interface Frontlib extends Library { - public static class NetconnPtr extends PointerType { } - public static class MapconnPtr extends PointerType { } - public static class GameconnPtr extends PointerType { } - - public static class MetaschemePtr extends PointerType { - public MetaScheme deref() { - return deref(getPointer()); - } - - public static MetaScheme deref(Pointer p) { - MetaschemeStruct struct = new MetaschemeStruct(p); - struct.read(); - return struct.toMetaScheme(); - } - } - - public static class RoomArrayPtr extends PointerType { - public Room[] getRooms(int count) { - Pointer ptr = getPointer(); - if(ptr == null) { - return new Room[0]; - } - Pointer[] untypedPtrs = ptr.getPointerArray(0, count); - Room[] result = new Room[count]; - for(int i=0; i deref() { - WeaponsetListStruct struct = new WeaponsetListStruct(getPointer()); - struct.read(); - return struct.toWeaponsetList(); - } - - public static WeaponsetListPtr createJavaOwned(List list) { - WeaponsetListPtr result = new WeaponsetListPtr(); - result.javaOwnedInstance = new WeaponsetListStruct(); - result.javaOwnedInstance.fillFrom(list); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class MapRecipePtr extends PointerType { - private MapRecipeStruct javaOwnedInstance; - - public MapRecipe deref() { - MapRecipeStruct struct = new MapRecipeStruct(getPointer()); - struct.read(); - return struct.toMapRecipe(); - } - - public static MapRecipePtr createJavaOwned(MapRecipe recipe) { - MapRecipePtr result = new MapRecipePtr(); - result.javaOwnedInstance = new MapRecipeStruct(); - result.javaOwnedInstance.fillFrom(recipe); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class SchemePtr extends PointerType { - private SchemeStruct javaOwnedInstance; - - public Scheme deref() { - SchemeStruct struct = new SchemeStruct(getPointer()); - struct.read(); - return struct.toScheme(); - } - - public static SchemePtr createJavaOwned(Scheme scheme) { - SchemePtr result = new SchemePtr(); - result.javaOwnedInstance = new SchemeStruct(); - result.javaOwnedInstance.fillFrom(scheme); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class SchemelistPtr extends PointerType { - private SchemelistStruct javaOwnedInstance; - - public List deref() { - SchemelistStruct struct = new SchemelistStruct(getPointer()); - struct.read(); - return struct.toSchemeList(); - } - - public static SchemelistPtr createJavaOwned(List schemes) { - SchemelistPtr result = new SchemelistPtr(); - result.javaOwnedInstance = new SchemelistStruct(); - result.javaOwnedInstance.fillFrom(schemes); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class GameSetupPtr extends PointerType { - private GameSetupStruct javaOwnedInstance; - - public GameConfig deref() { - GameSetupStruct struct = new GameSetupStruct(getPointer()); - struct.read(); - return struct.toGameConfig(); - } - - public static GameSetupPtr createJavaOwned(GameConfig conf) { - GameSetupPtr result = new GameSetupPtr(); - result.javaOwnedInstance = new GameSetupStruct(); - result.javaOwnedInstance.fillFrom(conf); - result.javaOwnedInstance.autoWrite(); - result.setPointer(result.javaOwnedInstance.getPointer()); - return result; - } - } - - public static class ByteArrayPtr extends PointerType { - public byte[] deref(int size) { - return getPointer().getByteArray(0, size); - } - - public static byte[] deref(ByteArrayPtr ptr, int size) { - if(ptr==null && size==0) { - return null; - } else { - return ptr.deref(size); - } - } - - public static ByteArrayPtr createJavaOwned(byte[] buffer) { - if(buffer == null || buffer.length == 0) { - return null; - } - // no need for javaOwnedInstance here because PointerType - // remembers the memory as its Pointer - Pointer ptr = new Memory(buffer.length); - ptr.write(0, buffer, 0, buffer.length); - ByteArrayPtr result = new ByteArrayPtr(); - result.setPointer(ptr); - return result; - } - } - - static class HogStruct extends Structure { - public static class ByVal extends HogStruct implements Structure.ByValue {} - public static class ByRef extends HogStruct implements Structure.ByReference {} - - public HogStruct() { super(); } - public HogStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("name", "hat", "rounds", "kills", "deaths", "suicides", "difficulty", "initialHealth", "weaponset"); - } - - public void fillFrom(Hog hog) { - difficulty = hog.level; - hat = hog.hat; - name = hog.name; - } - - public Hog toHog() { - return new Hog(name, hat, difficulty); - } - - public String name; - public String hat; - - public int rounds; - public int kills; - public int deaths; - public int suicides; - - public int difficulty; - - public int initialHealth; - public WeaponsetStruct.ByRef weaponset; - } - - static class TeamStruct extends Structure { - public static class ByVal extends TeamStruct implements Structure.ByValue {} - public static class ByRef extends TeamStruct implements Structure.ByReference {} - - public TeamStruct() { super(); } - public TeamStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("hogs", "name", "grave", "fort", "voicepack", "flag", "bindings", "bindingCount", "rounds", "wins", "campaignProgress", "colorIndex", "hogsInGame", "remoteDriven", "ownerName"); - } - - public void fillFrom(Team team, TeamIngameAttributes attrs) { - if(team != null) { - name = team.name; - grave = team.grave; - flag = team.flag; - voicepack = team.voice; - fort = team.fort; - if(team.hogs.size() != Team.HEDGEHOGS_PER_TEAM) { - throw new IllegalArgumentException(); - } - for(int i=0; i hogList = new ArrayList(); - for(int i=0; i getFieldOrder() { - return Arrays.asList("loadout", "crateprob", "crateammo", "delay", "name"); - } - - public void fillFrom(Weaponset weaponset) { - fillWeaponInfo(loadout, weaponset.loadout); - fillWeaponInfo(crateprob, weaponset.crateProb); - fillWeaponInfo(crateammo, weaponset.crateAmmo); - fillWeaponInfo(delay, weaponset.delay); - name = weaponset.name; - } - - private static void fillWeaponInfo(byte[] array, String str) { - for(int i=0; i getFieldOrder() { - return Arrays.asList("weaponset"); - } - - public WeaponsetStruct.ByRef weaponset; - } - - static class WeaponsetListStruct extends Structure { - public static class ByVal extends WeaponsetListStruct implements Structure.ByValue {} - public static class ByRef extends WeaponsetListStruct implements Structure.ByReference {} - - public WeaponsetListStruct() { super(); } - public WeaponsetListStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("weaponsetCount", "weaponsets"); - } - - public void fillFrom(List list) { - weaponsetCount = list.size(); - if(weaponsetCount<=0) { - weaponsets = null; - } else { - weaponsets = new WeaponsetPointerByReference(); - Structure[] structs = weaponsets.toArray(weaponsetCount); - - for(int i=0; i toWeaponsetList() { - if(weaponsetCount<=0) { - return new ArrayList(); - } else { - List list = new ArrayList(weaponsetCount); - Structure[] structs = weaponsets.toArray(weaponsetCount); - - for(int i=0; i getFieldOrder() { - return Arrays.asList("inProgress", "name", "playerCount", "teamCount", "owner", "map", "scheme", "weapons"); - } - - public Room toRoomlistRoom() { - return new Room(name, map, scheme, weapons, owner, playerCount, teamCount, inProgress); - } - - public boolean inProgress; - public String name; - public int playerCount; - public int teamCount; - public String owner; - public String map; - public String scheme; - public String weapons; - } - - static class MapRecipeStruct extends Structure { - public static class ByVal extends MapRecipeStruct implements Structure.ByValue {} - public static class ByRef extends MapRecipeStruct implements Structure.ByReference {} - - public MapRecipeStruct() { super(); } - public MapRecipeStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("mapgen", "name", "seed", "theme", "drawData", "drawDataSize", "templateFilter", "mazeSize"); - } - - public void fillFrom(MapRecipe map) { - mapgen = map.mapgen; - name = map.name; - seed = map.seed; - theme = map.theme; - byte[] buf = map.getDrawData(); - drawData = ByteArrayPtr.createJavaOwned(buf); - drawDataSize = NativeSizeT.valueOf(buf==null ? 0 : buf.length); - templateFilter = map.templateFilter; - mazeSize = map.mazeSize; - } - - public MapRecipe toMapRecipe() { - byte[] buf = ByteArrayPtr.deref(drawData, drawDataSize.intValue()); - return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, buf); - } - - public int mapgen; - public String name; - public String seed; - public String theme; - public ByteArrayPtr drawData; - public NativeSizeT drawDataSize; - public int templateFilter; - public int mazeSize; - } - - static class MetaschemeSettingStruct extends Structure { - public static class ByVal extends MetaschemeSettingStruct implements Structure.ByValue {} - public static class ByRef extends MetaschemeSettingStruct implements Structure.ByReference {} - - public MetaschemeSettingStruct() { super(); } - public MetaschemeSettingStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("name", "engineCommand", "maxMeansInfinity", "times1000", "min", "max", "def"); - } - - public void fillFrom(Setting setting) { - name = setting.name; - engineCommand = setting.engineCommand; - maxMeansInfinity = setting.maxMeansInfinity; - times1000 = setting.times1000; - min = setting.min; - max = setting.max; - def = setting.def; - } - - public MetaScheme.Setting toMetaSchemeSetting() { - return new MetaScheme.Setting(name, engineCommand, maxMeansInfinity, times1000, min, max, def); - } - - public String name; - public String engineCommand; - public boolean maxMeansInfinity; - public boolean times1000; - public int min; - public int max; - public int def; - } - - static class MetaschemeModStruct extends Structure { - public static class ByVal extends MetaschemeModStruct implements Structure.ByValue {} - public static class ByRef extends MetaschemeModStruct implements Structure.ByReference {} - - public MetaschemeModStruct() { super(); } - public MetaschemeModStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("name", "bitmaskIndex"); - } - - public void fillFrom(Mod mod) { - name = mod.name; - bitmaskIndex = mod.bitmaskIndex; - } - - public MetaScheme.Mod toMetaSchemeMod() { - return new MetaScheme.Mod(name, bitmaskIndex); - } - - public String name; - public int bitmaskIndex; - - } - - static class MetaschemeStruct extends Structure { - public static class ByVal extends MetaschemeStruct implements Structure.ByValue {} - public static class ByRef extends MetaschemeStruct implements Structure.ByReference {} - - public MetaschemeStruct() { super(); } - public MetaschemeStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("settingCount", "modCount", "settings", "mods"); - } - - /** - * Only use on native-owned structs! - * Calling this method on a Java-owned struct could cause garbage collection of referenced - * structures. - */ - public MetaScheme toMetaScheme() { - List settingList = new ArrayList(settingCount); - List modList = new ArrayList(modCount); - - Structure[] settingStructs = settings.toArray(settingCount); - Structure[] modStructs = mods.toArray(modCount); - - for(int i=0; i getFieldOrder() { - return Arrays.asList("name", "settings", "mods"); - } - - public void fillFrom(Scheme scheme) { - MetaScheme meta = MetaScheme.INSTANCE; - name = scheme.name; - settings = new Memory(AndroidTypeMapper.NATIVE_INT_SIZE * meta.settings.size()); - for(int i=0; i settingsMap = new HashMap(); - MetaScheme meta = MetaScheme.INSTANCE; - for(int i=0; i modsMap = new HashMap(); - for(int i=0; i getFieldOrder() { - return Arrays.asList("scheme"); - } - - public SchemeStruct.ByRef scheme; - } - - static class SchemelistStruct extends Structure { - public static class ByVal extends SchemelistStruct implements Structure.ByValue {} - public static class ByRef extends SchemelistStruct implements Structure.ByReference {} - - public SchemelistStruct() { super(); } - public SchemelistStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("schemeCount", "schemes"); - } - - public void fillFrom(List schemeList) { - schemeCount = schemeList.size(); - if(schemeCount<=0) { - schemes = null; - } else { - schemes = new SchemePointerByReference(); - Structure[] schemePtrStructs = schemes.toArray(schemeCount); - - for(int i=0; i toSchemeList() { - if(schemeCount<=0) { - return new ArrayList(); - } else { - List schemeList = new ArrayList(schemeCount); - - Structure[] schemePtrStructs = schemes.toArray(schemeCount); - - for(int i=0; i getFieldOrder() { - return Arrays.asList("team"); - } - - public TeamStruct.ByRef team; - } - - static class TeamlistStruct extends Structure { - public static class ByVal extends TeamlistStruct implements Structure.ByValue {} - public static class ByRef extends TeamlistStruct implements Structure.ByReference {} - - public TeamlistStruct() { super(); } - public TeamlistStruct(Pointer ptr) { super(ptr); } - - @Override - protected List getFieldOrder() { - return Arrays.asList("teamCount", "teams"); - } - - public void fillFrom(List teamList, WeaponsetStruct.ByRef weaponset, int initialHealth) { - teamCount = teamList.size(); - if(teamCount <= 0) { - teams = null; - } else { - teams = new TeamPointerByReference(); - Structure[] teamPtrStructs = teams.toArray(teamCount); - - for(int i=0; i toTeamInGameList() { - if(teamCount<=0) { - return new ArrayList(); - } else { - List result = new ArrayList(teamCount); - Structure[] structs = teams.toArray(teamCount); - - for(int i=0; i getFieldOrder() { - return Arrays.asList("script", "gamescheme", "map", "teamlist"); - } - - public void fillFrom(GameConfig conf) { - script = conf.style; - gamescheme = new SchemeStruct.ByRef(); - gamescheme.fillFrom(conf.scheme); - map = new MapRecipeStruct.ByRef(); - map.fillFrom(conf.map); - - /* - * At this point we deviate from the usual copying pattern because the frontlib - * expects per-hog weapons and initial health, but the UI models them as per- - * game, so we extract them from the config here and pass them on to be included - * in each hog. - */ - WeaponsetStruct.ByRef wss = new WeaponsetStruct.ByRef(); - wss.fillFrom(conf.weaponset); - int initialHealth = conf.scheme.getHealth(); - - teamlist = new TeamlistStruct.ByRef(); - teamlist.fillFrom(conf.teams, wss, initialHealth); - } - - public GameConfig toGameConfig() { - Scheme scheme = gamescheme != null ? gamescheme.toScheme() : null; - MapRecipe mapRecipe = map != null ? map.toMapRecipe() : null; - List teams = teamlist != null ? teamlist.toTeamInGameList() : null; - - WeaponsetStruct weaponsetStruct = teamlist != null && teamlist.teamCount>0 ? teamlist.teams.team.hogs[0].weaponset : null; - Weaponset weaponset = weaponsetStruct != null ? weaponsetStruct.toWeaponset() : null; - return new GameConfig(script, scheme, mapRecipe, teams, weaponset); - } - - public String script; - public SchemeStruct.ByRef gamescheme; - public MapRecipeStruct.ByRef map; - public TeamlistStruct.ByRef teamlist; - } - - /* - * Callback interfaces. The context parameter is never needed here and - * should always be ignored. Be sure to keep a reference to each callback - * for as long as they might be called by native code, to avoid premature - * garbage collection. - */ - public static interface VoidCallback extends Callback { - void callback(Pointer context); - } - - public static interface StrCallback extends Callback { - void callback(Pointer context, String arg1); - } - - public static interface IntCallback extends Callback { - void callback(Pointer context, int arg1); - } - - public static interface IntStrCallback extends Callback { - void callback(Pointer context, int arg1, String arg2); - } - - public static interface StrIntCallback extends Callback { - void callback(Pointer context, String arg1, int arg2); - } - - public static interface StrStrCallback extends Callback { - void callback(Pointer context, String arg1, String arg2); - } - - public static interface StrStrBoolCallback extends Callback { - void callback(Pointer context, String arg1, String arg2, boolean arg3); - } - - public static interface RoomCallback extends Callback { - void callback(Pointer context, RoomPtr arg1); - } - - public static interface RoomListCallback extends Callback { - void callback(Pointer context, RoomArrayPtr arg1, int count); - } - - public static interface StrRoomCallback extends Callback { - void callback(Pointer context, String arg1, RoomPtr arg2); - } - - public static interface BoolCallback extends Callback { - void callback(Pointer context, boolean arg1); - } - - public static interface StrBoolCallback extends Callback { - void callback(Pointer context, String arg1, boolean arg2); - } - - public static interface TeamCallback extends Callback { - void callback(Pointer context, TeamPtr arg1); - } - - public static interface BytesCallback extends Callback { - void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size); - } - - public static interface BytesBoolCallback extends Callback { - void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size, boolean arg3); - } - - public static interface SchemeCallback extends Callback { - void callback(Pointer context, SchemePtr arg1); - } - - public static interface MapIntCallback extends Callback { - void callback(Pointer context, MapRecipePtr arg1, int arg2); - } - - public static interface WeaponsetCallback extends Callback { - void callback(Pointer context, WeaponsetPtr arg1); - } - - public static interface MapimageCallback extends Callback { - void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount); - } - - public static interface LogCallback extends Callback { - void callback(int level, String logMessage); - } - - // frontlib.h - int flib_init(); - void flib_quit(); - - // hwconsts.h - int flib_get_teamcolor(int colorIndex); - int flib_get_teamcolor_count(); - int flib_get_hedgehogs_per_team(); - int flib_get_weapons_count(); - MetaschemePtr flib_get_metascheme(); - - // net/netconn.h - static final int NETCONN_STATE_CONNECTING = 0; - static final int NETCONN_STATE_LOBBY = 1; - static final int NETCONN_STATE_ROOM = 2; - static final int NETCONN_STATE_DISCONNECTED = 10; - - static final int NETCONN_DISCONNECT_NORMAL = 0; - static final int NETCONN_DISCONNECT_SERVER_TOO_OLD = 1; - static final int NETCONN_DISCONNECT_AUTH_FAILED = 2; - static final int NETCONN_DISCONNECT_CONNLOST = 3; - static final int NETCONN_DISCONNECT_INTERNAL_ERROR = 100; - - static final int NETCONN_ROOMLEAVE_ABANDONED = 0; - static final int NETCONN_ROOMLEAVE_KICKED = 1; - - static final int NETCONN_MSG_TYPE_PLAYERINFO = 0; - static final int NETCONN_MSG_TYPE_SERVERMESSAGE = 1; - static final int NETCONN_MSG_TYPE_WARNING = 2; - static final int NETCONN_MSG_TYPE_ERROR = 3; - - static final int NETCONN_MAPCHANGE_FULL = 0; - static final int NETCONN_MAPCHANGE_MAP = 1; - static final int NETCONN_MAPCHANGE_MAPGEN = 2; - static final int NETCONN_MAPCHANGE_DRAWNMAP = 3; - static final int NETCONN_MAPCHANGE_MAZE_SIZE = 4; - static final int NETCONN_MAPCHANGE_TEMPLATE = 5; - static final int NETCONN_MAPCHANGE_THEME = 6; - static final int NETCONN_MAPCHANGE_SEED = 7; - - NetconnPtr flib_netconn_create(String playerName, String dataDirPath, String host, int port); - void flib_netconn_destroy(NetconnPtr conn); - - void flib_netconn_tick(NetconnPtr conn); - boolean flib_netconn_is_chief(NetconnPtr conn); - String flib_netconn_get_playername(NetconnPtr conn); - GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn); - int flib_netconn_send_quit(NetconnPtr conn, String quitmsg); - int flib_netconn_send_chat(NetconnPtr conn, String chat); - int flib_netconn_send_teamchat(NetconnPtr conn, String msg); - int flib_netconn_send_password(NetconnPtr conn, String passwd); - int flib_netconn_send_nick(NetconnPtr conn, String nick); - int flib_netconn_send_request_roomlist(NetconnPtr conn); - int flib_netconn_send_joinRoom(NetconnPtr conn, String room); - int flib_netconn_send_createRoom(NetconnPtr conn, String room); - int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName); - int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg); - int flib_netconn_send_toggleReady(NetconnPtr conn); - int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team); - int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname); - int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size); - int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount); - int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex); - int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset); - int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map); - int flib_netconn_send_mapName(NetconnPtr conn, String mapName); - int flib_netconn_send_mapGen(NetconnPtr conn, int mapGen); - int flib_netconn_send_mapTemplate(NetconnPtr conn, int templateFilter); - int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize); - int flib_netconn_send_mapSeed(NetconnPtr conn, String seed); - int flib_netconn_send_mapTheme(NetconnPtr conn, String theme); - int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size); - int flib_netconn_send_script(NetconnPtr conn, String scriptName); - int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme); - int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError); - int flib_netconn_send_ban(NetconnPtr conn, String playerName); - int flib_netconn_send_kick(NetconnPtr conn, String playerName); - int flib_netconn_send_playerInfo(NetconnPtr conn, String playerName); - int flib_netconn_send_playerFollow(NetconnPtr conn, String playerName); - int flib_netconn_send_startGame(NetconnPtr conn); - int flib_netconn_send_toggleRestrictJoins(NetconnPtr conn); - int flib_netconn_send_toggleRestrictTeams(NetconnPtr conn); - int flib_netconn_send_clearAccountsCache(NetconnPtr conn); - int flib_netconn_send_setServerVar(NetconnPtr conn, String name, String value); - int flib_netconn_send_getServerVars(NetconnPtr conn); - - void flib_netconn_onMessage(NetconnPtr conn, IntStrCallback callback, Pointer context); - void flib_netconn_onClientFlags(NetconnPtr conn, StrStrBoolCallback callback, Pointer context); - void flib_netconn_onChat(NetconnPtr conn, StrStrCallback callback, Pointer context); - void flib_netconn_onConnected(NetconnPtr conn, VoidCallback callback, Pointer context); - void flib_netconn_onDisconnected(NetconnPtr conn, IntStrCallback callback, Pointer context); - void flib_netconn_onRoomlist(NetconnPtr conn, RoomListCallback callback, Pointer context); - void flib_netconn_onRoomAdd(NetconnPtr conn, RoomCallback callback, Pointer context); - void flib_netconn_onRoomDelete(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onRoomUpdate(NetconnPtr conn, StrRoomCallback callback, Pointer context); - void flib_netconn_onLobbyJoin(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onLobbyLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); - void flib_netconn_onNickTaken(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onPasswordRequest(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onEnterRoom(NetconnPtr conn, BoolCallback callback, Pointer context); - void flib_netconn_onLeaveRoom(NetconnPtr conn, IntStrCallback callback, Pointer context); - void flib_netconn_onTeamAdd(NetconnPtr conn, TeamCallback callback, Pointer context); - void flib_netconn_onTeamDelete(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onRoomJoin(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onRoomLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); - void flib_netconn_onRunGame(NetconnPtr conn, VoidCallback callback, Pointer context); - void flib_netconn_onTeamAccepted(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onHogCountChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); - void flib_netconn_onTeamColorChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); - void flib_netconn_onEngineMessage(NetconnPtr conn, BytesCallback callback, Pointer context); - void flib_netconn_onSchemeChanged(NetconnPtr conn, SchemeCallback callback, Pointer context); - void flib_netconn_onMapChanged(NetconnPtr conn, MapIntCallback callback, Pointer context); - void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context); - void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context); - void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context); - - // ipc/gameconn.h - static final int GAME_END_FINISHED = 0; - static final int GAME_END_INTERRUPTED = 1; - static final int GAME_END_HALTED = 2; - static final int GAME_END_ERROR = 3; - - GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame); - GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size); - GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size); - GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script); - - void flib_gameconn_destroy(GameconnPtr conn); - int flib_gameconn_getport(GameconnPtr conn); - void flib_gameconn_tick(GameconnPtr conn); - - int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len); - int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg); - int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg); - int flib_gameconn_send_quit(GameconnPtr conn); - int flib_gameconn_send_cmd(GameconnPtr conn, String cmdString); - - void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context); - void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context); - void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context); - void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context); - void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context); - void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context); - - // ipc/mapconn.h - public static final int MAPIMAGE_WIDTH = 256; - public static final int MAPIMAGE_HEIGHT = 128; - public static final int MAPIMAGE_BYTES = (MAPIMAGE_WIDTH/8*MAPIMAGE_HEIGHT); - - MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc); - void flib_mapconn_destroy(MapconnPtr conn); - int flib_mapconn_getport(MapconnPtr conn); - void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context); - void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context); - void flib_mapconn_tick(MapconnPtr conn); - - // model/map.h - public static final int MAPGEN_REGULAR = 0; - public static final int MAPGEN_MAZE = 1; - public static final int MAPGEN_DRAWN = 2; - public static final int MAPGEN_NAMED = 3; - - public static final int TEMPLATEFILTER_ALL = 0; - public static final int TEMPLATEFILTER_SMALL = 1; - public static final int TEMPLATEFILTER_MEDIUM = 2; - public static final int TEMPLATEFILTER_LARGE = 3; - public static final int TEMPLATEFILTER_CAVERN = 4; - public static final int TEMPLATEFILTER_WACKY = 5; - - public static final int MAZE_SIZE_SMALL_TUNNELS = 0; - public static final int MAZE_SIZE_MEDIUM_TUNNELS = 1; - public static final int MAZE_SIZE_LARGE_TUNNELS = 2; - public static final int MAZE_SIZE_SMALL_ISLANDS = 3; - public static final int MAZE_SIZE_MEDIUM_ISLANDS = 4; - public static final int MAZE_SIZE_LARGE_ISLANDS = 5; - - // model/schemelist.h - SchemelistPtr flib_schemelist_from_ini(String filename); - int flib_schemelist_to_ini(String filename, SchemelistPtr list); - void flib_schemelist_destroy(SchemelistPtr list); - - // model/team.h - TeamPtr flib_team_from_ini(String filename); - int flib_team_to_ini(String filename, TeamPtr team); - void flib_team_destroy(TeamPtr team); - - // model/weapon.h - WeaponsetListPtr flib_weaponsetlist_from_ini(String filename); - int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets); - void flib_weaponsetlist_destroy(WeaponsetListPtr list); - - // model/gamesetup.h - void flib_gamesetup_destroy(GameSetupPtr gamesetup); - - // util/logging.h - public static final int FLIB_LOGLEVEL_ALL = -100; - public static final int FLIB_LOGLEVEL_DEBUG = -1; - public static final int FLIB_LOGLEVEL_INFO = 0; - public static final int FLIB_LOGLEVEL_WARNING = 1; - public static final int FLIB_LOGLEVEL_ERROR = 2; - public static final int FLIB_LOGLEVEL_NONE = 100; - - void flib_log_setLevel(int level); - void flib_log_setCallback(LogCallback callback); +/* + * Hedgewars for Android. An Android port of Hedgewars, a free turn based strategy game + * Copyright (C) 2012 Simeon Maxein + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +package org.hedgewars.hedgeroid.frontlib; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.hedgewars.hedgeroid.Datastructures.Hog; +import org.hedgewars.hedgeroid.Datastructures.MapRecipe; +import org.hedgewars.hedgeroid.Datastructures.MetaScheme; +import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Mod; +import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Setting; +import org.hedgewars.hedgeroid.Datastructures.GameConfig; +import org.hedgewars.hedgeroid.Datastructures.Room; +import org.hedgewars.hedgeroid.Datastructures.Scheme; +import org.hedgewars.hedgeroid.Datastructures.Team; +import org.hedgewars.hedgeroid.Datastructures.TeamInGame; +import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes; +import org.hedgewars.hedgeroid.Datastructures.Weaponset; + +import com.sun.jna.Callback; +import com.sun.jna.Library; +import com.sun.jna.Memory; +import com.sun.jna.Pointer; +import com.sun.jna.PointerType; +import com.sun.jna.Structure; + +/** + * Here is an introduction to the most important aspects of the JNA code. + * + * This interface permits access to the Hedgewars frontend library (frontlib) + * from Java. Each function directly contained in the Frontlib interface + * represents a mapped C function. The Structure classes (ending in -Struct) are + * mappings of C structs, and the PointerType classes (ending in -Ptr) represent + * pointers to structs. + * + * Quick notes for USING these classes from outside this package: + * + * Usage should be fairly straightforward, but there are a few surprising + * gotchas. First, when you implement callbacks, YOU are responsible for + * ensuring that the callback objects are not garbage-collected while they might + * still be called! So make sure you keep them in member variables or similar, + * because Java will not know if there are still native references to them. + * + * When using Frontlib from outside its package, you only interact with structs + * via the PointerType classes. They allow you to get at the data of the struct + * with a function called deref(), which creates a plain normal Java object + * representing the data (e.g. SchemePtr.deref() will give you a Scheme object). + * + * Remember that you usually have to destroy structs that you receive from the + * library, because they are owned by the native code, not Java. The recommended + * pattern for most cases is to call deref() on the pointer to get a Java object + * (that you can keep as long as you like), and then immediately destroy the + * struct if it needs destroying. To find out whether and how the struct needs + * to be destroyed, see the library's documentation of the function that you got + * the struct from. + * + * To pass new structs to the library, you can use the static createJavaOwned() + * function in each PointerType, which creates a new struct from the Java object + * you provide, and returns a pointer to that struct that you can pass to + * library functions. This new structure's memory is owned and managed by Java + * code, so do not destroy it with frontlib functions! + * + * There is a slight mismatch between the data model for the game setup. The + * frontlib supports setting initial health and weaponset per-hog, because the + * engine allows for that, but currently neither the networking protocol nor the + * PC frontend support this feature, so the Android version does not take + * advantage of it either and treats both as per-game settings. The initial + * health is contained in the game scheme, the weaponset is explicitly part of + * the GameConfig. When converting GameConfig to a native flib_gamesetup, both + * are automatically copied to all hogs in the game, and for the reverse + * conversion the weaponset of the first hog of the first team is used as the + * GameConfig weaponset. This means that GameConfig.weaponset will be null if + * there are no teams in the game. + * + * When starting a network game, you only need to query the GameSetupPtr from + * the netconn and use it to create the gameconn - this is preferable to using + * your own recreation of the game setup, because that way the same piece of + * code is used to determine the game setup on all platforms. + * + * The "context" parameter of the callbacks is never needed here because JNA + * generates function code for each callback object. Don't worry about it, just + * pass null for context and ignore the context parameter in the callbacks. + * + * Finally, the library functions are documented in the actual library, not + * here, so check the docs there to find out what exactly each function does! + * + * Notes about the structure of this class (for the next one who has to touch + * this...): + * + * Java/C interop is quite fiddly and error-prone, so as long as things work, + * try to stick to the established patterns. + * + * Structure types should always be hidden from the outside world, because they + * can be misused too easily. For example, if you get a Structure from the + * library, change a String value in there and pass it back, JNA will re-write + * that string using Java-owned memory without freeing the old native-owned + * string, which causes a memory leak and possibly a double-free or other Bad + * Things (tm). To avoid problems like this, Structure types are only used + * internally, to map existing structures to Java types (without modifying them) + * or to create brand-new, Java-owned structures. Both operations are exposed to + * the outside through the PointerType classes corresponding to the structures + * in question. + * + * Since all of the struct mapping happens in Java, it is never checked against + * the actual struct declarations in the library. That means strange things can + * start happening at runtime if the frontlib structs are modified without + * changing the mappings here to match. This also applies to the function + * signatures: JNA checks whether the functions actually exist when loading the + * library, but it has no way of knowing whether the signatures are correct. If + * the signatures here deviate from those in the frontlib, you might get stack + * corruption. + * + * In order to check at least the function signatures, take a look at the file + * extra/jnacontrol.c in the frontlib sources. You can validate whether the + * function signatures are still correct by copy-pasting them into jnaControl.c + * and compiling it against the frontlib headers. The typedefs and #defines in + * that file will make the compiler see the Java method signatures as C function + * declarations. Since the same functions are already declared in the frontlib + * headers, the compiler will give you errors if the signatures don't match. + */ +public interface Frontlib extends Library { + public static class NetconnPtr extends PointerType { } + public static class MapconnPtr extends PointerType { } + public static class GameconnPtr extends PointerType { } + + public static class MetaschemePtr extends PointerType { + public MetaScheme deref() { + return deref(getPointer()); + } + + public static MetaScheme deref(Pointer p) { + MetaschemeStruct struct = new MetaschemeStruct(p); + struct.read(); + return struct.toMetaScheme(); + } + } + + public static class RoomArrayPtr extends PointerType { + public Room[] getRooms(int count) { + Pointer ptr = getPointer(); + if(ptr == null) { + return new Room[0]; + } + Pointer[] untypedPtrs = ptr.getPointerArray(0, count); + Room[] result = new Room[count]; + for(int i=0; i deref() { + WeaponsetListStruct struct = new WeaponsetListStruct(getPointer()); + struct.read(); + return struct.toWeaponsetList(); + } + + public static WeaponsetListPtr createJavaOwned(List list) { + WeaponsetListPtr result = new WeaponsetListPtr(); + result.javaOwnedInstance = new WeaponsetListStruct(); + result.javaOwnedInstance.fillFrom(list); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class MapRecipePtr extends PointerType { + private MapRecipeStruct javaOwnedInstance; + + public MapRecipe deref() { + MapRecipeStruct struct = new MapRecipeStruct(getPointer()); + struct.read(); + return struct.toMapRecipe(); + } + + public static MapRecipePtr createJavaOwned(MapRecipe recipe) { + MapRecipePtr result = new MapRecipePtr(); + result.javaOwnedInstance = new MapRecipeStruct(); + result.javaOwnedInstance.fillFrom(recipe); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class SchemePtr extends PointerType { + private SchemeStruct javaOwnedInstance; + + public Scheme deref() { + SchemeStruct struct = new SchemeStruct(getPointer()); + struct.read(); + return struct.toScheme(); + } + + public static SchemePtr createJavaOwned(Scheme scheme) { + SchemePtr result = new SchemePtr(); + result.javaOwnedInstance = new SchemeStruct(); + result.javaOwnedInstance.fillFrom(scheme); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class SchemelistPtr extends PointerType { + private SchemelistStruct javaOwnedInstance; + + public List deref() { + SchemelistStruct struct = new SchemelistStruct(getPointer()); + struct.read(); + return struct.toSchemeList(); + } + + public static SchemelistPtr createJavaOwned(List schemes) { + SchemelistPtr result = new SchemelistPtr(); + result.javaOwnedInstance = new SchemelistStruct(); + result.javaOwnedInstance.fillFrom(schemes); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class GameSetupPtr extends PointerType { + private GameSetupStruct javaOwnedInstance; + + public GameConfig deref() { + GameSetupStruct struct = new GameSetupStruct(getPointer()); + struct.read(); + return struct.toGameConfig(); + } + + public static GameSetupPtr createJavaOwned(GameConfig conf) { + GameSetupPtr result = new GameSetupPtr(); + result.javaOwnedInstance = new GameSetupStruct(); + result.javaOwnedInstance.fillFrom(conf); + result.javaOwnedInstance.autoWrite(); + result.setPointer(result.javaOwnedInstance.getPointer()); + return result; + } + } + + public static class ByteArrayPtr extends PointerType { + public byte[] deref(int size) { + return getPointer().getByteArray(0, size); + } + + public static byte[] deref(ByteArrayPtr ptr, int size) { + if(ptr==null && size==0) { + return null; + } else { + return ptr.deref(size); + } + } + + public static ByteArrayPtr createJavaOwned(byte[] buffer) { + if(buffer == null || buffer.length == 0) { + return null; + } + // no need for javaOwnedInstance here because PointerType + // remembers the memory as its Pointer + Pointer ptr = new Memory(buffer.length); + ptr.write(0, buffer, 0, buffer.length); + ByteArrayPtr result = new ByteArrayPtr(); + result.setPointer(ptr); + return result; + } + } + + static class HogStruct extends Structure { + public static class ByVal extends HogStruct implements Structure.ByValue {} + public static class ByRef extends HogStruct implements Structure.ByReference {} + + public HogStruct() { super(); } + public HogStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("name", "hat", "rounds", "kills", "deaths", "suicides", "difficulty", "initialHealth", "weaponset"); + } + + public void fillFrom(Hog hog) { + difficulty = hog.level; + hat = hog.hat; + name = hog.name; + } + + public Hog toHog() { + return new Hog(name, hat, difficulty); + } + + public String name; + public String hat; + + public int rounds; + public int kills; + public int deaths; + public int suicides; + + public int difficulty; + + public int initialHealth; + public WeaponsetStruct.ByRef weaponset; + } + + static class TeamStruct extends Structure { + public static class ByVal extends TeamStruct implements Structure.ByValue {} + public static class ByRef extends TeamStruct implements Structure.ByReference {} + + public TeamStruct() { super(); } + public TeamStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("hogs", "name", "grave", "fort", "voicepack", "flag", "bindings", "bindingCount", "rounds", "wins", "campaignProgress", "colorIndex", "hogsInGame", "remoteDriven", "ownerName"); + } + + public void fillFrom(Team team, TeamIngameAttributes attrs) { + if(team != null) { + name = team.name; + grave = team.grave; + flag = team.flag; + voicepack = team.voice; + fort = team.fort; + if(team.hogs.size() != Team.HEDGEHOGS_PER_TEAM) { + throw new IllegalArgumentException(); + } + for(int i=0; i hogList = new ArrayList(); + for(int i=0; i getFieldOrder() { + return Arrays.asList("loadout", "crateprob", "crateammo", "delay", "name"); + } + + public void fillFrom(Weaponset weaponset) { + fillWeaponInfo(loadout, weaponset.loadout); + fillWeaponInfo(crateprob, weaponset.crateProb); + fillWeaponInfo(crateammo, weaponset.crateAmmo); + fillWeaponInfo(delay, weaponset.delay); + name = weaponset.name; + } + + private static void fillWeaponInfo(byte[] array, String str) { + for(int i=0; i getFieldOrder() { + return Arrays.asList("weaponset"); + } + + public WeaponsetStruct.ByRef weaponset; + } + + static class WeaponsetListStruct extends Structure { + public static class ByVal extends WeaponsetListStruct implements Structure.ByValue {} + public static class ByRef extends WeaponsetListStruct implements Structure.ByReference {} + + public WeaponsetListStruct() { super(); } + public WeaponsetListStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("weaponsetCount", "weaponsets"); + } + + public void fillFrom(List list) { + weaponsetCount = list.size(); + if(weaponsetCount<=0) { + weaponsets = null; + } else { + weaponsets = new WeaponsetPointerByReference(); + Structure[] structs = weaponsets.toArray(weaponsetCount); + + for(int i=0; i toWeaponsetList() { + if(weaponsetCount<=0) { + return new ArrayList(); + } else { + List list = new ArrayList(weaponsetCount); + Structure[] structs = weaponsets.toArray(weaponsetCount); + + for(int i=0; i getFieldOrder() { + return Arrays.asList("inProgress", "name", "playerCount", "teamCount", "owner", "map", "scheme", "weapons"); + } + + public Room toRoomlistRoom() { + return new Room(name, map, scheme, weapons, owner, playerCount, teamCount, inProgress); + } + + public boolean inProgress; + public String name; + public int playerCount; + public int teamCount; + public String owner; + public String map; + public String scheme; + public String weapons; + } + + static class MapRecipeStruct extends Structure { + public static class ByVal extends MapRecipeStruct implements Structure.ByValue {} + public static class ByRef extends MapRecipeStruct implements Structure.ByReference {} + + public MapRecipeStruct() { super(); } + public MapRecipeStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("mapgen", "name", "seed", "theme", "drawData", "drawDataSize", "templateFilter", "mazeSize"); + } + + public void fillFrom(MapRecipe map) { + mapgen = map.mapgen; + name = map.name; + seed = map.seed; + theme = map.theme; + byte[] buf = map.getDrawData(); + drawData = ByteArrayPtr.createJavaOwned(buf); + drawDataSize = NativeSizeT.valueOf(buf==null ? 0 : buf.length); + templateFilter = map.templateFilter; + mazeSize = map.mazeSize; + } + + public MapRecipe toMapRecipe() { + byte[] buf = ByteArrayPtr.deref(drawData, drawDataSize.intValue()); + return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, buf); + } + + public int mapgen; + public String name; + public String seed; + public String theme; + public ByteArrayPtr drawData; + public NativeSizeT drawDataSize; + public int templateFilter; + public int mazeSize; + } + + static class MetaschemeSettingStruct extends Structure { + public static class ByVal extends MetaschemeSettingStruct implements Structure.ByValue {} + public static class ByRef extends MetaschemeSettingStruct implements Structure.ByReference {} + + public MetaschemeSettingStruct() { super(); } + public MetaschemeSettingStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("name", "engineCommand", "maxMeansInfinity", "times1000", "min", "max", "def"); + } + + public void fillFrom(Setting setting) { + name = setting.name; + engineCommand = setting.engineCommand; + maxMeansInfinity = setting.maxMeansInfinity; + times1000 = setting.times1000; + min = setting.min; + max = setting.max; + def = setting.def; + } + + public MetaScheme.Setting toMetaSchemeSetting() { + return new MetaScheme.Setting(name, engineCommand, maxMeansInfinity, times1000, min, max, def); + } + + public String name; + public String engineCommand; + public boolean maxMeansInfinity; + public boolean times1000; + public int min; + public int max; + public int def; + } + + static class MetaschemeModStruct extends Structure { + public static class ByVal extends MetaschemeModStruct implements Structure.ByValue {} + public static class ByRef extends MetaschemeModStruct implements Structure.ByReference {} + + public MetaschemeModStruct() { super(); } + public MetaschemeModStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("name", "bitmaskIndex"); + } + + public void fillFrom(Mod mod) { + name = mod.name; + bitmaskIndex = mod.bitmaskIndex; + } + + public MetaScheme.Mod toMetaSchemeMod() { + return new MetaScheme.Mod(name, bitmaskIndex); + } + + public String name; + public int bitmaskIndex; + + } + + static class MetaschemeStruct extends Structure { + public static class ByVal extends MetaschemeStruct implements Structure.ByValue {} + public static class ByRef extends MetaschemeStruct implements Structure.ByReference {} + + public MetaschemeStruct() { super(); } + public MetaschemeStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("settingCount", "modCount", "settings", "mods"); + } + + /** + * Only use on native-owned structs! + * Calling this method on a Java-owned struct could cause garbage collection of referenced + * structures. + */ + public MetaScheme toMetaScheme() { + List settingList = new ArrayList(settingCount); + List modList = new ArrayList(modCount); + + Structure[] settingStructs = settings.toArray(settingCount); + Structure[] modStructs = mods.toArray(modCount); + + for(int i=0; i getFieldOrder() { + return Arrays.asList("name", "settings", "mods"); + } + + public void fillFrom(Scheme scheme) { + MetaScheme meta = MetaScheme.INSTANCE; + name = scheme.name; + settings = new Memory(AndroidTypeMapper.NATIVE_INT_SIZE * meta.settings.size()); + for(int i=0; i settingsMap = new HashMap(); + MetaScheme meta = MetaScheme.INSTANCE; + for(int i=0; i modsMap = new HashMap(); + for(int i=0; i getFieldOrder() { + return Arrays.asList("scheme"); + } + + public SchemeStruct.ByRef scheme; + } + + static class SchemelistStruct extends Structure { + public static class ByVal extends SchemelistStruct implements Structure.ByValue {} + public static class ByRef extends SchemelistStruct implements Structure.ByReference {} + + public SchemelistStruct() { super(); } + public SchemelistStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("schemeCount", "schemes"); + } + + public void fillFrom(List schemeList) { + schemeCount = schemeList.size(); + if(schemeCount<=0) { + schemes = null; + } else { + schemes = new SchemePointerByReference(); + Structure[] schemePtrStructs = schemes.toArray(schemeCount); + + for(int i=0; i toSchemeList() { + if(schemeCount<=0) { + return new ArrayList(); + } else { + List schemeList = new ArrayList(schemeCount); + + Structure[] schemePtrStructs = schemes.toArray(schemeCount); + + for(int i=0; i getFieldOrder() { + return Arrays.asList("team"); + } + + public TeamStruct.ByRef team; + } + + static class TeamlistStruct extends Structure { + public static class ByVal extends TeamlistStruct implements Structure.ByValue {} + public static class ByRef extends TeamlistStruct implements Structure.ByReference {} + + public TeamlistStruct() { super(); } + public TeamlistStruct(Pointer ptr) { super(ptr); } + + @Override + protected List getFieldOrder() { + return Arrays.asList("teamCount", "teams"); + } + + public void fillFrom(List teamList, WeaponsetStruct.ByRef weaponset, int initialHealth) { + teamCount = teamList.size(); + if(teamCount <= 0) { + teams = null; + } else { + teams = new TeamPointerByReference(); + Structure[] teamPtrStructs = teams.toArray(teamCount); + + for(int i=0; i toTeamInGameList() { + if(teamCount<=0) { + return new ArrayList(); + } else { + List result = new ArrayList(teamCount); + Structure[] structs = teams.toArray(teamCount); + + for(int i=0; i getFieldOrder() { + return Arrays.asList("script", "gamescheme", "map", "teamlist"); + } + + public void fillFrom(GameConfig conf) { + script = conf.style; + gamescheme = new SchemeStruct.ByRef(); + gamescheme.fillFrom(conf.scheme); + map = new MapRecipeStruct.ByRef(); + map.fillFrom(conf.map); + + /* + * At this point we deviate from the usual copying pattern because the frontlib + * expects per-hog weapons and initial health, but the UI models them as per- + * game, so we extract them from the config here and pass them on to be included + * in each hog. + */ + WeaponsetStruct.ByRef wss = new WeaponsetStruct.ByRef(); + wss.fillFrom(conf.weaponset); + int initialHealth = conf.scheme.getHealth(); + + teamlist = new TeamlistStruct.ByRef(); + teamlist.fillFrom(conf.teams, wss, initialHealth); + } + + public GameConfig toGameConfig() { + Scheme scheme = gamescheme != null ? gamescheme.toScheme() : null; + MapRecipe mapRecipe = map != null ? map.toMapRecipe() : null; + List teams = teamlist != null ? teamlist.toTeamInGameList() : null; + + WeaponsetStruct weaponsetStruct = teamlist != null && teamlist.teamCount>0 ? teamlist.teams.team.hogs[0].weaponset : null; + Weaponset weaponset = weaponsetStruct != null ? weaponsetStruct.toWeaponset() : null; + return new GameConfig(script, scheme, mapRecipe, teams, weaponset); + } + + public String script; + public SchemeStruct.ByRef gamescheme; + public MapRecipeStruct.ByRef map; + public TeamlistStruct.ByRef teamlist; + } + + /* + * Callback interfaces. The context parameter is never needed here and + * should always be ignored. Be sure to keep a reference to each callback + * for as long as they might be called by native code, to avoid premature + * garbage collection. + */ + public static interface VoidCallback extends Callback { + void callback(Pointer context); + } + + public static interface StrCallback extends Callback { + void callback(Pointer context, String arg1); + } + + public static interface IntCallback extends Callback { + void callback(Pointer context, int arg1); + } + + public static interface IntStrCallback extends Callback { + void callback(Pointer context, int arg1, String arg2); + } + + public static interface StrIntCallback extends Callback { + void callback(Pointer context, String arg1, int arg2); + } + + public static interface StrStrCallback extends Callback { + void callback(Pointer context, String arg1, String arg2); + } + + public static interface StrStrBoolCallback extends Callback { + void callback(Pointer context, String arg1, String arg2, boolean arg3); + } + + public static interface RoomCallback extends Callback { + void callback(Pointer context, RoomPtr arg1); + } + + public static interface RoomListCallback extends Callback { + void callback(Pointer context, RoomArrayPtr arg1, int count); + } + + public static interface StrRoomCallback extends Callback { + void callback(Pointer context, String arg1, RoomPtr arg2); + } + + public static interface BoolCallback extends Callback { + void callback(Pointer context, boolean arg1); + } + + public static interface StrBoolCallback extends Callback { + void callback(Pointer context, String arg1, boolean arg2); + } + + public static interface TeamCallback extends Callback { + void callback(Pointer context, TeamPtr arg1); + } + + public static interface BytesCallback extends Callback { + void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size); + } + + public static interface BytesBoolCallback extends Callback { + void callback(Pointer context, ByteArrayPtr buffer, NativeSizeT size, boolean arg3); + } + + public static interface SchemeCallback extends Callback { + void callback(Pointer context, SchemePtr arg1); + } + + public static interface MapIntCallback extends Callback { + void callback(Pointer context, MapRecipePtr arg1, int arg2); + } + + public static interface WeaponsetCallback extends Callback { + void callback(Pointer context, WeaponsetPtr arg1); + } + + public static interface MapimageCallback extends Callback { + void callback(Pointer context, ByteArrayPtr buffer, int hedgehogCount); + } + + public static interface LogCallback extends Callback { + void callback(int level, String logMessage); + } + + // frontlib.h + int flib_init(); + void flib_quit(); + + // hwconsts.h + int flib_get_teamcolor(int colorIndex); + int flib_get_teamcolor_count(); + int flib_get_hedgehogs_per_team(); + int flib_get_weapons_count(); + MetaschemePtr flib_get_metascheme(); + + // net/netconn.h + static final int NETCONN_STATE_CONNECTING = 0; + static final int NETCONN_STATE_LOBBY = 1; + static final int NETCONN_STATE_ROOM = 2; + static final int NETCONN_STATE_DISCONNECTED = 10; + + static final int NETCONN_DISCONNECT_NORMAL = 0; + static final int NETCONN_DISCONNECT_SERVER_TOO_OLD = 1; + static final int NETCONN_DISCONNECT_AUTH_FAILED = 2; + static final int NETCONN_DISCONNECT_CONNLOST = 3; + static final int NETCONN_DISCONNECT_INTERNAL_ERROR = 100; + + static final int NETCONN_ROOMLEAVE_ABANDONED = 0; + static final int NETCONN_ROOMLEAVE_KICKED = 1; + + static final int NETCONN_MSG_TYPE_PLAYERINFO = 0; + static final int NETCONN_MSG_TYPE_SERVERMESSAGE = 1; + static final int NETCONN_MSG_TYPE_WARNING = 2; + static final int NETCONN_MSG_TYPE_ERROR = 3; + + static final int NETCONN_MAPCHANGE_FULL = 0; + static final int NETCONN_MAPCHANGE_MAP = 1; + static final int NETCONN_MAPCHANGE_MAPGEN = 2; + static final int NETCONN_MAPCHANGE_DRAWNMAP = 3; + static final int NETCONN_MAPCHANGE_MAZE_SIZE = 4; + static final int NETCONN_MAPCHANGE_TEMPLATE = 5; + static final int NETCONN_MAPCHANGE_THEME = 6; + static final int NETCONN_MAPCHANGE_SEED = 7; + + NetconnPtr flib_netconn_create(String playerName, String dataDirPath, String host, int port); + void flib_netconn_destroy(NetconnPtr conn); + + void flib_netconn_tick(NetconnPtr conn); + boolean flib_netconn_is_chief(NetconnPtr conn); + String flib_netconn_get_playername(NetconnPtr conn); + GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn); + int flib_netconn_send_quit(NetconnPtr conn, String quitmsg); + int flib_netconn_send_chat(NetconnPtr conn, String chat); + int flib_netconn_send_teamchat(NetconnPtr conn, String msg); + int flib_netconn_send_password(NetconnPtr conn, String passwd); + int flib_netconn_send_nick(NetconnPtr conn, String nick); + int flib_netconn_send_request_roomlist(NetconnPtr conn); + int flib_netconn_send_joinRoom(NetconnPtr conn, String room); + int flib_netconn_send_createRoom(NetconnPtr conn, String room); + int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName); + int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg); + int flib_netconn_send_toggleReady(NetconnPtr conn); + int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team); + int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname); + int flib_netconn_send_engineMessage(NetconnPtr conn, ByteArrayPtr message, NativeSizeT size); + int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount); + int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex); + int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset); + int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map); + int flib_netconn_send_mapName(NetconnPtr conn, String mapName); + int flib_netconn_send_mapGen(NetconnPtr conn, int mapGen); + int flib_netconn_send_mapTemplate(NetconnPtr conn, int templateFilter); + int flib_netconn_send_mapMazeSize(NetconnPtr conn, int mazeSize); + int flib_netconn_send_mapSeed(NetconnPtr conn, String seed); + int flib_netconn_send_mapTheme(NetconnPtr conn, String theme); + int flib_netconn_send_mapDrawdata(NetconnPtr conn, ByteArrayPtr drawData, NativeSizeT size); + int flib_netconn_send_script(NetconnPtr conn, String scriptName); + int flib_netconn_send_scheme(NetconnPtr conn, SchemePtr scheme); + int flib_netconn_send_roundfinished(NetconnPtr conn, boolean withoutError); + int flib_netconn_send_ban(NetconnPtr conn, String playerName); + int flib_netconn_send_kick(NetconnPtr conn, String playerName); + int flib_netconn_send_playerInfo(NetconnPtr conn, String playerName); + int flib_netconn_send_playerFollow(NetconnPtr conn, String playerName); + int flib_netconn_send_startGame(NetconnPtr conn); + int flib_netconn_send_toggleRestrictJoins(NetconnPtr conn); + int flib_netconn_send_toggleRestrictTeams(NetconnPtr conn); + int flib_netconn_send_clearAccountsCache(NetconnPtr conn); + int flib_netconn_send_setServerVar(NetconnPtr conn, String name, String value); + int flib_netconn_send_getServerVars(NetconnPtr conn); + + void flib_netconn_onMessage(NetconnPtr conn, IntStrCallback callback, Pointer context); + void flib_netconn_onClientFlags(NetconnPtr conn, StrStrBoolCallback callback, Pointer context); + void flib_netconn_onChat(NetconnPtr conn, StrStrCallback callback, Pointer context); + void flib_netconn_onConnected(NetconnPtr conn, VoidCallback callback, Pointer context); + void flib_netconn_onDisconnected(NetconnPtr conn, IntStrCallback callback, Pointer context); + void flib_netconn_onRoomlist(NetconnPtr conn, RoomListCallback callback, Pointer context); + void flib_netconn_onRoomAdd(NetconnPtr conn, RoomCallback callback, Pointer context); + void flib_netconn_onRoomDelete(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onRoomUpdate(NetconnPtr conn, StrRoomCallback callback, Pointer context); + void flib_netconn_onLobbyJoin(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onLobbyLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); + void flib_netconn_onNickTaken(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onPasswordRequest(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onEnterRoom(NetconnPtr conn, BoolCallback callback, Pointer context); + void flib_netconn_onLeaveRoom(NetconnPtr conn, IntStrCallback callback, Pointer context); + void flib_netconn_onTeamAdd(NetconnPtr conn, TeamCallback callback, Pointer context); + void flib_netconn_onTeamDelete(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onRoomJoin(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onRoomLeave(NetconnPtr conn, StrStrCallback callback, Pointer context); + void flib_netconn_onRunGame(NetconnPtr conn, VoidCallback callback, Pointer context); + void flib_netconn_onTeamAccepted(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onHogCountChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); + void flib_netconn_onTeamColorChanged(NetconnPtr conn, StrIntCallback callback, Pointer context); + void flib_netconn_onEngineMessage(NetconnPtr conn, BytesCallback callback, Pointer context); + void flib_netconn_onSchemeChanged(NetconnPtr conn, SchemeCallback callback, Pointer context); + void flib_netconn_onMapChanged(NetconnPtr conn, MapIntCallback callback, Pointer context); + void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context); + void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context); + void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context); + + // ipc/gameconn.h + static final int GAME_END_FINISHED = 0; + static final int GAME_END_INTERRUPTED = 1; + static final int GAME_END_HALTED = 2; + static final int GAME_END_ERROR = 3; + + GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame); + GameconnPtr flib_gameconn_create_playdemo(ByteArrayPtr demo, NativeSizeT size); + GameconnPtr flib_gameconn_create_loadgame(String playerName, ByteArrayPtr save, NativeSizeT size); + GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script); + + void flib_gameconn_destroy(GameconnPtr conn); + int flib_gameconn_getport(GameconnPtr conn); + void flib_gameconn_tick(GameconnPtr conn); + + int flib_gameconn_send_enginemsg(GameconnPtr conn, ByteArrayPtr data, NativeSizeT len); + int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg); + int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg); + int flib_gameconn_send_quit(GameconnPtr conn); + int flib_gameconn_send_cmd(GameconnPtr conn, String cmdString); + + void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context); + void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context); + void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context); + void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context); + void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context); + void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context); + + // ipc/mapconn.h + public static final int MAPIMAGE_WIDTH = 256; + public static final int MAPIMAGE_HEIGHT = 128; + public static final int MAPIMAGE_BYTES = (MAPIMAGE_WIDTH/8*MAPIMAGE_HEIGHT); + + MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc); + void flib_mapconn_destroy(MapconnPtr conn); + int flib_mapconn_getport(MapconnPtr conn); + void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context); + void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context); + void flib_mapconn_tick(MapconnPtr conn); + + // model/map.h + public static final int MAPGEN_REGULAR = 0; + public static final int MAPGEN_MAZE = 1; + public static final int MAPGEN_DRAWN = 2; + public static final int MAPGEN_NAMED = 3; + + public static final int TEMPLATEFILTER_ALL = 0; + public static final int TEMPLATEFILTER_SMALL = 1; + public static final int TEMPLATEFILTER_MEDIUM = 2; + public static final int TEMPLATEFILTER_LARGE = 3; + public static final int TEMPLATEFILTER_CAVERN = 4; + public static final int TEMPLATEFILTER_WACKY = 5; + + public static final int MAZE_SIZE_SMALL_TUNNELS = 0; + public static final int MAZE_SIZE_MEDIUM_TUNNELS = 1; + public static final int MAZE_SIZE_LARGE_TUNNELS = 2; + public static final int MAZE_SIZE_SMALL_ISLANDS = 3; + public static final int MAZE_SIZE_MEDIUM_ISLANDS = 4; + public static final int MAZE_SIZE_LARGE_ISLANDS = 5; + + // model/schemelist.h + SchemelistPtr flib_schemelist_from_ini(String filename); + int flib_schemelist_to_ini(String filename, SchemelistPtr list); + void flib_schemelist_destroy(SchemelistPtr list); + + // model/team.h + TeamPtr flib_team_from_ini(String filename); + int flib_team_to_ini(String filename, TeamPtr team); + void flib_team_destroy(TeamPtr team); + + // model/weapon.h + WeaponsetListPtr flib_weaponsetlist_from_ini(String filename); + int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets); + void flib_weaponsetlist_destroy(WeaponsetListPtr list); + + // model/gamesetup.h + void flib_gamesetup_destroy(GameSetupPtr gamesetup); + + // util/logging.h + public static final int FLIB_LOGLEVEL_ALL = -100; + public static final int FLIB_LOGLEVEL_DEBUG = -1; + public static final int FLIB_LOGLEVEL_INFO = 0; + public static final int FLIB_LOGLEVEL_WARNING = 1; + public static final int FLIB_LOGLEVEL_ERROR = 2; + public static final int FLIB_LOGLEVEL_NONE = 100; + + void flib_log_setLevel(int level); + void flib_log_setCallback(LogCallback callback); } \ No newline at end of file