diff options
Diffstat (limited to 'src/org/happysanta/gd/Levels')
-rw-r--r-- | src/org/happysanta/gd/Levels/InvalidTrackException.java | 12 | ||||
-rwxr-xr-x | src/org/happysanta/gd/Levels/Level.java | 245 | ||||
-rw-r--r-- | src/org/happysanta/gd/Levels/LevelHeader.java | 53 | ||||
-rwxr-xr-x | src/org/happysanta/gd/Levels/Loader.java | 335 | ||||
-rw-r--r-- | src/org/happysanta/gd/Levels/Reader.java | 52 |
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; + } + +} |