DEADSOFTWARE

Implement DI for menu and refactor #13
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / GameSaver.java
1 package ru.deadsoftware.cavedroid.game;
3 import com.badlogic.gdx.Gdx;
4 import com.badlogic.gdx.files.FileHandle;
5 import ru.deadsoftware.cavedroid.MainConfig;
6 import ru.deadsoftware.cavedroid.game.mobs.MobsController;
7 import ru.deadsoftware.cavedroid.game.objects.DropController;
9 import javax.annotation.CheckForNull;
10 import java.io.*;
11 import java.nio.ByteBuffer;
13 public class GameSaver {
15 public static class Data {
16 @CheckForNull
17 private MobsController mMobsController;
18 @CheckForNull
19 private DropController mDropController;
20 @CheckForNull
21 private int[][] mForeMap, mBackMap;
23 public Data(MobsController mobsController, DropController dropController, int[][] foreMap, int[][] backMap) {
24 mMobsController = mobsController;
25 mDropController = dropController;
26 mForeMap = foreMap;
27 mBackMap = backMap;
28 }
30 public MobsController retrieveMobsController() {
31 assert mMobsController != null;
32 MobsController mobsController = mMobsController;
33 mMobsController = null;
34 return mobsController;
35 }
37 public DropController retrieveDropController() {
38 assert mDropController != null;
39 DropController dropController = mDropController;
40 mDropController = null;
41 return dropController;
42 }
44 public int[][] retrieveForeMap() {
45 assert mForeMap != null;
46 int[][] foreMap = mForeMap;
47 mForeMap = null;
48 return foreMap;
49 }
51 public int[][] retrieveBackMap() {
52 assert mBackMap != null;
53 int[][] backMap = mBackMap;
54 mBackMap = null;
55 return backMap;
56 }
58 public boolean isEmpty() {
59 return mMobsController == null && mDropController == null && mForeMap == null && mBackMap == null;
60 }
61 }
63 private static final int SAVE_VERSION = 1;
65 private static byte[] intToBytes(int i) {
66 return ByteBuffer.allocate(4).putInt(i).array();
67 }
69 private static void saveMap(FileHandle file, int[][] map) throws IOException {
70 int run, block;
71 int width = map.length;
72 int height = map[0].length;
74 BufferedOutputStream out = new BufferedOutputStream(file.write(false));
76 out.write(intToBytes(SAVE_VERSION));
77 out.write(intToBytes(width));
78 out.write(intToBytes(height));
80 for (int y = 0; y < height; y++) {
81 block = map[0][y];
82 run = 0;
83 for (int[] ints : map) {
84 if (ints[y] != block) {
85 out.write(intToBytes(run));
86 out.write(intToBytes(block));
87 run = 0;
88 block = ints[y];
89 }
90 run++;
91 }
92 out.write(intToBytes(run));
93 out.write(intToBytes(block));
94 }
96 out.flush();
97 out.close();
98 }
100 private static int[][] loadMap(FileHandle file) throws Exception {
101 int[][] map;
102 int version, width, height;
103 int run, block;
105 DataInputStream in = new DataInputStream(file.read());
107 version = in.readInt();
109 if (SAVE_VERSION == version) {
110 width = in.readInt();
111 height = in.readInt();
112 map = new int[width][height];
113 for (int y = 0; y < height; y++) {
114 for (int x = 0; x < width; x += run) {
115 run = in.readInt();
116 block = in.readInt();
117 for (int i = x; i < x + run; i++) {
118 map[i][y] = block;
122 } else {
123 throw new Exception("version mismatch");
126 in.close();
127 return map;
130 @CheckForNull
131 public static Data load(MainConfig mainConfig) {
132 String folder = mainConfig.getGameFolder();
133 FileHandle file = Gdx.files.absolute(folder + "/saves/game.sav");
135 try {
136 ObjectInputStream in = new ObjectInputStream(file.read());
137 int version = in.readInt();
138 DropController dropController;
139 MobsController mobsController;
141 if (SAVE_VERSION == version) {
142 dropController = (DropController) in.readObject();
143 mobsController = (MobsController) in.readObject();
144 } else {
145 throw new Exception("version mismatch");
148 in.close();
150 int[][] foreMap = loadMap(Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/foremap.sav"));
151 int[][] backMap = loadMap(Gdx.files.absolute(mainConfig.getGameFolder() + "/saves/backmap.sav"));
153 if (dropController == null || mobsController == null) {
154 throw new Exception("couldn't load");
157 return new Data(mobsController, dropController, foreMap, backMap);
158 } catch (Exception e) {
159 Gdx.app.error("GameSaver", e.getMessage());
162 return null;
165 public static void save(MainConfig mainConfig,
166 DropController dropController,
167 MobsController mobsController,
168 GameWorld gameWorld) {
170 String folder = mainConfig.getGameFolder();
171 FileHandle file = Gdx.files.absolute(folder + "/saves/");
172 file.mkdirs();
173 file = Gdx.files.absolute(folder + "/saves/game.sav");
175 try {
176 ObjectOutputStream out = new ObjectOutputStream(file.write(false));
177 out.writeInt(SAVE_VERSION);
178 out.writeObject(dropController);
179 out.writeObject(mobsController);
180 out.close();
181 saveMap(Gdx.files.absolute(folder + "/saves/foremap.sav"), gameWorld.getFullForeMap());
182 saveMap(Gdx.files.absolute(folder + "/saves/backmap.sav"), gameWorld.getFullBackMap());
183 } catch (Exception e) {
184 e.printStackTrace();
188 public static boolean exists(MainConfig mainConfig) {
189 String folder = mainConfig.getGameFolder();
190 return (Gdx.files.absolute(folder + "/saves/game.sav").exists() &&
191 Gdx.files.absolute(folder + "/saves/foremap.sav").exists() &&
192 Gdx.files.absolute(folder + "/saves/backmap.sav").exists());