summaryrefslogtreecommitdiff
path: root/src/org/happysanta/gd/Levels
diff options
context:
space:
mode:
authorevgenyzinoviev <me@ch1p.com>2015-08-14 17:11:48 +0300
committerevgenyzinoviev <me@ch1p.com>2015-08-14 17:11:48 +0300
commitae0e6ec634d8ab515ae381145a89d9ce649ba082 (patch)
tree081af7274605451b6e48d20961dbcf47bdf43b93 /src/org/happysanta/gd/Levels
initial
Diffstat (limited to 'src/org/happysanta/gd/Levels')
-rw-r--r--src/org/happysanta/gd/Levels/InvalidTrackException.java12
-rwxr-xr-xsrc/org/happysanta/gd/Levels/Level.java245
-rw-r--r--src/org/happysanta/gd/Levels/LevelHeader.java53
-rwxr-xr-xsrc/org/happysanta/gd/Levels/Loader.java335
-rw-r--r--src/org/happysanta/gd/Levels/Reader.java52
5 files changed, 697 insertions, 0 deletions
diff --git a/src/org/happysanta/gd/Levels/InvalidTrackException.java b/src/org/happysanta/gd/Levels/InvalidTrackException.java
new file mode 100644
index 0000000..9b2b827
--- /dev/null
+++ b/src/org/happysanta/gd/Levels/InvalidTrackException.java
@@ -0,0 +1,12 @@
+package org.happysanta.gd.Levels;
+
+/**
+ * Created by evgeny on 6/15/14.
+ */
+public class InvalidTrackException extends Exception {
+
+ public InvalidTrackException(Exception e) {
+ super(e);
+ }
+
+}
diff --git a/src/org/happysanta/gd/Levels/Level.java b/src/org/happysanta/gd/Levels/Level.java
new file mode 100755
index 0000000..78f89ac
--- /dev/null
+++ b/src/org/happysanta/gd/Levels/Level.java
@@ -0,0 +1,245 @@
+package org.happysanta.gd.Levels;
+
+import org.happysanta.gd.Game.GameView;
+import org.happysanta.gd.Game.Physics;
+
+import java.io.DataInputStream;
+
+import static org.happysanta.gd.Helpers.getLevelLoader;
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class Level {
+
+ public int startX;
+ public int startY;
+ public int finishX;
+ public int m_gotoI;
+ public int m_forI;
+ public int finishY;
+ public int pointsCount;
+ public int m_intI;
+ public int points[][];
+ public String levelName;
+ private int m_aI;
+ private int m_dI;
+ private int m_eI;
+ private int m_bI;
+ private int m_gI;
+ private int m_rI;
+
+ public Level() {
+ m_aI = 0;
+ m_dI = 0;
+ m_eI = 0;
+ m_bI = 0;
+ m_gI = 0;
+ m_gotoI = 0;
+ m_forI = 0;
+ points = (int[][]) null;
+ levelName = "levelname";
+ m_rI = 0;
+ clear();
+ }
+
+ public void clear() {
+ startX = 0;
+ startY = 0;
+ finishX = 0xc80000;
+ pointsCount = 0;
+ m_intI = 0;
+ }
+
+ public int _doII(int j) {
+ int k = j - points[m_gotoI][0];
+ int i1;
+ if (((i1 = points[m_forI][0] - points[m_gotoI][0]) >= 0 ? i1 : -i1) < 3 || k > i1)
+ return 0x10000;
+ else
+ return (int) (((long) k << 32) / (long) i1 >> 16);
+ }
+
+ public void _ifIIV(int j, int k) {
+ m_aI = (j << 16) >> 3;
+ m_dI = (k << 16) >> 3;
+ }
+
+ public void _aIIV(int j, int k) {
+ m_eI = j >> 1;
+ m_bI = k >> 1;
+ }
+
+ public void _aIIV(int j, int k, int i1) {
+ m_eI = j;
+ m_bI = k;
+ m_gI = i1;
+ }
+
+ public void _ifiIV(GameView view, int k, int i1) {
+ if (i1 <= pointsCount - 1) {
+ int j1 = m_gI - (points[k][1] + points[i1 + 1][1] >> 1) >= 0 ? m_gI - (points[k][1] + points[i1 + 1][1] >> 1) : 0;
+ if (m_gI <= points[k][1] || m_gI <= points[i1 + 1][1])
+ j1 = j1 >= 0x50000 ? 0x50000 : j1;
+ m_rI = (int) ((long) m_rI * 49152L >> 16) + (int) ((long) j1 * 16384L >> 16);
+ if (m_rI <= 0x88000) {
+ int k1 = (int) (0x190000L * (long) m_rI >> 16) >> 16;
+ view.setColor(k1, k1, k1);
+ int l1 = points[k][0] - points[k + 1][0];
+ int i2 = (int) (((long) (points[k][1] - points[k + 1][1]) << 32) / (long) l1 >> 16);
+ int j2 = points[k][1] - (int) ((long) points[k][0] * (long) i2 >> 16);
+ int k2 = (int) ((long) m_eI * (long) i2 >> 16) + j2;
+ l1 = points[i1][0] - points[i1 + 1][0];
+ i2 = (int) (((long) (points[i1][1] - points[i1 + 1][1]) << 32) / (long) l1 >> 16);
+ j2 = points[i1][1] - (int) ((long) points[i1][0] * (long) i2 >> 16);
+ int l2 = (int) ((long) m_bI * (long) i2 >> 16) + j2;
+ if (k == i1) {
+ view._aIIIV((m_eI << 3) >> 16, (k2 + 0x10000 << 3) >> 16, (m_bI << 3) >> 16, (l2 + 0x10000 << 3) >> 16);
+ return;
+ }
+ view._aIIIV((m_eI << 3) >> 16, (k2 + 0x10000 << 3) >> 16, (points[k + 1][0] << 3) >> 16, (points[k + 1][1] + 0x10000 << 3) >> 16);
+ for (int i3 = k + 1; i3 < i1; i3++)
+ view._aIIIV((points[i3][0] << 3) >> 16, (points[i3][1] + 0x10000 << 3) >> 16, (points[i3 + 1][0] << 3) >> 16, (points[i3 + 1][1] + 0x10000 << 3) >> 16);
+
+ view._aIIIV((points[i1][0] << 3) >> 16, (points[i1][1] + 0x10000 << 3) >> 16, (m_bI << 3) >> 16, (l2 + 0x10000 << 3) >> 16);
+ }
+ }
+ }
+
+ public synchronized void _aiIV(GameView view, int k, int i1) {
+ int k2 = 0;
+ int l2 = 0;
+ int j2;
+ for (j2 = 0; j2 < pointsCount - 1 && points[j2][0] <= m_aI; j2++) ;
+ if (j2 > 0)
+ j2--;
+ int i3 = k - points[j2][0];
+ int j3 = (i1 + 0x320000) - points[j2][1];
+ int k3 = Physics._doIII(i3, j3);
+ i3 = (int) (((long) i3 << 32) / (long) (k3 >> 1 >> 1) >> 16);
+ j3 = (int) (((long) j3 << 32) / (long) (k3 >> 1 >> 1) >> 16);
+ view.setColor(0, 170, 0);
+ do {
+ if (j2 >= pointsCount - 1)
+ break;
+ int j1 = i3;
+ int l1 = j3;
+ i3 = k - points[j2 + 1][0];
+ j3 = (i1 + 0x320000) - points[j2 + 1][1];
+ int l3 = Physics._doIII(i3, j3);
+ i3 = (int) (((long) i3 << 32) / (long) (l3 >> 1 >> 1) >> 16);
+ j3 = (int) (((long) j3 << 32) / (long) (l3 >> 1 >> 1) >> 16);
+ view._aIIIV((points[j2][0] + j1 << 3) >> 16, (points[j2][1] + l1 << 3) >> 16, (points[j2 + 1][0] + i3 << 3) >> 16, (points[j2 + 1][1] + j3 << 3) >> 16);
+ view._aIIIV((points[j2][0] << 3) >> 16, (points[j2][1] << 3) >> 16, (points[j2][0] + j1 << 3) >> 16, (points[j2][1] + l1 << 3) >> 16);
+ if (j2 > 1) {
+ if (points[j2][0] > m_eI && k2 == 0)
+ k2 = j2 - 1;
+ if (points[j2][0] > m_bI && l2 == 0)
+ l2 = j2 - 1;
+ }
+ if (m_gotoI == j2) {
+ view.drawStartFlag((points[m_gotoI][0] + j1 << 3) >> 16, (points[m_gotoI][1] + l1 << 3) >> 16);
+ view.setColor(0, 170, 0);
+ }
+ if (m_forI == j2) {
+ view.drawFinishFlag((points[m_forI][0] + j1 << 3) >> 16, (points[m_forI][1] + l1 << 3) >> 16);
+ view.setColor(0, 170, 0);
+ }
+ if (points[j2][0] > m_dI)
+ break;
+ j2++;
+ } while (true);
+ int k1 = i3;
+ int i2 = j3;
+ view._aIIIV((points[pointsCount - 1][0] << 3) >> 16, (points[pointsCount - 1][1] << 3) >> 16, (points[pointsCount - 1][0] + k1 << 3) >> 16, (points[pointsCount - 1][1] + i2 << 3) >> 16);
+ if (getLevelLoader().isShadowsEnabled())
+ _ifiIV(view, k2, l2);
+ }
+
+ public synchronized void _aiV(GameView view) {
+ int k;
+ for (k = 0; k < pointsCount - 1 && points[k][0] <= m_aI; k++) ;
+ if (k > 0)
+ k--;
+ do {
+ if (k >= pointsCount - 1)
+ break;
+ view._aIIIV((points[k][0] << 3) >> 16, (points[k][1] << 3) >> 16, (points[k + 1][0] << 3) >> 16, (points[k + 1][1] << 3) >> 16);
+ if (m_gotoI == k) {
+ view.drawStartFlag((points[m_gotoI][0] << 3) >> 16, (points[m_gotoI][1] << 3) >> 16);
+ view.setColor(0, 255, 0);
+ }
+ if (m_forI == k) {
+ view.drawFinishFlag((points[m_forI][0] << 3) >> 16, (points[m_forI][1] << 3) >> 16);
+ view.setColor(0, 255, 0);
+ }
+ if (points[k][0] > m_dI)
+ break;
+ k++;
+ } while (true);
+ }
+
+ public void unpackInt(int x, int y) {
+ addPoint((x << 16) >> 3, (y << 16) >> 3);
+ }
+
+ public void addPoint(int x, int y) {
+ if (points == null || points.length <= pointsCount) {
+ int i1 = 100;
+ if (points != null)
+ i1 = i1 >= points.length + 30 ? i1 : points.length + 30;
+ int ai[][] = new int[i1][2];
+ if (points != null)
+ System.arraycopy(points, 0, ai, 0, points.length);
+ points = ai;
+ }
+ if (pointsCount == 0 || points[pointsCount - 1][0] < x) {
+ points[pointsCount][0] = x;
+ points[pointsCount][1] = y;
+ pointsCount++;
+ }
+ }
+
+ public synchronized void readTrackData(DataInputStream in) {
+ try {
+ clear();
+ if (in.readByte() == 50) {
+ byte bytes[] = new byte[20];
+ in.readFully(bytes);
+ }
+ m_forI = 0;
+ m_gotoI = 0;
+ startX = in.readInt();
+ startY = in.readInt();
+ finishX = in.readInt();
+ finishY = in.readInt();
+ short pointsCount = in.readShort();
+ int firstPointX = in.readInt();
+ int firstPointY = in.readInt();
+ int k1 = firstPointX;
+ int l1 = firstPointY;
+ unpackInt(k1, l1);
+ for (int i = 1; i < pointsCount; i++) {
+ int x;
+ int y;
+ byte byte0;
+ if ((byte0 = in.readByte()) == -1) {
+ k1 = l1 = 0;
+ x = in.readInt();
+ y = in.readInt();
+ } else {
+ x = byte0;
+ y = in.readByte();
+ }
+ k1 += x;
+ l1 += y;
+ unpackInt(k1, l1);
+ }
+
+ /*logDebug("Points: ");
+ for (int[] point: points) {
+ logDebug("(" + ((point[0] >> 16) << 3) + ", " + ((point[1] >> 16) << 3) + ")");
+ }*/
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+}
diff --git a/src/org/happysanta/gd/Levels/LevelHeader.java b/src/org/happysanta/gd/Levels/LevelHeader.java
new file mode 100644
index 0000000..68aa112
--- /dev/null
+++ b/src/org/happysanta/gd/Levels/LevelHeader.java
@@ -0,0 +1,53 @@
+package org.happysanta.gd.Levels;
+
+public class LevelHeader {
+
+ private int pointers[][] = new int[3][];
+ private String names[][] = new String[3][];
+ private int counts[] = new int[3];
+
+ public LevelHeader() {
+ }
+
+ public void setCount(int level, int count) {
+ if (level >= counts.length)
+ return;
+
+ pointers[level] = new int[count];
+ names[level] = new String[count];
+ counts[level] = count;
+ }
+
+ public int getCount(int level) {
+ if (level < counts.length)
+ return counts[level];
+ else
+ return 0;
+ }
+
+ public void setPointer(int level, int index, int value) {
+ pointers[level][index] = value;
+ }
+
+ public void setName(int level, int index, String value) {
+ names[level][index] = value;
+ }
+
+ public int[][] getPointers() {
+ return pointers;
+ }
+
+ public String[][] getNames() {
+ return names;
+ }
+
+ public boolean isCountsOk() {
+ for (int i = 0; i < counts.length; i++) {
+ if (counts[i] <= 0)
+ return false;
+ }
+
+ return true;
+ }
+
+}
diff --git a/src/org/happysanta/gd/Levels/Loader.java b/src/org/happysanta/gd/Levels/Loader.java
new file mode 100755
index 0000000..48ef645
--- /dev/null
+++ b/src/org/happysanta/gd/Levels/Loader.java
@@ -0,0 +1,335 @@
+package org.happysanta.gd.Levels;
+
+import org.happysanta.gd.GDActivity;
+import org.happysanta.gd.Game.GameView;
+import org.happysanta.gd.Menu.SimpleMenuElement;
+import org.happysanta.gd.Game.Physics;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class Loader {
+
+ //public static final int m_bI;
+ // public static final int m_forI = 1;
+ // public static final int m_intI = 2;
+ //public static final int m_doI;
+ // public static final int m_ifI = 1;
+
+ public File levelsFile;
+ public Level levels;
+ public int m_nullI;
+ public int m_fI;
+ public String names[][];
+ public int m_jI;
+ public int m_iI;
+ public int m_longI;
+ public int m_eI;
+ public int m_dI;
+
+ private boolean perspectiveEnabled = true;
+ private boolean shadowsEnabled = true;
+ private int pointers[][] = new int[3][];
+ private int m_eaI = 0;
+ private int m_faI = 0;
+ private int m_aI = 0;
+ private int m_kI = 0;
+ private int m_saaI[][];
+ private int m_haI[];
+ private int m_vaI[];
+ private int m_daI;
+
+ public Loader() throws IOException {
+ reset();
+ }
+
+ public Loader(File levelsFile) throws IOException {
+ if (levelsFile != null)
+ this.levelsFile = levelsFile;
+ reset();
+ }
+
+ private void reset() throws IOException {
+ m_saaI = null;
+ levels = null;
+ m_haI = new int[3];
+ m_vaI = new int[3];
+ m_nullI = 0;
+ m_fI = -1;
+ names = new String[3][];
+ m_daI = 0;
+ for (int j = 0; j < 3; j++) {
+ m_haI[j] = (int) ((long) (Physics.m_foraI[j] + 19660 >> 1) * (long) (Physics.m_foraI[j] + 19660 >> 1) >> 16);
+ m_vaI[j] = (int) ((long) (Physics.m_foraI[j] - 19660 >> 1) * (long) (Physics.m_foraI[j] - 19660 >> 1) >> 16);
+ }
+
+ // try {
+ readLevels();
+ // } catch ( _ex) {
+ // _ex.printStackTrace();
+ //}
+ _ifvV();
+ }
+
+
+ public void setLevelsFile(File file) throws IOException {
+ levelsFile = file;
+ reset();
+ }
+
+ public InputStream getLevelsInputStream(String s) throws IOException {
+ if (levelsFile == null)
+ return GDActivity.shared.getAssets().open(s);
+ else
+ return new FileInputStream(levelsFile);
+ }
+
+ private void readLevels() throws IOException {
+ //try {
+ InputStream in = getLevelsInputStream("levels.mrg");
+ LevelHeader header = Reader.readHeader(in);
+
+ pointers = header.getPointers();
+ names = header.getNames();
+ //} catch (Exception ex) {
+ // logDebug("Levels.Loader: error while reading mrg file");
+ // ex.printStackTrace();
+ //}
+ }
+
+ public String getLevelName(int j, int k) {
+ if (j < names.length && k < names[j].length)
+ return names[j][k];
+ else
+ return "---";
+ }
+
+ public void _ifvV() {
+ try {
+ _doIII(m_nullI, m_fI + 1);
+ } catch (InvalidTrackException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public int _doIII(int j, int k) throws InvalidTrackException {
+ m_nullI = j;
+ m_fI = k;
+ if (m_fI >= names[m_nullI].length)
+ m_fI = 0;
+ _hIIV(m_nullI + 1, m_fI + 1);
+ return m_fI;
+ }
+
+ private void _hIIV(int j, int k) throws InvalidTrackException {
+ try {
+ InputStream is = getLevelsInputStream("levels.mrg");
+ DataInputStream dis = new DataInputStream(is);
+ for (int i1 = pointers[j - 1][k - 1]; i1 > 0; i1 -= dis.skipBytes(i1)) ;
+ if (levels == null)
+ levels = new Level();
+ levels.readTrackData(dis);
+ dis.close();
+ load(levels);
+ } catch (IOException _ex) {
+ _ex.printStackTrace();
+ }
+ }
+
+ public void _ifIV(int j) {
+ m_jI = levels.startX << 1;
+ m_iI = levels.startY << 1;
+ }
+
+ public int _dovI() {
+ return levels.points[levels.m_forI][0] << 1;
+ }
+
+ public int _intvI() {
+ return levels.points[levels.m_gotoI][0] << 1;
+ }
+
+ public int _newvI() {
+ return levels.startX << 1;
+ }
+
+ public int _avI() {
+ return levels.startY << 1;
+ }
+
+ public int _aII(int j) {
+ return levels._doII(j >> 1);
+ }
+
+ public void load(Level l1) throws InvalidTrackException {
+ try {
+ m_longI = 0x80000000;
+ levels = l1;
+ int j = levels.pointsCount;
+ if (m_saaI == null || m_daI < j) {
+ m_saaI = (int[][]) null;
+ // System.gc();
+ m_daI = j >= 100 ? j : 100;
+ m_saaI = new int[m_daI][2];
+ }
+ m_eaI = 0;
+ m_faI = 0;
+ m_aI = l1.points[m_eaI][0];
+ m_kI = l1.points[m_faI][0];
+ for (int k = 0; k < j; k++) {
+ int i1 = l1.points[(k + 1) % j][0] - l1.points[k][0];
+ int j1 = l1.points[(k + 1) % j][1] - l1.points[k][1];
+ if (k != 0 && k != j - 1)
+ m_longI = m_longI >= l1.points[k][0] ? m_longI : l1.points[k][0];
+ int k1 = -j1;
+ int i2 = i1;
+ int j2 = Physics._doIII(k1, i2);
+ m_saaI[k][0] = (int) (((long) k1 << 32) / (long) j2 >> 16);
+ m_saaI[k][1] = (int) (((long) i2 << 32) / (long) j2 >> 16);
+ if (levels.m_gotoI == 0 && l1.points[k][0] > levels.startX)
+ levels.m_gotoI = k + 1;
+ if (levels.m_forI == 0 && l1.points[k][0] > levels.finishX)
+ levels.m_forI = k;
+ }
+
+ m_eaI = 0;
+ m_faI = 0;
+ m_aI = 0;
+ m_kI = 0;
+ } catch (ArithmeticException e) {
+ throw new InvalidTrackException(e);
+ }
+ }
+
+ public void _ifIIV(int j, int k) {
+ levels._ifIIV(j, k);
+ }
+
+ public void _aiIV(GameView j, int k, int i1) {
+ if (j != null) {
+ j.setColor(0, 170, 0);
+ k >>= 1;
+ i1 >>= 1;
+ levels._aiIV(j, k, i1);
+ }
+ }
+
+ public void _aiV(GameView j) {
+ j.setColor(0, 255, 0);
+ levels._aiV(j);
+ }
+
+ public void _aIIV(int j, int k, int i1) {
+ levels._aIIV(j + 0x18000 >> 1, k - 0x18000 >> 1, i1 >> 1);
+ k >>= 1;
+ j >>= 1;
+ m_faI = m_faI >= levels.pointsCount - 1 ? levels.pointsCount - 1 : m_faI;
+ m_eaI = m_eaI >= 0 ? m_eaI : 0;
+ if (k > m_kI)
+ while (m_faI < levels.pointsCount - 1 && k > levels.points[++m_faI][0]) ;
+ else if (j < m_aI) {
+ while (m_eaI > 0 && j < levels.points[--m_eaI][0]) ;
+ } else {
+ while (m_eaI < levels.pointsCount && j > levels.points[++m_eaI][0]) ;
+ if (m_eaI > 0)
+ m_eaI--;
+ while (m_faI > 0 && k < levels.points[--m_faI][0]) ;
+ m_faI = m_faI + 1 >= levels.pointsCount - 1 ? levels.pointsCount - 1 : m_faI + 1;
+ }
+ m_aI = levels.points[m_eaI][0];
+ m_kI = levels.points[m_faI][0];
+ }
+
+ public int _anvI(SimpleMenuElement n1, int j) {
+ int k3 = 0;
+ byte byte1 = 2;
+ int l3 = n1.x >> 1;
+ int i4 = n1.y >> 1;
+ if (perspectiveEnabled)
+ i4 -= 0x10000;
+ int j4 = 0;
+ int k4 = 0;
+ for (int l4 = m_eaI; l4 < m_faI; l4++) {
+ int k = levels.points[l4][0];
+ int i1 = levels.points[l4][1];
+ int j1 = levels.points[l4 + 1][0];
+ int k1;
+ int _tmp = (k1 = levels.points[l4 + 1][1]) < i1 ? i1 : k1;
+ if (l3 - m_haI[j] > j1 || l3 + m_haI[j] < k)
+ continue;
+ int l1 = k - j1;
+ int i2 = i1 - k1;
+ int j2 = (int) ((long) l1 * (long) l1 >> 16) + (int) ((long) i2 * (long) i2 >> 16);
+ int k2 = (int) ((long) (l3 - k) * (long) (-l1) >> 16) + (int) ((long) (i4 - i1) * (long) (-i2) >> 16);
+ int l2;
+ if ((j2 >= 0 ? j2 : -j2) >= 3)
+ l2 = (int) (((long) k2 << 32) / (long) j2 >> 16);
+ else
+ l2 = (k2 <= 0 ? -1 : 1) * (j2 <= 0 ? -1 : 1) * 0x7fffffff;
+ if (l2 < 0)
+ l2 = 0;
+ if (l2 > 0x10000)
+ l2 = 0x10000;
+ int i3 = k + (int) ((long) l2 * (long) (-l1) >> 16);
+ int j3 = i1 + (int) ((long) l2 * (long) (-i2) >> 16);
+ l1 = l3 - i3;
+ i2 = i4 - j3;
+ byte byte0;
+ long l5;
+ if ((l5 = ((long) l1 * (long) l1 >> 16) + ((long) i2 * (long) i2 >> 16)) < (long) m_haI[j]) {
+ if (l5 >= (long) m_vaI[j])
+ byte0 = 1;
+ else
+ byte0 = 0;
+ } else {
+ byte0 = 2;
+ }
+ if (byte0 == 0 && (int) ((long) m_saaI[l4][0] * (long) n1.m_eI >> 16) + (int) ((long) m_saaI[l4][1] * (long) n1.m_dI >> 16) < 0) {
+ m_eI = m_saaI[l4][0];
+ m_dI = m_saaI[l4][1];
+ return 0;
+ }
+ if (byte0 != 1 || (int) ((long) m_saaI[l4][0] * (long) n1.m_eI >> 16) + (int) ((long) m_saaI[l4][1] * (long) n1.m_dI >> 16) >= 0)
+ continue;
+ k3++;
+ byte1 = 1;
+ if (k3 == 1) {
+ j4 = m_saaI[l4][0];
+ k4 = m_saaI[l4][1];
+ } else {
+ j4 += m_saaI[l4][0];
+ k4 += m_saaI[l4][1];
+ }
+ }
+
+ if (byte1 == 1) {
+ if ((int) ((long) j4 * (long) n1.m_eI >> 16) + (int) ((long) k4 * (long) n1.m_dI >> 16) >= 0)
+ return 2;
+ m_eI = j4;
+ m_dI = k4;
+ }
+ return byte1;
+ }
+
+ public boolean isShadowsEnabled() {
+ return shadowsEnabled;
+ }
+
+ public boolean isPerspectiveEnabled() {
+ return perspectiveEnabled;
+ }
+
+ public void setPerspectiveEnabled(boolean enabled) {
+ perspectiveEnabled = enabled;
+ }
+
+ public void setShadowsEnabled(boolean enabled) {
+ shadowsEnabled = enabled;
+ }
+
+}
diff --git a/src/org/happysanta/gd/Levels/Reader.java b/src/org/happysanta/gd/Levels/Reader.java
new file mode 100644
index 0000000..f0ce9a6
--- /dev/null
+++ b/src/org/happysanta/gd/Levels/Reader.java
@@ -0,0 +1,52 @@
+package org.happysanta.gd.Levels;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.happysanta.gd.Helpers.decodeCp1251;
+
+public class Reader {
+
+ private static final int MAX_VALID_TRACKS = 16384;
+
+ public static LevelHeader readHeader(InputStream in) throws IOException {
+ LevelHeader header = new LevelHeader();
+ DataInputStream din = new DataInputStream(in);
+ byte buf[] = new byte[40];
+ String tmp;
+ for (int i = 0; i < 3; i++) {
+ int tCount = din.readInt();
+ if (tCount > MAX_VALID_TRACKS) {
+ din.close();
+ throw new IOException("Level file is not valid");
+ }
+ header.setCount(i, tCount);
+
+ label0:
+ for (int j = 0; j < header.getCount(i); j++) {
+ int trackPointer = din.readInt();
+ header.setPointer(i, j, trackPointer);
+ int nameLen = 0;
+ do {
+ if (nameLen >= 40)
+ continue label0;
+
+ buf[nameLen] = din.readByte();
+ if (buf[nameLen] == 0) {
+ // tmp = (new String(buf, 0, nameLen, "CP-1251"));
+ tmp = decodeCp1251(buf);
+ header.setName(i, j, tmp.replace('_', ' '));
+ continue label0;
+ }
+ nameLen++;
+ } while (true);
+ }
+
+ }
+ din.close();
+
+ return header;
+ }
+
+}