project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/frontlib/Frontlib.java
changeset 7485 0481bd74267c
parent 7476 2fb781bbdd51
child 7508 763d3961400b
equal deleted inserted replaced
7482:d70a5b0d1190 7485:0481bd74267c
     1 package org.hedgewars.hedgeroid.frontlib;
     1 package org.hedgewars.hedgeroid.frontlib;
       
     2 import java.io.UnsupportedEncodingException;
     2 import java.nio.Buffer;
     3 import java.nio.Buffer;
     3 import java.util.ArrayList;
     4 import java.util.ArrayList;
     4 import java.util.HashMap;
     5 import java.util.HashMap;
     5 import java.util.List;
     6 import java.util.List;
     6 import java.util.Map;
     7 import java.util.Map;
     7 
     8 
     8 import org.hedgewars.hedgeroid.Datastructures.Hog;
     9 import org.hedgewars.hedgeroid.Datastructures.Hog;
       
    10 import org.hedgewars.hedgeroid.Datastructures.MapRecipe;
     9 import org.hedgewars.hedgeroid.Datastructures.MetaScheme;
    11 import org.hedgewars.hedgeroid.Datastructures.MetaScheme;
    10 import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Mod;
    12 import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Mod;
    11 import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Setting;
    13 import org.hedgewars.hedgeroid.Datastructures.MetaScheme.Setting;
       
    14 import org.hedgewars.hedgeroid.Datastructures.GameConfig;
    12 import org.hedgewars.hedgeroid.Datastructures.RoomlistRoom;
    15 import org.hedgewars.hedgeroid.Datastructures.RoomlistRoom;
    13 import org.hedgewars.hedgeroid.Datastructures.Scheme;
    16 import org.hedgewars.hedgeroid.Datastructures.Scheme;
    14 import org.hedgewars.hedgeroid.Datastructures.Team;
    17 import org.hedgewars.hedgeroid.Datastructures.Team;
    15 import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
    18 import org.hedgewars.hedgeroid.Datastructures.TeamInGame;
    16 import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes;
    19 import org.hedgewars.hedgeroid.Datastructures.TeamIngameAttributes;
    17 import org.hedgewars.hedgeroid.EngineProtocol.GameConfig;
    20 import org.hedgewars.hedgeroid.Datastructures.Weaponset;
    18 
    21 
    19 import com.sun.jna.Callback;
    22 import com.sun.jna.Callback;
    20 import com.sun.jna.Library;
    23 import com.sun.jna.Library;
    21 import com.sun.jna.Memory;
    24 import com.sun.jna.Memory;
    22 import com.sun.jna.NativeLong;
    25 import com.sun.jna.NativeLong;
    23 import com.sun.jna.Pointer;
    26 import com.sun.jna.Pointer;
    24 import com.sun.jna.PointerType;
    27 import com.sun.jna.PointerType;
    25 import com.sun.jna.Structure;
    28 import com.sun.jna.Structure;
    26 
    29 import com.sun.jna.ptr.IntByReference;
       
    30 
       
    31 /**
       
    32  * Here is an introduction to the most important aspects of the JNA code.
       
    33  * 
       
    34  * This interface permits access to the Hedgewars frontend library (frontlib)
       
    35  * from Java. Each function directly contained in the Frontlib interface
       
    36  * represents a mapped C function. The Structure classes (ending in -Struct) are
       
    37  * mappings of C structs, and the PointerType classes (ending in -Ptr) represent
       
    38  * pointers to structs.
       
    39  * 
       
    40  * Quick notes for USING these classes from outside this package:
       
    41  * 
       
    42  * Usage should be fairly straightforward, but there are a few surprising
       
    43  * gotchas. First, when you implement callbacks, YOU are responsible for
       
    44  * ensuring that the callback objects are not garbage-collected while they might
       
    45  * still be called! So make sure you keep them in member variables or similar,
       
    46  * because Java will not know if there are still native references to them.
       
    47  * 
       
    48  * When using Frontlib from outside its package, you only interact with structs
       
    49  * via the PointerType classes. They allow you to get at the data of the struct
       
    50  * with a function called deref(), which creates a plain normal Java object
       
    51  * representing the data (e.g. SchemePtr.deref() will give you a Scheme object).
       
    52  * 
       
    53  * Remember that you usually have to destroy structs that you receive from the
       
    54  * library, because they are owned by the native code, not Java. For example, if
       
    55  * you obtain a {@link MetaschemePtr} metaPtr using flib_metascheme_from_ini,
       
    56  * you have to call flib_metascheme_release(metaPtr) after you are done using
       
    57  * it. The recommended pattern for most cases is to call deref() on the pointer
       
    58  * to get a Java object (that you can keep as long as you like), and then
       
    59  * immediately destroy the struct if it needs destroying. To find out whether
       
    60  * and how the struct needs to be destroyed, see the library's documentation of
       
    61  * the function that you got the struct from.
       
    62  * 
       
    63  * To pass new structs to the library, you can use the static createJavaOwned()
       
    64  * function in each PointerType, which creates a new struct from the Java object
       
    65  * you provide, and returns a pointer to that struct that you can pass to
       
    66  * library functions. This new structure's memory is owned and managed by Java
       
    67  * code, so do not destroy it with frontlib functions!
       
    68  * 
       
    69  * There is a slight mismatch between the data model for the game setup. The
       
    70  * frontlib supports setting initial health and weaponset per-hog, because the
       
    71  * engine allows for that, but currently neither the networking protocol nor the
       
    72  * PC frontend support this feature, so the Android version does not take
       
    73  * advantage of it either and treats both as per-game settings. The initial
       
    74  * health is contained in the game scheme, the weaponset is explicitly part of
       
    75  * the GameConfig. When converting GameConfig to a native flib_gamesetup, both
       
    76  * are automatically copied to all hogs in the game, and for the reverse
       
    77  * conversion the weaponset of the first hog of the first team is used as the
       
    78  * GameConfig weaponset. This means that GameConfig.weaponset will be null if
       
    79  * there are no teams in the game.
       
    80  * 
       
    81  * When starting a network game, you only need to query the GameSetupPtr from
       
    82  * the netconn and use it to create the gameconn - this is preferable to using
       
    83  * your own recreation of the game setup, because that way the same piece of
       
    84  * code is used to determine the game setup on all platforms.
       
    85  * 
       
    86  * The "context" parameter of the callbacks is never needed here because JNA
       
    87  * generates function code for each callback object. Don't worry about it, just
       
    88  * pass null for context and ignore the context parameter in the callbacks.
       
    89  * 
       
    90  * Finally, the library functions are documented in the actual library, not
       
    91  * here, so check the docs there to find out what exactly each function does!
       
    92  * 
       
    93  * Notes about the structure of this class (for the next one who has to touch
       
    94  * this...):
       
    95  * 
       
    96  * Java/C interop is quite fiddly and error-prone, so as long as things work,
       
    97  * try to stick to the established patterns.
       
    98  * 
       
    99  * Structure types should always be hidden from the outside world, because they
       
   100  * can be misused too easily. For example, if you get a Structure from the
       
   101  * library, change a String value in there and pass it back, JNA will re-write
       
   102  * that string using Java-owned memory without freeing the old native-owned
       
   103  * string, which causes a memory leak and possibly a double-free or other Bad
       
   104  * Things (tm). To avoid problems like this, Structure types are only used
       
   105  * internally, to map existing structures to Java types (without modifying them)
       
   106  * or to create brand-new, Java-owned structures. Both operations are exposed to
       
   107  * the outside through the PointerType classes corresponding to the structures
       
   108  * in question.
       
   109  * 
       
   110  * Since all of the struct mapping happens in Java, it is never checked against
       
   111  * the actual struct declarations in the library. That means strange things can
       
   112  * start happening at runtime if the frontlib structs are modified without
       
   113  * changing the mappings here to match. This also applies to the function
       
   114  * signatures: JNA checks whether the functions actually exist when loading the
       
   115  * library, but it has no way of knowing whether the signatures are correct. If
       
   116  * the signatures here deviate from those in the frontlib, you might get stack
       
   117  * corruption.
       
   118  * 
       
   119  * In order to check at least the function signatures, take a look at the file
       
   120  * extra/jnacontrol.c in the frontlib sources. You can validate whether the
       
   121  * function signatures are still correct by copy-pasting them into jnaControl.c
       
   122  * and compiling it against the frontlib headers. The typedefs and #defines in
       
   123  * that file will make the compiler see the Java method signatures as C function
       
   124  * declarations. Since the same functions are already declared in the frontlib
       
   125  * headers, the compiler will give you errors if the signatures don't match.
       
   126  */
    27 public interface Frontlib extends Library {
   127 public interface Frontlib extends Library {
    28 	static final int NATIVE_INT_SIZE = 4;
   128 	static final int NATIVE_INT_SIZE = 4;
    29 	static final int NATIVE_BOOL_SIZE = 1;
   129 	static final int NATIVE_BOOL_SIZE = 1;
    30 	
   130 	
    31 	static final int NETCONN_STATE_CONNECTING = 0;
       
    32 	static final int NETCONN_STATE_LOBBY = 1;
       
    33 	static final int NETCONN_STATE_ROOM = 2;
       
    34 	static final int NETCONN_STATE_INGAME = 3;
       
    35 	static final int NETCONN_STATE_DISCONNECTED = 10;
       
    36 	
       
    37 	static final int NETCONN_DISCONNECT_NORMAL = 0;
       
    38 	static final int NETCONN_DISCONNECT_SERVER_TOO_OLD = 1;
       
    39 	static final int NETCONN_DISCONNECT_AUTH_FAILED = 2;
       
    40 	static final int NETCONN_DISCONNECT_CONNLOST = 3;
       
    41 	static final int NETCONN_DISCONNECT_INTERNAL_ERROR = 100;
       
    42 	
       
    43 	static final int NETCONN_ROOMLEAVE_ABANDONED = 0;
       
    44 	static final int NETCONN_ROOMLEAVE_KICKED = 1;
       
    45 	
       
    46 	static final int NETCONN_MSG_TYPE_PLAYERINFO = 0;
       
    47 	static final int NETCONN_MSG_TYPE_SERVERMESSAGE = 1;
       
    48 	static final int NETCONN_MSG_TYPE_WARNING = 2;
       
    49 	static final int NETCONN_MSG_TYPE_ERROR = 3;
       
    50 	
       
    51 	static final int NETCONN_MAPCHANGE_FULL = 0;
       
    52 	static final int NETCONN_MAPCHANGE_MAP = 1;
       
    53 	static final int NETCONN_MAPCHANGE_MAPGEN = 2;
       
    54 	static final int NETCONN_MAPCHANGE_DRAWNMAP = 3;
       
    55 	static final int NETCONN_MAPCHANGE_MAZE_SIZE = 4;
       
    56 	static final int NETCONN_MAPCHANGE_TEMPLATE = 5;
       
    57 	static final int NETCONN_MAPCHANGE_THEME = 6;
       
    58 	static final int NETCONN_MAPCHANGE_SEED = 7;
       
    59 	
       
    60 	static final int GAME_END_FINISHED = 0;
       
    61 	static final int GAME_END_INTERRUPTED = 1;
       
    62 	static final int GAME_END_HALTED = 2;
       
    63 	static final int GAME_END_ERROR = 3;
       
    64 	
       
    65 	static final int HEDGEHOGS_PER_TEAM = 8;
       
    66 	
       
    67 	public static class NetconnPtr extends PointerType { }
   131 	public static class NetconnPtr extends PointerType { }
    68 	public static class MapconnPtr extends PointerType { }
   132 	public static class MapconnPtr extends PointerType { }
    69 	public static class GameconnPtr extends PointerType { }
   133 	public static class GameconnPtr extends PointerType { }
    70 	public static class MetaschemePtr extends PointerType { }
   134 	
       
   135 	// TODO avoid code duplication in the pointer types
       
   136 	public static class MetaschemePtr extends PointerType {
       
   137 		public MetaScheme deref() {
       
   138 			return deref(getPointer());
       
   139 		}
       
   140 		
       
   141 		public static MetaScheme deref(Pointer p) {
       
   142 			MetaschemeStruct struct = new MetaschemeStruct(p);
       
   143 			struct.read();
       
   144 			return struct.toMetaScheme();
       
   145 		}
       
   146 	}
    71 	
   147 	
    72 	public static class RoomArrayPtr extends PointerType { 
   148 	public static class RoomArrayPtr extends PointerType { 
    73 		/**
       
    74 		 * Returns the (native-owned) rooms in this list
       
    75 		 */
       
    76 		public RoomlistRoom[] getRooms(int count) {
   149 		public RoomlistRoom[] getRooms(int count) {
    77 			Pointer ptr = getPointer();
   150 			Pointer ptr = getPointer();
    78 			if(ptr == null) {
   151 			if(ptr == null) {
    79 				return new RoomlistRoom[0];
   152 				return new RoomlistRoom[0];
    80 			}
   153 			}
    86 			return result;
   159 			return result;
    87 		}
   160 		}
    88 	}
   161 	}
    89 	
   162 	
    90 	public static class RoomPtr extends PointerType {
   163 	public static class RoomPtr extends PointerType {
    91 		public RoomPtr() { super(); }
       
    92 		public RoomPtr(Pointer ptr) { super(ptr); }
       
    93 		
       
    94 		public RoomlistRoom deref() {
   164 		public RoomlistRoom deref() {
    95 			return deref(getPointer());
   165 			return deref(getPointer());
    96 		}
   166 		}
    97 		
   167 		
    98 		public static RoomlistRoom deref(Pointer p) {
   168 		public static RoomlistRoom deref(Pointer p) {
    99 			RoomStruct r = new RoomStruct(p);
   169 			RoomStruct struct = new RoomStruct(p);
   100 			r.read();
   170 			struct.read();
   101 			return new RoomlistRoom(r.name, r.map, r.scheme, r.weapons, r.owner, r.playerCount, r.teamCount, r.inProgress);
   171 			return struct.toRoomlistRoom();
   102 		}
   172 		}
   103 	}
   173 	}
   104 	
   174 	
   105 	public static class TeamPtr extends PointerType {
   175 	public static class TeamPtr extends PointerType {
       
   176 		private TeamStruct javaOwnedInstance; 
       
   177 		
   106 		public TeamInGame deref() {
   178 		public TeamInGame deref() {
   107 			return deref(getPointer());
   179 			TeamStruct struct = new TeamStruct(getPointer());
   108 		}
   180 			struct.read();
   109 		
   181 			return struct.toTeamInGame();
   110 		public static TeamInGame deref(Pointer p) {
   182 		}
   111 			TeamStruct ts = new TeamStruct(p);
   183 		
   112 			ts.read();
       
   113 			List<Hog> hogs = new ArrayList<Hog>();
       
   114 			for(int i=0; i<ts.hogs.length; i++) {
       
   115 				HogStruct hog = ts.hogs[i];
       
   116 				hogs.add(new Hog(hog.name, hog.hat, hog.difficulty));
       
   117 			}
       
   118 			Team team = new Team(ts.name, ts.grave, ts.flag, ts.voicepack, ts.fort, hogs);
       
   119 			TeamIngameAttributes attrs = new TeamIngameAttributes(ts.ownerName, ts.colorIndex, ts.hogsInGame, ts.remoteDriven);
       
   120 			return new TeamInGame(team, attrs);
       
   121 		}
       
   122 
       
   123 		public static TeamPtr createJavaOwned(Team t) {
   184 		public static TeamPtr createJavaOwned(Team t) {
   124 			return createJavaOwned(new TeamInGame(t, null));
   185 			return createJavaOwned(new TeamInGame(t, null));
   125 		}
   186 		}
   126 		
   187 		
   127 		public static TeamPtr createJavaOwned(TeamInGame ingameTeam) {
   188 		public static TeamPtr createJavaOwned(TeamInGame ingameTeam) {
   128 			TeamStruct ts = TeamStruct.from(ingameTeam.team, ingameTeam.ingameAttribs);
       
   129 			ts.write();
       
   130 			TeamPtr result = new TeamPtr();
   189 			TeamPtr result = new TeamPtr();
   131 			result.setPointer(ts.getPointer());
   190 			result.javaOwnedInstance = new TeamStruct();
       
   191 			result.javaOwnedInstance.fillFrom(ingameTeam.team, ingameTeam.ingameAttribs);
       
   192 			result.javaOwnedInstance.autoWrite();
       
   193 			result.setPointer(result.javaOwnedInstance.getPointer());
   132 			return result;
   194 			return result;
   133 		}
   195 		}
   134 	}
   196 	}
   135 	
   197 	
   136 	public static class WeaponsetPtr extends PointerType { }
   198 	public static class WeaponsetPtr extends PointerType {
   137 	public static class MapRecipePtr extends PointerType { }
   199 		private WeaponsetStruct javaOwnedInstance; 
   138 	public static class SchemePtr extends PointerType { }
   200 		
       
   201 		public Weaponset deref() {
       
   202 			WeaponsetStruct struct = new WeaponsetStruct(getPointer());
       
   203 			struct.read();
       
   204 			return struct.toWeaponset();
       
   205 		}
       
   206 		
       
   207 		public static WeaponsetPtr createJavaOwned(Weaponset weaponset) {
       
   208 			WeaponsetPtr result = new WeaponsetPtr();
       
   209 			result.javaOwnedInstance = new WeaponsetStruct();
       
   210 			result.javaOwnedInstance.fillFrom(weaponset);
       
   211 			result.javaOwnedInstance.autoWrite();
       
   212 			result.setPointer(result.javaOwnedInstance.getPointer());
       
   213 			return result;
       
   214 		}
       
   215 	}
       
   216 	
       
   217 	public static class WeaponsetListPtr extends PointerType {
       
   218 		private WeaponsetListStruct javaOwnedInstance;
       
   219 		
       
   220 		public List<Weaponset> deref() {
       
   221 			WeaponsetListStruct struct = new WeaponsetListStruct(getPointer());
       
   222 			struct.read();
       
   223 			return struct.toWeaponsetList();
       
   224 		}
       
   225 		
       
   226 		public static WeaponsetListPtr createJavaOwned(List<Weaponset> list) {
       
   227 			WeaponsetListPtr result = new WeaponsetListPtr();
       
   228 			result.javaOwnedInstance = new WeaponsetListStruct();
       
   229 			result.javaOwnedInstance.fillFrom(list);
       
   230 			result.javaOwnedInstance.autoWrite();
       
   231 			result.setPointer(result.javaOwnedInstance.getPointer());
       
   232 			return result;
       
   233 		}
       
   234 	}
       
   235 	
       
   236 	public static class MapRecipePtr extends PointerType {
       
   237 		private MapRecipeStruct javaOwnedInstance;
       
   238 		
       
   239 		public MapRecipe deref() {
       
   240 			MapRecipeStruct struct = new MapRecipeStruct(getPointer());
       
   241 			struct.read();
       
   242 			return struct.toMapRecipe();
       
   243 		}
       
   244 		
       
   245 		public static MapRecipePtr createJavaOwned(MapRecipe recipe) {
       
   246 			MapRecipePtr result = new MapRecipePtr();
       
   247 			result.javaOwnedInstance = new MapRecipeStruct();
       
   248 			result.javaOwnedInstance.fillFrom(recipe);
       
   249 			result.javaOwnedInstance.autoWrite();
       
   250 			result.setPointer(result.javaOwnedInstance.getPointer());
       
   251 			return result;
       
   252 		}
       
   253 	}
       
   254 	
       
   255 	public static class SchemePtr extends PointerType {
       
   256 		private SchemeStruct javaOwnedInstance;
       
   257 		
       
   258 		public Scheme deref() {
       
   259 			SchemeStruct struct = new SchemeStruct(getPointer());
       
   260 			struct.read();
       
   261 			return struct.toScheme();
       
   262 		}
       
   263 		
       
   264 		public static SchemePtr createJavaOwned(Scheme scheme) {
       
   265 			SchemePtr result = new SchemePtr();
       
   266 			result.javaOwnedInstance = new SchemeStruct();
       
   267 			result.javaOwnedInstance.fillFrom(scheme);
       
   268 			result.javaOwnedInstance.autoWrite();
       
   269 			result.setPointer(result.javaOwnedInstance.getPointer());
       
   270 			return result;
       
   271 		}
       
   272 	}
       
   273 	
   139 	public static class SchemelistPtr extends PointerType {
   274 	public static class SchemelistPtr extends PointerType {
   140 		private SchemelistStruct javaOwnedInstance;
   275 		private SchemelistStruct javaOwnedInstance;
   141 		
   276 		
   142 		public List<Scheme> deref() {
   277 		public List<Scheme> deref() {
   143 			return deref(getPointer());
   278 			SchemelistStruct struct = new SchemelistStruct(getPointer());
   144 		}
   279 			struct.read();
   145 		
   280 			return struct.toSchemeList();
   146 		public static List<Scheme> deref(Pointer p) {
       
   147 			SchemelistStruct sls = new SchemelistStruct(p);
       
   148 			sls.read();
       
   149 			return sls.toSchemeList();
       
   150 		}
   281 		}
   151 		
   282 		
   152 		public static SchemelistPtr createJavaOwned(List<Scheme> schemes) {
   283 		public static SchemelistPtr createJavaOwned(List<Scheme> schemes) {
   153 			SchemelistPtr result = new SchemelistPtr();
   284 			SchemelistPtr result = new SchemelistPtr();
   154 			result.javaOwnedInstance = new SchemelistStruct();
   285 			result.javaOwnedInstance = new SchemelistStruct();
   158 			return result;
   289 			return result;
   159 		}
   290 		}
   160 	}
   291 	}
   161 	
   292 	
   162 	public static class GameSetupPtr extends PointerType {
   293 	public static class GameSetupPtr extends PointerType {
       
   294 		private GameSetupStruct javaOwnedInstance;
       
   295 		
       
   296 		public GameConfig deref() {
       
   297 			GameSetupStruct struct = new GameSetupStruct(getPointer());
       
   298 			struct.read();
       
   299 			return struct.toGameConfig();
       
   300 		}
       
   301 		
   163 		public static GameSetupPtr createJavaOwned(GameConfig conf) {
   302 		public static GameSetupPtr createJavaOwned(GameConfig conf) {
   164 			GameSetupStruct gss = GameSetupStruct.from(conf);
       
   165 			gss.write();
       
   166 			GameSetupPtr result = new GameSetupPtr();
   303 			GameSetupPtr result = new GameSetupPtr();
   167 			result.setPointer(gss.getPointer());
   304 			result.javaOwnedInstance = new GameSetupStruct();
       
   305 			result.javaOwnedInstance.fillFrom(conf);
       
   306 			result.javaOwnedInstance.autoWrite();
       
   307 			result.setPointer(result.javaOwnedInstance.getPointer());
   168 			return result;
   308 			return result;
   169 		}
   309 		}
   170 	}
   310 	}
   171 	
   311 	
   172 	static class HogStruct extends Structure {
   312 	static class HogStruct extends Structure {
   175 		private static String[] FIELD_ORDER = new String[] {"name", "hat", "rounds", "kills", "deaths", "suicides", "difficulty", "initialHealth", "weaponset"};
   315 		private static String[] FIELD_ORDER = new String[] {"name", "hat", "rounds", "kills", "deaths", "suicides", "difficulty", "initialHealth", "weaponset"};
   176 
   316 
   177 		public HogStruct() { super(); setFieldOrder(FIELD_ORDER); }
   317 		public HogStruct() { super(); setFieldOrder(FIELD_ORDER); }
   178 		public HogStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   318 		public HogStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   179 		
   319 		
   180 		public static HogStruct from(Hog hog) {
   320 		public void fillFrom(Hog hog) {
   181 			HogStruct hs = new HogStruct();
   321 			difficulty = hog.level;
   182 			hs.difficulty = hog.level;
   322 			hat = hog.hat;
   183 			hs.hat = hog.hat;
   323 			name = hog.name;
   184 			hs.name = hog.name;
   324 		}
   185 			// TODO weaponset
   325 		
   186 			// TODO initialHealth
   326 		public Hog toHog() {
   187 			return hs;
   327 			return new Hog(name, hat, difficulty);
   188 		}
   328 		}
   189 		
   329 		
   190 		public String name;
   330 		public String name;
   191 		public String hat;
   331 		public String hat;
   192 		
   332 		
   196 		public int suicides;
   336 		public int suicides;
   197 	
   337 	
   198 		public int difficulty;
   338 		public int difficulty;
   199 		
   339 		
   200 		public int initialHealth;
   340 		public int initialHealth;
   201 		public WeaponsetPtr weaponset;
   341 		public WeaponsetStruct.ByRef weaponset;
   202 	}
   342 	}
   203 	
   343 	
   204 	static class TeamStruct extends Structure {
   344 	static class TeamStruct extends Structure {
   205 		public static class ByVal extends TeamStruct implements Structure.ByValue {}
   345 		public static class ByVal extends TeamStruct implements Structure.ByValue {}
   206 		public static class ByRef extends TeamStruct implements Structure.ByReference {}
   346 		public static class ByRef extends TeamStruct implements Structure.ByReference {}
   207 		private static String[] FIELD_ORDER = new String[] {"hogs", "name", "grave", "fort", "voicepack", "flag", "bindings", "bindingCount", "rounds", "wins", "campaignProgress", "colorIndex", "hogsInGame", "remoteDriven", "ownerName"};
   347 		private static String[] FIELD_ORDER = new String[] {"hogs", "name", "grave", "fort", "voicepack", "flag", "bindings", "bindingCount", "rounds", "wins", "campaignProgress", "colorIndex", "hogsInGame", "remoteDriven", "ownerName"};
   208 
   348 
   209 		public TeamStruct() { super(); setFieldOrder(FIELD_ORDER); }
   349 		public TeamStruct() { super(); setFieldOrder(FIELD_ORDER); }
   210 		public TeamStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   350 		public TeamStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   211 		
   351 		
   212 		public static TeamStruct from(Team team, TeamIngameAttributes attrs) {
   352 		public void fillFrom(Team team, TeamIngameAttributes attrs) {
   213 			TeamStruct ts = new TeamStruct();
       
   214 			if(team != null) {
   353 			if(team != null) {
   215 				ts.name = team.name;
   354 				name = team.name;
   216 				ts.grave = team.grave;
   355 				grave = team.grave;
   217 				ts.flag = team.flag;
   356 				flag = team.flag;
   218 				ts.voicepack = team.voice;
   357 				voicepack = team.voice;
   219 				ts.fort = team.fort;
   358 				fort = team.fort;
   220 				if(team.hogs.size() != HEDGEHOGS_PER_TEAM) {
   359 				if(team.hogs.size() != Team.HEDGEHOGS_PER_TEAM) {
   221 					throw new IllegalArgumentException();
   360 					throw new IllegalArgumentException();
   222 				}
   361 				}
   223 				for(int i=0; i<ts.hogs.length; i++) {
   362 				for(int i=0; i<hogs.length; i++) {
   224 					ts.hogs[i] = HogStruct.from(team.hogs.get(i));
   363 					hogs[i] = new HogStruct();
       
   364 					hogs[i].fillFrom(team.hogs.get(i));
   225 				}
   365 				}
   226 			}
   366 			}
   227 			
   367 			
   228 			if(attrs != null) {
   368 			if(attrs != null) {
   229 				ts.hogsInGame = attrs.hogCount;
   369 				hogsInGame = attrs.hogCount;
   230 				ts.ownerName = attrs.ownerName;
   370 				ownerName = attrs.ownerName;
   231 				ts.colorIndex = attrs.colorIndex;
   371 				colorIndex = attrs.colorIndex;
   232 				ts.remoteDriven = attrs.remoteDriven;
   372 				remoteDriven = attrs.remoteDriven;
   233 			}
   373 			}
   234 			return ts;
   374 		}
   235 		}
   375 		
   236 		
   376 		public void fillFrom(TeamInGame team, WeaponsetStruct.ByRef weaponset, int initialHealth) {
   237 		public HogStruct[] hogs = new HogStruct[HEDGEHOGS_PER_TEAM];
   377 			fillFrom(team.team, team.ingameAttribs);
       
   378 			for(int i=0; i<hogs.length; i++) {
       
   379 				hogs[i].initialHealth = initialHealth;
       
   380 				hogs[i].weaponset = weaponset;
       
   381 			}
       
   382 		}
       
   383 		
       
   384 		public Team toTeam() {
       
   385 			List<Hog> hogList = new ArrayList<Hog>();
       
   386 			for(int i=0; i<hogs.length; i++) {
       
   387 				hogList.add(hogs[i].toHog());
       
   388 			}
       
   389 			return new Team(name, grave, flag, voicepack, fort, hogList);
       
   390 		}
       
   391 		
       
   392 		public TeamIngameAttributes toTeamIngameAttributes() {
       
   393 			return new TeamIngameAttributes(ownerName, colorIndex, hogsInGame, remoteDriven);
       
   394 		}
       
   395 		
       
   396 		public TeamInGame toTeamInGame() {
       
   397 			return new TeamInGame(toTeam(), toTeamIngameAttributes());
       
   398 		}
       
   399 		
       
   400 		public HogStruct[] hogs = new HogStruct[Team.HEDGEHOGS_PER_TEAM];
   238 		public String name;
   401 		public String name;
   239 		public String grave;
   402 		public String grave;
   240 		public String fort;
   403 		public String fort;
   241 		public String voicepack;
   404 		public String voicepack;
   242 		public String flag;
   405 		public String flag;
   252 		public int hogsInGame;
   415 		public int hogsInGame;
   253 		public boolean remoteDriven;
   416 		public boolean remoteDriven;
   254 		public String ownerName;
   417 		public String ownerName;
   255 	}
   418 	}
   256 	
   419 	
       
   420 	static class WeaponsetStruct extends Structure {
       
   421 		public static class ByVal extends WeaponsetStruct implements Structure.ByValue {}
       
   422 		public static class ByRef extends WeaponsetStruct implements Structure.ByReference {}
       
   423 		private static String[] FIELD_ORDER = new String[] {"_referenceCount", "loadout", "crateprob", "crateammo", "delay", "name"};
       
   424 		
       
   425 		public WeaponsetStruct() { super(); setFieldOrder(FIELD_ORDER); }
       
   426 		public WeaponsetStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
       
   427 		
       
   428 		public void fillFrom(Weaponset weaponset) {
       
   429 			_referenceCount = 0;
       
   430 			fillWeaponInfo(loadout, weaponset.loadout);
       
   431 			fillWeaponInfo(crateprob, weaponset.crateProb);
       
   432 			fillWeaponInfo(crateammo, weaponset.crateAmmo);
       
   433 			fillWeaponInfo(delay, weaponset.delay);
       
   434 			name = weaponset.name;
       
   435 		}
       
   436 		
       
   437 		private static void fillWeaponInfo(byte[] array, String str) {
       
   438 			for(int i=0; i<array.length-1; i++) {
       
   439 				array[i] = (byte) (i<str.length() ? str.charAt(i) : '0');
       
   440 			}
       
   441 			array[array.length-1] = (byte)0;
       
   442 		}
       
   443 		
       
   444 		public Weaponset toWeaponset() {
       
   445 			return new Weaponset(name, weaponInfoToString(loadout), weaponInfoToString(crateprob), weaponInfoToString(crateammo), weaponInfoToString(delay));
       
   446 		}
       
   447 		
       
   448 		private static String weaponInfoToString(byte[] array) {
       
   449 			try {
       
   450 				return new String(array, 0, array.length-1, "ASCII");
       
   451 			} catch (UnsupportedEncodingException e) {
       
   452 				throw new AssertionError();
       
   453 			}
       
   454 		}
       
   455 		
       
   456 		public int _referenceCount;
       
   457 		public byte[] loadout = new byte[Weaponset.WEAPONS_COUNT+1];
       
   458 		public byte[] crateprob = new byte[Weaponset.WEAPONS_COUNT+1];
       
   459 		public byte[] crateammo = new byte[Weaponset.WEAPONS_COUNT+1];
       
   460 		public byte[] delay = new byte[Weaponset.WEAPONS_COUNT+1];
       
   461 		public String name;
       
   462 	}
       
   463 	
       
   464 	/**
       
   465 	 * Represents a flib_weaponset*, for use as part of a flib_weaponset**
       
   466 	 */
       
   467 	static class WeaponsetPointerByReference extends Structure implements Structure.ByReference {
       
   468 		private static String[] FIELD_ORDER = new String[] {"weaponset"};
       
   469 		
       
   470 		public WeaponsetPointerByReference() { super(); setFieldOrder(FIELD_ORDER); }
       
   471 		public WeaponsetPointerByReference(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
       
   472 		
       
   473 		public WeaponsetStruct.ByRef weaponset;
       
   474 	}
       
   475 	
       
   476 	static class WeaponsetListStruct extends Structure {
       
   477 		public static class ByVal extends WeaponsetListStruct implements Structure.ByValue {}
       
   478 		public static class ByRef extends WeaponsetListStruct implements Structure.ByReference {}
       
   479 		private static String[] FIELD_ORDER = new String[] {"weaponsetCount", "weaponsets"};
       
   480 		
       
   481 		public WeaponsetListStruct() { super(); setFieldOrder(FIELD_ORDER); }
       
   482 		public WeaponsetListStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
       
   483 		
       
   484 		public void fillFrom(List<Weaponset> list) {
       
   485 			weaponsetCount = list.size();
       
   486 			weaponsets = new WeaponsetPointerByReference();
       
   487 			Structure[] structs = weaponsets.toArray(weaponsetCount);
       
   488 			
       
   489 			for(int i=0; i<weaponsetCount; i++) {
       
   490 				WeaponsetPointerByReference pstruct = (WeaponsetPointerByReference)structs[i];
       
   491 				pstruct.weaponset = new WeaponsetStruct.ByRef();
       
   492 				pstruct.weaponset.fillFrom(list.get(i));
       
   493 			}
       
   494 		}
       
   495 		
       
   496 		/**
       
   497 		 * Only use on native-owned structs!
       
   498 		 * Calling this method on a Java-owned struct could cause garbage collection of referenced
       
   499 		 * structures.
       
   500 		 */
       
   501 		public List<Weaponset> toWeaponsetList() {
       
   502 			if(weaponsetCount<=0) {
       
   503 				return new ArrayList<Weaponset>();
       
   504 			} else {
       
   505 				List<Weaponset> list = new ArrayList<Weaponset>(weaponsetCount);
       
   506 				Structure[] structs = weaponsets.toArray(weaponsetCount);
       
   507 				
       
   508 				for(int i=0; i<weaponsetCount; i++) {
       
   509 					WeaponsetPointerByReference pstruct = (WeaponsetPointerByReference)structs[i];
       
   510 					list.add(pstruct.weaponset.toWeaponset());
       
   511 				}
       
   512 				return list;
       
   513 			}
       
   514 		}
       
   515 		
       
   516 		public int weaponsetCount;
       
   517 		public WeaponsetPointerByReference weaponsets;
       
   518 	}
       
   519 	
   257 	static class RoomStruct extends Structure {
   520 	static class RoomStruct extends Structure {
   258 		public static class ByVal extends RoomStruct implements Structure.ByValue {}
   521 		public static class ByVal extends RoomStruct implements Structure.ByValue {}
   259 		public static class ByRef extends RoomStruct implements Structure.ByReference {}
   522 		public static class ByRef extends RoomStruct implements Structure.ByReference {}
   260 		private static String[] FIELD_ORDER = new String[] {"inProgress", "name", "playerCount", "teamCount", "owner", "map", "scheme", "weapons"};
   523 		private static String[] FIELD_ORDER = new String[] {"inProgress", "name", "playerCount", "teamCount", "owner", "map", "scheme", "weapons"};
   261 		
   524 		
   262 		public RoomStruct() { super(); setFieldOrder(FIELD_ORDER); }
   525 		public RoomStruct() { super(); setFieldOrder(FIELD_ORDER); }
   263 		public RoomStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   526 		public RoomStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
       
   527 
       
   528 		public RoomlistRoom toRoomlistRoom() {
       
   529 			return new RoomlistRoom(name, map, scheme, weapons, owner, playerCount, teamCount, inProgress);
       
   530 		}
   264 		
   531 		
   265 	    public boolean inProgress;
   532 	    public boolean inProgress;
   266 	    public String name;
   533 	    public String name;
   267 	    public int playerCount;
   534 	    public int playerCount;
   268 	    public int teamCount;
   535 	    public int teamCount;
   273 	}
   540 	}
   274 	
   541 	
   275 	static class MapRecipeStruct extends Structure {
   542 	static class MapRecipeStruct extends Structure {
   276 		public static class ByVal extends MapRecipeStruct implements Structure.ByValue {}
   543 		public static class ByVal extends MapRecipeStruct implements Structure.ByValue {}
   277 		public static class ByRef extends MapRecipeStruct implements Structure.ByReference {}
   544 		public static class ByRef extends MapRecipeStruct implements Structure.ByReference {}
   278 		private static String[] FIELD_ORDER = new String[] {"_referenceCount", "mapgen", "name", "seed", "theme", "drawData", "drawDataSize", "templateFilter", "mazeSize"};
   545 		private static String[] FIELD_ORDER = new String[] {"mapgen", "name", "seed", "theme", "drawData", "drawDataSize", "templateFilter", "mazeSize"};
   279 		
   546 		
   280 		public MapRecipeStruct() { super(); setFieldOrder(FIELD_ORDER); }
   547 		public MapRecipeStruct() { super(); setFieldOrder(FIELD_ORDER); }
   281 		public MapRecipeStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   548 		public MapRecipeStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   282 		
   549 		
   283 		public int _referenceCount;
   550 		public void fillFrom(MapRecipe map) {
       
   551 			mapgen = map.mapgen;
       
   552 			name = map.name;
       
   553 			seed = map.seed;
       
   554 			theme = map.theme;
       
   555 			byte[] buf = map.getDrawData();
       
   556 			if(buf != null) {
       
   557 				drawData = new Memory(buf.length);
       
   558 				drawData.write(0, buf, 0, buf.length);
       
   559 				drawDataSize = new NativeLong(buf.length);
       
   560 			} else {
       
   561 				drawData = null;
       
   562 				drawDataSize = new NativeLong(0);
       
   563 			}
       
   564 			templateFilter = map.templateFilter;
       
   565 			mazeSize = map.mazeSize;
       
   566 		}
       
   567 		
       
   568 		public MapRecipe toMapRecipe() {
       
   569 			byte[] buf = null;
       
   570 			if(drawData != null && drawDataSize.intValue()>0) {
       
   571 				buf = new byte[drawDataSize.intValue()];
       
   572 				drawData.read(0, buf, 0, drawDataSize.intValue());
       
   573 			}
       
   574 			return new MapRecipe(mapgen, templateFilter, mazeSize, name, seed, theme, buf);
       
   575 		}
       
   576 		
   284 		public int mapgen;
   577 		public int mapgen;
   285 		public String name;
   578 		public String name;
   286 		public String seed;
   579 		public String seed;
   287 		public String theme;
   580 		public String theme;
   288 		public Pointer drawData;
   581 		public Pointer drawData;
   289 		public int drawDataSize;
   582 		public NativeLong drawDataSize;
   290 		public int templateFilter;
   583 		public int templateFilter;
   291 		public int mazeSize;
   584 		public int mazeSize;
   292 	}
   585 	}
   293 	
   586 	
   294 	static class MetaschemeSettingStruct extends Structure {
   587 	static class MetaschemeSettingStruct extends Structure {
   406 	}
   699 	}
   407 	
   700 	
   408 	static class SchemeStruct extends Structure {
   701 	static class SchemeStruct extends Structure {
   409 		public static class ByVal extends SchemeStruct implements Structure.ByValue {}
   702 		public static class ByVal extends SchemeStruct implements Structure.ByValue {}
   410 		public static class ByRef extends SchemeStruct implements Structure.ByReference {}
   703 		public static class ByRef extends SchemeStruct implements Structure.ByReference {}
   411 		private static String[] FIELD_ORDER = new String[] {"_referenceCount", "meta", "name", "settings", "mod"};
   704 		private static String[] FIELD_ORDER = new String[] {"meta", "name", "settings", "mod"};
   412 		
   705 		
   413 		public SchemeStruct() { super(); setFieldOrder(FIELD_ORDER); }
   706 		public SchemeStruct() { super(); setFieldOrder(FIELD_ORDER); }
   414 		public SchemeStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   707 		public SchemeStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   415 		
   708 		
   416 		public void fillFrom(Scheme scheme) {
   709 		public void fillFrom(Scheme scheme) {
   440 				modsMap.put(metaScheme.mods.get(i).name, mods.getByte(i) != 0 ? Boolean.TRUE : Boolean.FALSE);
   733 				modsMap.put(metaScheme.mods.get(i).name, mods.getByte(i) != 0 ? Boolean.TRUE : Boolean.FALSE);
   441 			}
   734 			}
   442 			return new Scheme(metaScheme, name, settingsMap, modsMap);
   735 			return new Scheme(metaScheme, name, settingsMap, modsMap);
   443 		}
   736 		}
   444 		
   737 		
   445 		public int _referenceCount;
       
   446 		public MetaschemeStruct.ByRef meta;
   738 		public MetaschemeStruct.ByRef meta;
   447 		public String name;
   739 		public String name;
   448 		public Pointer settings;
   740 		public Pointer settings;
   449 		public Pointer mods;
   741 		public Pointer mods;
   450 	}
   742 	}
   467 		private static String[] FIELD_ORDER = new String[] {"schemeCount", "schemes"};
   759 		private static String[] FIELD_ORDER = new String[] {"schemeCount", "schemes"};
   468 		
   760 		
   469 		public SchemelistStruct() { super(); setFieldOrder(FIELD_ORDER); }
   761 		public SchemelistStruct() { super(); setFieldOrder(FIELD_ORDER); }
   470 		public SchemelistStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   762 		public SchemelistStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   471 		
   763 		
       
   764 		public void fillFrom(List<Scheme> schemeList) {
       
   765 			schemeCount = schemeList.size();
       
   766 			schemes = new SchemePointerByReference();
       
   767 			Structure[] schemePtrStructs = schemes.toArray(schemeCount);
       
   768 			
       
   769 			for(int i=0; i<this.schemeCount; i++) {
       
   770 				SchemePointerByReference spbr = (SchemePointerByReference)schemePtrStructs[i];
       
   771 				spbr.scheme = new SchemeStruct.ByRef();
       
   772 				spbr.scheme.fillFrom(schemeList.get(i));
       
   773 			}
       
   774 		}
       
   775 
   472 		/**
   776 		/**
   473 		 * Only use on native-owned structs!
   777 		 * Only use on native-owned structs!
   474 		 * Calling this method on a Java-owned struct could cause garbage collection of referenced
   778 		 * Calling this method on a Java-owned struct could cause garbage collection of referenced
   475 		 * structures.
   779 		 * structures.
   476 		 */
   780 		 */
   488 				}
   792 				}
   489 				return schemeList;
   793 				return schemeList;
   490 			}
   794 			}
   491 		}
   795 		}
   492 		
   796 		
   493 		public void fillFrom(List<Scheme> schemeList) {
       
   494 			schemeCount = schemeList.size();
       
   495 			schemes = new SchemePointerByReference();
       
   496 			Structure[] schemePtrStructs = schemes.toArray(schemeCount);
       
   497 			
       
   498 			for(int i=0; i<this.schemeCount; i++) {
       
   499 				SchemePointerByReference spbr = (SchemePointerByReference)schemePtrStructs[i];
       
   500 				spbr.scheme = new SchemeStruct.ByRef();
       
   501 				spbr.scheme.fillFrom(schemeList.get(i));
       
   502 			}
       
   503 		}
       
   504 		
       
   505 		public int schemeCount;
   797 		public int schemeCount;
   506 		public SchemePointerByReference schemes;
   798 		public SchemePointerByReference schemes;
       
   799 	}
       
   800 	
       
   801 	/**
       
   802 	 * Represents a flib_team*, for use as part of a flib_team**
       
   803 	 */
       
   804 	static class TeamPointerByReference extends Structure implements Structure.ByReference {
       
   805 		private static String[] FIELD_ORDER = new String[] {"team"};
       
   806 		
       
   807 		public TeamPointerByReference() { super(); setFieldOrder(FIELD_ORDER); }
       
   808 		public TeamPointerByReference(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
       
   809 		
       
   810 		public TeamStruct.ByRef team;
   507 	}
   811 	}
   508 	
   812 	
   509 	static class TeamlistStruct extends Structure {
   813 	static class TeamlistStruct extends Structure {
   510 		public static class ByVal extends TeamlistStruct implements Structure.ByValue {}
   814 		public static class ByVal extends TeamlistStruct implements Structure.ByValue {}
   511 		public static class ByRef extends TeamlistStruct implements Structure.ByReference {}
   815 		public static class ByRef extends TeamlistStruct implements Structure.ByReference {}
       
   816 
   512 		private static String[] FIELD_ORDER = new String[] {"teamCount", "teams"};
   817 		private static String[] FIELD_ORDER = new String[] {"teamCount", "teams"};
   513 		
   818 		
   514 		public TeamlistStruct() { super(); setFieldOrder(FIELD_ORDER); }
   819 		public TeamlistStruct() { super(); setFieldOrder(FIELD_ORDER); }
   515 		public TeamlistStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   820 		public TeamlistStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   516 		
   821 		
       
   822 		public void fillFrom(List<TeamInGame> teamList, WeaponsetStruct.ByRef weaponset, int initialHealth) {
       
   823 			teamCount = teamList.size();
       
   824 			teams = new TeamPointerByReference();
       
   825 			Structure[] teamPtrStructs = teams.toArray(teamCount);
       
   826 			
       
   827 			for(int i=0; i<this.teamCount; i++) {
       
   828 				TeamPointerByReference tpbr = (TeamPointerByReference)teamPtrStructs[i];
       
   829 				tpbr.team = new TeamStruct.ByRef();
       
   830 				tpbr.team.fillFrom(teamList.get(i), weaponset, initialHealth);
       
   831 			}
       
   832 		}
       
   833 
       
   834 		public List<TeamInGame> toTeamInGameList() {
       
   835 			if(teamCount<=0) {
       
   836 				return new ArrayList<TeamInGame>();
       
   837 			} else {
       
   838 				List<TeamInGame> result = new ArrayList<TeamInGame>(teamCount);
       
   839 				Structure[] structs = teams.toArray(teamCount);
       
   840 				
       
   841 				for(int i=0; i<teamCount; i++) {
       
   842 					TeamPointerByReference struct = (TeamPointerByReference)structs[i];
       
   843 					result.add(struct.team.toTeamInGame());
       
   844 				}
       
   845 				return result;
       
   846 			}
       
   847 		}
       
   848 		
   517 		public int teamCount;
   849 		public int teamCount;
   518 		public Pointer teams;
   850 		public TeamPointerByReference teams;
   519 	}
   851 	}
   520 	
   852 	
   521 	static class GameSetupStruct extends Structure {
   853 	static class GameSetupStruct extends Structure {
   522 		public static class ByVal extends GameSetupStruct implements Structure.ByValue {}
   854 		public static class ByVal extends GameSetupStruct implements Structure.ByValue {}
   523 		public static class ByRef extends GameSetupStruct implements Structure.ByReference {}
   855 		public static class ByRef extends GameSetupStruct implements Structure.ByReference {}
   524 		private static String[] FIELD_ORDER = new String[] {"script", "gamescheme", "map", "teamlist"};
   856 		private static String[] FIELD_ORDER = new String[] {"script", "gamescheme", "map", "teamlist"};
   525 		
   857 		
   526 		public GameSetupStruct() { super(); setFieldOrder(FIELD_ORDER); }
   858 		public GameSetupStruct() { super(); setFieldOrder(FIELD_ORDER); }
   527 		public GameSetupStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   859 		public GameSetupStruct(Pointer ptr) { super(ptr); setFieldOrder(FIELD_ORDER); }
   528 		
   860 		
   529 		public static GameSetupStruct from(GameConfig conf) {
   861 		public void fillFrom(GameConfig conf) {
   530 			GameSetupStruct gss = new GameSetupStruct();
   862 			script = conf.style;
   531 			gss.gamescheme = new SchemeStruct.ByRef();
   863 			gamescheme = new SchemeStruct.ByRef();
   532 			gss.gamescheme.fillFrom(conf.scheme);
   864 			gamescheme.fillFrom(conf.scheme);
   533 			gss.map = new MapRecipeStruct.ByRef();
   865 			map = new MapRecipeStruct.ByRef();
   534 			// TODO gss.map.fillFrom(conf.map, conf.seed, conf.theme);
   866 			map.fillFrom(conf.map);
   535 			gss.script = conf.style;
   867 			
   536 			gss.teamlist = new TeamlistStruct.ByRef();
   868 			/*
   537 			// TODO gss.teamlist.fillFrom(conf.teams, conf.weapon);
   869 			 * At this point we deviate from the usual copying pattern because the frontlib
   538 			return gss;
   870 			 * expects per-hog weapons and initial health, but the UI models them as per-
       
   871 			 * game, so we extract them from the config here and pass them on to be included
       
   872 			 * in each hog.
       
   873 			 */
       
   874 			WeaponsetStruct.ByRef wss = new WeaponsetStruct.ByRef();
       
   875 			wss.fillFrom(conf.weaponset);
       
   876 			int initialHealth = conf.scheme.getHealth();
       
   877 			
       
   878 			teamlist = new TeamlistStruct.ByRef();
       
   879 			teamlist.fillFrom(conf.teams, wss, initialHealth);
       
   880 		}
       
   881 		
       
   882 		public GameConfig toGameConfig() {
       
   883 			Scheme scheme = gamescheme != null ? gamescheme.toScheme() : null;
       
   884 			MapRecipe mapRecipe = map != null ? map.toMapRecipe() : null;
       
   885 			List<TeamInGame> teams = teamlist != null ? teamlist.toTeamInGameList() : null;
       
   886 			
       
   887 			WeaponsetStruct weaponsetStruct = teamlist != null && teamlist.teamCount>0 ? teamlist.teams.team.hogs[0].weaponset : null;
       
   888 			Weaponset weaponset = weaponsetStruct != null ? weaponsetStruct.toWeaponset() : null;
       
   889 			return new GameConfig(script, scheme, mapRecipe, teams, weaponset);
   539 		}
   890 		}
   540 
   891 
   541 		public String script;
   892 		public String script;
   542 		public SchemeStruct.ByRef gamescheme;
   893 		public SchemeStruct.ByRef gamescheme;
   543 		public MapRecipeStruct.ByRef map;
   894 		public MapRecipeStruct.ByRef map;
   544 		public TeamlistStruct.ByRef teamlist;
   895 		public TeamlistStruct.ByRef teamlist;
   545 	}
   896 	}
   546 	
   897 	
       
   898 	/*
       
   899 	 * Callback interfaces. The context parameter is never needed here and
       
   900 	 * should always be ignored. Be sure to keep a reference to each callback
       
   901 	 * for as long as they might be called by native code, to avoid premature
       
   902 	 * garbage collection.
       
   903 	 */
   547 	public static interface VoidCallback extends Callback {
   904 	public static interface VoidCallback extends Callback {
   548 		void callback(Pointer context);
   905 		void callback(Pointer context);
   549 	}
   906 	}
   550 	
   907 	
   551 	public static interface StrCallback extends Callback {
   908 	public static interface StrCallback extends Callback {
   618 	
   975 	
   619 	public static interface LogCallback extends Callback {
   976 	public static interface LogCallback extends Callback {
   620 		void callback(int level, String logMessage);
   977 		void callback(int level, String logMessage);
   621 	}
   978 	}
   622 	
   979 	
       
   980 	// frontlib.h
   623     int flib_init();
   981     int flib_init();
   624     void flib_quit();
   982     void flib_quit();
   625 	
   983 	
       
   984     // hwconsts.h
       
   985     int flib_get_teamcolor(int colorIndex);
       
   986     int flib_get_teamcolor_count();
       
   987     int flib_get_hedgehogs_per_team();
       
   988     int flib_get_weapons_count();
       
   989     
       
   990     // net/netconn.h
       
   991 	static final int NETCONN_STATE_CONNECTING = 0;
       
   992 	static final int NETCONN_STATE_LOBBY = 1;
       
   993 	static final int NETCONN_STATE_ROOM = 2;
       
   994 	static final int NETCONN_STATE_DISCONNECTED = 10;
       
   995 	
       
   996 	static final int NETCONN_DISCONNECT_NORMAL = 0;
       
   997 	static final int NETCONN_DISCONNECT_SERVER_TOO_OLD = 1;
       
   998 	static final int NETCONN_DISCONNECT_AUTH_FAILED = 2;
       
   999 	static final int NETCONN_DISCONNECT_CONNLOST = 3;
       
  1000 	static final int NETCONN_DISCONNECT_INTERNAL_ERROR = 100;
       
  1001 	
       
  1002 	static final int NETCONN_ROOMLEAVE_ABANDONED = 0;
       
  1003 	static final int NETCONN_ROOMLEAVE_KICKED = 1;
       
  1004 	
       
  1005 	static final int NETCONN_MSG_TYPE_PLAYERINFO = 0;
       
  1006 	static final int NETCONN_MSG_TYPE_SERVERMESSAGE = 1;
       
  1007 	static final int NETCONN_MSG_TYPE_WARNING = 2;
       
  1008 	static final int NETCONN_MSG_TYPE_ERROR = 3;
       
  1009 	
       
  1010 	static final int NETCONN_MAPCHANGE_FULL = 0;
       
  1011 	static final int NETCONN_MAPCHANGE_MAP = 1;
       
  1012 	static final int NETCONN_MAPCHANGE_MAPGEN = 2;
       
  1013 	static final int NETCONN_MAPCHANGE_DRAWNMAP = 3;
       
  1014 	static final int NETCONN_MAPCHANGE_MAZE_SIZE = 4;
       
  1015 	static final int NETCONN_MAPCHANGE_TEMPLATE = 5;
       
  1016 	static final int NETCONN_MAPCHANGE_THEME = 6;
       
  1017 	static final int NETCONN_MAPCHANGE_SEED = 7;
       
  1018     
   626 	NetconnPtr flib_netconn_create(String playerName, MetaschemePtr meta, String dataDirPath, String host, int port);
  1019 	NetconnPtr flib_netconn_create(String playerName, MetaschemePtr meta, String dataDirPath, String host, int port);
   627 	void flib_netconn_destroy(NetconnPtr conn);
  1020 	void flib_netconn_destroy(NetconnPtr conn);
   628 
  1021 
   629 	void flib_netconn_tick(NetconnPtr conn);
  1022 	void flib_netconn_tick(NetconnPtr conn);
   630 	boolean flib_netconn_is_chief(NetconnPtr conn);
  1023 	boolean flib_netconn_is_chief(NetconnPtr conn);
   631 	boolean flib_netconn_is_in_room_context(NetconnPtr conn);
       
   632 	String flib_netconn_get_playername(NetconnPtr conn);
  1024 	String flib_netconn_get_playername(NetconnPtr conn);
   633 	GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn);
  1025 	GameSetupPtr flib_netconn_create_gamesetup(NetconnPtr conn);
   634 	int flib_netconn_send_quit(NetconnPtr conn, String quitmsg);
  1026 	int flib_netconn_send_quit(NetconnPtr conn, String quitmsg);
   635 	int flib_netconn_send_chat(NetconnPtr conn, String chat);
  1027 	int flib_netconn_send_chat(NetconnPtr conn, String chat);
   636 	int flib_netconn_send_teamchat(NetconnPtr conn, String msg);
  1028 	int flib_netconn_send_teamchat(NetconnPtr conn, String msg);
   642 	int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName);
  1034 	int flib_netconn_send_renameRoom(NetconnPtr conn, String roomName);
   643 	int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg);
  1035 	int flib_netconn_send_leaveRoom(NetconnPtr conn, String msg);
   644 	int flib_netconn_send_toggleReady(NetconnPtr conn);
  1036 	int flib_netconn_send_toggleReady(NetconnPtr conn);
   645 	int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team);
  1037 	int flib_netconn_send_addTeam(NetconnPtr conn, TeamPtr team);
   646 	int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname);
  1038 	int flib_netconn_send_removeTeam(NetconnPtr conn, String teamname);
   647 	int flib_netconn_send_engineMessage(NetconnPtr conn, Buffer message, NativeLong size); // TODO check if NativeLong==size_t
  1039 	int flib_netconn_send_engineMessage(NetconnPtr conn, Buffer message, NativeLong size);
   648 	int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount);
  1040 	int flib_netconn_send_teamHogCount(NetconnPtr conn, String teamname, int hogcount);
   649 	int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex);
  1041 	int flib_netconn_send_teamColor(NetconnPtr conn, String teamname, int colorIndex);
   650 	int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset);
  1042 	int flib_netconn_send_weaponset(NetconnPtr conn, WeaponsetPtr weaponset);
   651 	int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map);
  1043 	int flib_netconn_send_map(NetconnPtr conn, MapRecipePtr map);
   652 	int flib_netconn_send_mapName(NetconnPtr conn, String mapName);
  1044 	int flib_netconn_send_mapName(NetconnPtr conn, String mapName);
   700 	void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context);
  1092 	void flib_netconn_onScriptChanged(NetconnPtr conn, StrCallback callback, Pointer context);
   701 	void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context);
  1093 	void flib_netconn_onWeaponsetChanged(NetconnPtr conn, WeaponsetCallback callback, Pointer context);
   702 	void flib_netconn_onAdminAccess(NetconnPtr conn, VoidCallback callback, Pointer context);
  1094 	void flib_netconn_onAdminAccess(NetconnPtr conn, VoidCallback callback, Pointer context);
   703 	void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context);
  1095 	void flib_netconn_onServerVar(NetconnPtr conn, StrStrCallback callback, Pointer context);
   704 
  1096 
   705 	// Gameconn
  1097 	// ipc/gameconn.h
       
  1098 	static final int GAME_END_FINISHED = 0;
       
  1099 	static final int GAME_END_INTERRUPTED = 1;
       
  1100 	static final int GAME_END_HALTED = 2;
       
  1101 	static final int GAME_END_ERROR = 3;
       
  1102 	
   706 	GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame);
  1103 	GameconnPtr flib_gameconn_create(String playerName, GameSetupPtr setup, boolean netgame);
   707 	GameconnPtr flib_gameconn_create_playdemo(Buffer demo, NativeLong size);
  1104 	GameconnPtr flib_gameconn_create_playdemo(Buffer demo, NativeLong size);
   708 	GameconnPtr flib_gameconn_create_loadgame(String playerName, Buffer save, NativeLong size);
  1105 	GameconnPtr flib_gameconn_create_loadgame(String playerName, Buffer save, NativeLong size);
   709 	GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script);
  1106 	GameconnPtr flib_gameconn_create_campaign(String playerName, String seed, String script);
   710 
  1107 
   713 	void flib_gameconn_tick(GameconnPtr conn);
  1110 	void flib_gameconn_tick(GameconnPtr conn);
   714 
  1111 
   715 	int flib_gameconn_send_enginemsg(GameconnPtr conn, Buffer data, NativeLong len);
  1112 	int flib_gameconn_send_enginemsg(GameconnPtr conn, Buffer data, NativeLong len);
   716 	int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg);
  1113 	int flib_gameconn_send_textmsg(GameconnPtr conn, int msgtype, String msg);
   717 	int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg);
  1114 	int flib_gameconn_send_chatmsg(GameconnPtr conn, String playername, String msg);
       
  1115 	int flib_gameconn_send_quit(GameconnPtr conn);
   718 	
  1116 	
   719 	void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context);
  1117 	void flib_gameconn_onConnect(GameconnPtr conn, VoidCallback callback, Pointer context);
   720 	void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context);
  1118 	void flib_gameconn_onDisconnect(GameconnPtr conn, IntCallback callback, Pointer context);
   721 	void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context);
  1119 	void flib_gameconn_onErrorMessage(GameconnPtr conn, StrCallback callback, Pointer context);
   722 	void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context);
  1120 	void flib_gameconn_onChat(GameconnPtr conn, StrBoolCallback callback, Pointer context);
   723 	void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context);
  1121 	void flib_gameconn_onGameRecorded(GameconnPtr conn, BytesBoolCallback callback, Pointer context);
   724 	void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context);
  1122 	void flib_gameconn_onEngineMessage(GameconnPtr conn, BytesCallback callback, Pointer context);
   725 	
  1123 	
   726 	// MapConn
  1124 	// ipc/mapconn.h
   727 	MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc);
  1125 	MapconnPtr flib_mapconn_create(MapRecipePtr mapdesc);
   728 	void flib_mapconn_destroy(MapconnPtr conn);
  1126 	void flib_mapconn_destroy(MapconnPtr conn);
   729 	int flib_mapconn_getport(MapconnPtr conn);
  1127 	int flib_mapconn_getport(MapconnPtr conn);
   730 	void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context);
  1128 	void flib_mapconn_onSuccess(MapconnPtr conn, MapimageCallback callback, Pointer context);
   731 	void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context);
  1129 	void flib_mapconn_onFailure(MapconnPtr conn, StrCallback callback, Pointer context);
   732 	void flib_mapconn_tick(MapconnPtr conn);
  1130 	void flib_mapconn_tick(MapconnPtr conn);
   733 	
  1131 	
   734 	// GameSetup
  1132 	// model/map.h
   735 	void flib_gamesetup_destroy(GameSetupPtr gamesetup);
       
   736 	GameSetupPtr flib_gamesetup_copy(GameSetupPtr gamesetup);
       
   737 	
       
   738 	// MapRecipe
       
   739 	public static final int MAPGEN_REGULAR = 0;
  1133 	public static final int MAPGEN_REGULAR = 0;
   740 	public static final int MAPGEN_MAZE = 1;
  1134 	public static final int MAPGEN_MAZE = 1;
   741 	public static final int MAPGEN_DRAWN = 2;
  1135 	public static final int MAPGEN_DRAWN = 2;
   742 	public static final int MAPGEN_NAMED = 3;
  1136 	public static final int MAPGEN_NAMED = 3;
   743 
  1137 
   752 	public static final int MAZE_SIZE_MEDIUM_TUNNELS = 1;
  1146 	public static final int MAZE_SIZE_MEDIUM_TUNNELS = 1;
   753 	public static final int MAZE_SIZE_LARGE_TUNNELS = 2;
  1147 	public static final int MAZE_SIZE_LARGE_TUNNELS = 2;
   754 	public static final int MAZE_SIZE_SMALL_ISLANDS = 3;
  1148 	public static final int MAZE_SIZE_SMALL_ISLANDS = 3;
   755 	public static final int MAZE_SIZE_MEDIUM_ISLANDS = 4;
  1149 	public static final int MAZE_SIZE_MEDIUM_ISLANDS = 4;
   756 	public static final int MAZE_SIZE_LARGE_ISLANDS = 5;
  1150 	public static final int MAZE_SIZE_LARGE_ISLANDS = 5;
   757 	
  1151 		
   758 	MapRecipePtr flib_map_create_regular(String seed, String theme, int templateFilter);
  1152 	// model/scheme.h
   759 	MapRecipePtr flib_map_create_maze(String seed, String theme, int mazeSize);
       
   760 	MapRecipePtr flib_map_create_named(String seed, String name);
       
   761 	MapRecipePtr flib_map_create_drawn(String seed, String theme, Buffer drawData, NativeLong drawDataSize);
       
   762 	MapRecipePtr flib_map_copy(MapRecipePtr map);
       
   763 	MapRecipePtr flib_map_retain(MapRecipePtr map);
       
   764 	void flib_map_release(MapRecipePtr map);
       
   765 	
       
   766 	// Metascheme
       
   767 	MetaschemePtr flib_metascheme_from_ini(String filename);
  1153 	MetaschemePtr flib_metascheme_from_ini(String filename);
   768 	MetaschemePtr flib_metascheme_retain(MetaschemePtr metainfo);
  1154 	MetaschemePtr flib_metascheme_retain(MetaschemePtr metainfo);
   769 	void flib_metascheme_release(MetaschemePtr metainfo);
  1155 	void flib_metascheme_release(MetaschemePtr metainfo);
   770 
  1156 
   771 	// Scheme lists
  1157 	// model/schemelist.h
   772 	SchemelistPtr flib_schemelist_from_ini(MetaschemePtr meta, String filename);
  1158 	SchemelistPtr flib_schemelist_from_ini(MetaschemePtr meta, String filename);
   773 	int flib_schemelist_to_ini(String filename, SchemelistPtr list);
  1159 	int flib_schemelist_to_ini(String filename, SchemelistPtr list);
   774 	void flib_schemelist_destroy(SchemelistPtr list);
  1160 	void flib_schemelist_destroy(SchemelistPtr list);
   775 	
  1161 	
   776 	// Team
  1162 	// model/team.h
   777 	void flib_team_destroy(TeamPtr team);
       
   778 	TeamPtr flib_team_from_ini(String filename);
  1163 	TeamPtr flib_team_from_ini(String filename);
   779 	int flib_team_to_ini(String filename, TeamPtr team);
  1164 	int flib_team_to_ini(String filename, TeamPtr team);
   780 	void flib_team_set_weaponset(TeamPtr team, WeaponsetPtr set);
  1165 	void flib_team_destroy(TeamPtr team);
   781 	void flib_team_set_health(TeamPtr team, int health);
  1166 	
   782 	
  1167 	// model/weapon.h
   783 	// Logging
  1168 	WeaponsetListPtr flib_weaponsetlist_from_ini(String filename);
       
  1169 	int flib_weaponsetlist_to_ini(String filename, WeaponsetListPtr weaponsets);
       
  1170 	void flib_weaponsetlist_destroy(WeaponsetListPtr list);
       
  1171 	
       
  1172 	// util/logging.h
   784 	public static final int FLIB_LOGLEVEL_ALL = -100;
  1173 	public static final int FLIB_LOGLEVEL_ALL = -100;
   785 	public static final int FLIB_LOGLEVEL_DEBUG = -1;
  1174 	public static final int FLIB_LOGLEVEL_DEBUG = -1;
   786 	public static final int FLIB_LOGLEVEL_INFO = 0;
  1175 	public static final int FLIB_LOGLEVEL_INFO = 0;
   787 	public static final int FLIB_LOGLEVEL_WARNING = 1;
  1176 	public static final int FLIB_LOGLEVEL_WARNING = 1;
   788 	public static final int FLIB_LOGLEVEL_ERROR = 2;
  1177 	public static final int FLIB_LOGLEVEL_ERROR = 2;