aboutsummaryrefslogtreecommitdiff
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
initial
-rwxr-xr-x.classpath9
-rwxr-xr-x.idea/.name1
-rw-r--r--.idea/artifacts/Gravity_Defied_Classic.xml22
-rwxr-xr-x.idea/codeStyleSettings.xml14
-rwxr-xr-x.idea/compiler.xml25
-rwxr-xr-x.idea/copyright/profiles_settings.xml3
-rwxr-xr-x.idea/encodings.xml5
-rw-r--r--.idea/libraries/acra_4_5_0.xml9
-rw-r--r--.idea/libraries/android_support_v4.xml9
-rw-r--r--.idea/libraries/android_support_v4_c1a500050aef26b42ae63e5fd8ee3115.xml9
-rwxr-xr-x.idea/misc.xml120
-rwxr-xr-x.idea/modules.xml9
-rwxr-xr-x.idea/scopes/scope_settings.xml5
-rw-r--r--.idea/src.iml9
-rwxr-xr-x.idea/uiDesigner.xml125
-rwxr-xr-x.idea/vcs.xml7
-rwxr-xr-x.idea/workspace.xml1767
-rwxr-xr-x.project33
-rw-r--r--AGDTR.iml20
-rwxr-xr-xAndroidManifest.xml37
-rw-r--r--README.md27
-rwxr-xr-xassets/RobotoCondensed-Regular.ttfbin0 -> 114568 bytes
-rwxr-xr-xassets/levels.mrgbin0 -> 5123 bytes
-rw-r--r--libs/acra-4.5.0.jarbin0 -> 126013 bytes
-rwxr-xr-xproguard-project.txt20
-rwxr-xr-xproject.properties14
-rwxr-xr-xpsd/drawables/drawable-hdpi/flag_h.psdbin0 -> 104864 bytes
-rwxr-xr-xpsd/drawables/drawable-hdpi/helmet.psdbin0 -> 35458 bytes
-rw-r--r--psd/drawables/drawable-hdpi/ic_downloaded.psdbin0 -> 22126 bytes
-rw-r--r--psd/drawables/drawable-hdpi/ic_menu_down.psdbin0 -> 29276 bytes
-rw-r--r--psd/drawables/drawable-hdpi/ic_menu_up.psdbin0 -> 29262 bytes
-rw-r--r--psd/drawables/drawable-hdpi/ic_sort.psdbin0 -> 30972 bytes
-rw-r--r--psd/drawables/drawable-mdpi/ic_downloaded.psdbin0 -> 25710 bytes
-rw-r--r--psd/drawables/drawable-mdpi/ic_menu_down.psdbin0 -> 33644 bytes
-rw-r--r--psd/drawables/drawable-mdpi/ic_menu_up.psdbin0 -> 33582 bytes
-rw-r--r--psd/drawables/drawable-mdpi/ic_sort.psdbin0 -> 27278 bytes
-rwxr-xr-xpsd/drawables/drawable-mdpi/s_flag_mdpi.psdbin0 -> 23030 bytes
-rwxr-xr-xpsd/drawables/drawable-mdpi/s_lock_mdpi.psdbin0 -> 22398 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/bluearm.psdbin0 -> 26732 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/bluebody.psdbin0 -> 28445 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/blueleg.psdbin0 -> 28304 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/btn_bottom_left.psdbin0 -> 52136 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/btn_bottom_right.psdbin0 -> 52128 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/btn_left_right.psdbin0 -> 52120 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/btn_middle.psdbin0 -> 66556 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/btn_top_bottom_middle.psdbin0 -> 64402 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/btn_top_left.psdbin0 -> 48070 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/btn_top_right.psdbin0 -> 48996 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/engine.psdbin0 -> 1101269 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/engine_hdpi.psdbin0 -> 43578 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/engine_xx.psdbin0 -> 1110318 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/fender.psdbin0 -> 47654 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/fender_hdpi.psdbin0 -> 34322 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/flag.psdbin0 -> 107633 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/helmet1.psdbin0 -> 152793 bytes
-rw-r--r--psd/drawables/drawable-xhdpi/ic_downloaded.psdbin0 -> 26706 bytes
-rw-r--r--psd/drawables/drawable-xhdpi/ic_menu_down.psdbin0 -> 36592 bytes
-rw-r--r--psd/drawables/drawable-xhdpi/ic_menu_up.psdbin0 -> 36608 bytes
-rw-r--r--psd/drawables/drawable-xhdpi/ic_sort.psdbin0 -> 27466 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/lock.psdbin0 -> 33047 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/medal.psdbin0 -> 50962 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/s_arrow_down.psdbin0 -> 23361 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/s_arrow_up.psdbin0 -> 22485 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/s_steering.psdbin0 -> 27194 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/wheel1.psdbin0 -> 48775 bytes
-rwxr-xr-xpsd/drawables/drawable-xhdpi/wheel_1x.psdbin0 -> 24550 bytes
-rwxr-xr-xpsd/drawables/drawable-xxhdpi/flag_xxh.psdbin0 -> 112915 bytes
-rwxr-xr-xpsd/drawables/drawable-xxhdpi/helmet1.psdbin0 -> 38354 bytes
-rw-r--r--psd/drawables/drawable-xxhdpi/ic_downloaded.psdbin0 -> 27764 bytes
-rw-r--r--psd/drawables/drawable-xxhdpi/ic_menu_down.psdbin0 -> 39482 bytes
-rw-r--r--psd/drawables/drawable-xxhdpi/ic_menu_up.psdbin0 -> 39416 bytes
-rw-r--r--psd/drawables/drawable-xxhdpi/ic_sort.psdbin0 -> 32786 bytes
-rwxr-xr-xpsd/drawables/drawable-xxhdpi/medal_xx.psdbin0 -> 46462 bytes
-rw-r--r--psd/icon/icon_512.psdbin0 -> 429262 bytes
-rw-r--r--psd/icon/icon_hdpi.psdbin0 -> 67414 bytes
-rw-r--r--psd/icon/icon_mdpi.psdbin0 -> 56483 bytes
-rw-r--r--psd/icon/icon_xhdpi.psdbin0 -> 78042 bytes
-rw-r--r--psd/icon/icon_xxhdpi.psdbin0 -> 103243 bytes
-rw-r--r--psd/icon/icon_xxxhdpi.psdbin0 -> 131005 bytes
-rwxr-xr-xres/drawable-hdpi/btn_b_down.9.pngbin0 -> 171 bytes
-rwxr-xr-xres/drawable-hdpi/btn_b_up.9.pngbin0 -> 161 bytes
-rwxr-xr-xres/drawable-hdpi/btn_br_down.9.pngbin0 -> 168 bytes
-rwxr-xr-xres/drawable-hdpi/btn_br_up.9.pngbin0 -> 163 bytes
-rwxr-xr-xres/drawable-hdpi/btn_n_down.9.pngbin0 -> 159 bytes
-rwxr-xr-xres/drawable-hdpi/btn_n_up.9.pngbin0 -> 85 bytes
-rwxr-xr-xres/drawable-hdpi/btn_r_down.9.pngbin0 -> 162 bytes
-rwxr-xr-xres/drawable-hdpi/btn_r_up.9.pngbin0 -> 159 bytes
-rwxr-xr-xres/drawable-hdpi/codebrew.pngbin0 -> 7829 bytes
-rwxr-xr-xres/drawable-hdpi/gd.pngbin0 -> 11615 bytes
-rw-r--r--res/drawable-hdpi/ic_downloaded.pngbin0 -> 180 bytes
-rw-r--r--res/drawable-hdpi/ic_downloaded_selected.pngbin0 -> 179 bytes
-rw-r--r--res/drawable-hdpi/ic_installed.pngbin0 -> 449 bytes
-rw-r--r--res/drawable-hdpi/ic_installed_selected.pngbin0 -> 449 bytes
-rwxr-xr-xres/drawable-hdpi/ic_launcher.pngbin0 -> 9397 bytes
-rwxr-xr-xres/drawable-hdpi/ic_menu_down.pngbin0 -> 231 bytes
-rwxr-xr-xres/drawable-hdpi/ic_menu_up.pngbin0 -> 221 bytes
-rw-r--r--res/drawable-hdpi/ic_sort_down.pngbin0 -> 167 bytes
-rw-r--r--res/drawable-hdpi/ic_sort_up.pngbin0 -> 167 bytes
-rw-r--r--res/drawable-hdpi/icon.pngbin0 -> 877 bytes
-rwxr-xr-xres/drawable-hdpi/levels_wheel0.pngbin0 -> 450 bytes
-rwxr-xr-xres/drawable-hdpi/levels_wheel1.pngbin0 -> 498 bytes
-rwxr-xr-xres/drawable-hdpi/levels_wheel2.pngbin0 -> 495 bytes
-rwxr-xr-xres/drawable-hdpi/s_arrow_down.pngbin0 -> 170 bytes
-rwxr-xr-xres/drawable-hdpi/s_arrow_up.pngbin0 -> 174 bytes
-rwxr-xr-xres/drawable-hdpi/s_bluearm.pngbin0 -> 305 bytes
-rwxr-xr-xres/drawable-hdpi/s_bluebody.pngbin0 -> 283 bytes
-rwxr-xr-xres/drawable-hdpi/s_blueleg.pngbin0 -> 246 bytes
-rwxr-xr-xres/drawable-hdpi/s_engine.pngbin0 -> 967 bytes
-rwxr-xr-xres/drawable-hdpi/s_fender.pngbin0 -> 770 bytes
-rwxr-xr-xres/drawable-hdpi/s_flag_finish0.pngbin0 -> 487 bytes
-rwxr-xr-xres/drawable-hdpi/s_flag_finish1.pngbin0 -> 501 bytes
-rwxr-xr-xres/drawable-hdpi/s_flag_finish2.pngbin0 -> 483 bytes
-rwxr-xr-xres/drawable-hdpi/s_flag_start0.pngbin0 -> 425 bytes
-rwxr-xr-xres/drawable-hdpi/s_flag_start1.pngbin0 -> 421 bytes
-rwxr-xr-xres/drawable-hdpi/s_flag_start2.pngbin0 -> 453 bytes
-rwxr-xr-xres/drawable-hdpi/s_helmet.pngbin0 -> 543 bytes
-rwxr-xr-xres/drawable-hdpi/s_lock0.pngbin0 -> 275 bytes
-rwxr-xr-xres/drawable-hdpi/s_lock1.pngbin0 -> 498 bytes
-rwxr-xr-xres/drawable-hdpi/s_lock2.pngbin0 -> 302 bytes
-rwxr-xr-xres/drawable-hdpi/s_medal_bronze.pngbin0 -> 320 bytes
-rwxr-xr-xres/drawable-hdpi/s_medal_gold.pngbin0 -> 325 bytes
-rwxr-xr-xres/drawable-hdpi/s_medal_silver.pngbin0 -> 311 bytes
-rwxr-xr-xres/drawable-hdpi/s_steering.pngbin0 -> 152 bytes
-rwxr-xr-xres/drawable-hdpi/s_wheel1.pngbin0 -> 540 bytes
-rwxr-xr-xres/drawable-hdpi/s_wheel2.pngbin0 -> 547 bytes
-rwxr-xr-xres/drawable-mdpi/btn_b_down.9.pngbin0 -> 93 bytes
-rwxr-xr-xres/drawable-mdpi/btn_b_up.9.pngbin0 -> 91 bytes
-rwxr-xr-xres/drawable-mdpi/btn_br_down.9.pngbin0 -> 94 bytes
-rwxr-xr-xres/drawable-mdpi/btn_br_up.9.pngbin0 -> 90 bytes
-rwxr-xr-xres/drawable-mdpi/btn_n_down.9.pngbin0 -> 86 bytes
-rwxr-xr-xres/drawable-mdpi/btn_n_up.9.pngbin0 -> 85 bytes
-rwxr-xr-xres/drawable-mdpi/btn_r_down.9.pngbin0 -> 90 bytes
-rwxr-xr-xres/drawable-mdpi/btn_r_up.9.pngbin0 -> 88 bytes
-rwxr-xr-xres/drawable-mdpi/codebrew.pngbin0 -> 4775 bytes
-rwxr-xr-xres/drawable-mdpi/gd.pngbin0 -> 6483 bytes
-rw-r--r--res/drawable-mdpi/ic_downloaded.pngbin0 -> 166 bytes
-rw-r--r--res/drawable-mdpi/ic_downloaded_selected.pngbin0 -> 166 bytes
-rw-r--r--res/drawable-mdpi/ic_installed.pngbin0 -> 314 bytes
-rw-r--r--res/drawable-mdpi/ic_installed_selected.pngbin0 -> 309 bytes
-rwxr-xr-xres/drawable-mdpi/ic_launcher.pngbin0 -> 5237 bytes
-rwxr-xr-xres/drawable-mdpi/ic_menu_down.pngbin0 -> 187 bytes
-rwxr-xr-xres/drawable-mdpi/ic_menu_up.pngbin0 -> 187 bytes
-rw-r--r--res/drawable-mdpi/ic_sort_down.pngbin0 -> 158 bytes
-rw-r--r--res/drawable-mdpi/ic_sort_up.pngbin0 -> 158 bytes
-rw-r--r--res/drawable-mdpi/icon.pngbin0 -> 669 bytes
-rwxr-xr-xres/drawable-mdpi/levels_wheel0.pngbin0 -> 304 bytes
-rwxr-xr-xres/drawable-mdpi/levels_wheel1.pngbin0 -> 331 bytes
-rwxr-xr-xres/drawable-mdpi/levels_wheel2.pngbin0 -> 337 bytes
-rwxr-xr-xres/drawable-mdpi/s_arrow_down.pngbin0 -> 153 bytes
-rwxr-xr-xres/drawable-mdpi/s_arrow_up.pngbin0 -> 151 bytes
-rwxr-xr-xres/drawable-mdpi/s_bluearm.pngbin0 -> 185 bytes
-rwxr-xr-xres/drawable-mdpi/s_bluebody.pngbin0 -> 248 bytes
-rwxr-xr-xres/drawable-mdpi/s_blueleg.pngbin0 -> 198 bytes
-rwxr-xr-xres/drawable-mdpi/s_engine.pngbin0 -> 458 bytes
-rwxr-xr-xres/drawable-mdpi/s_fender.pngbin0 -> 308 bytes
-rwxr-xr-xres/drawable-mdpi/s_flag_finish0.pngbin0 -> 254 bytes
-rwxr-xr-xres/drawable-mdpi/s_flag_finish1.pngbin0 -> 284 bytes
-rwxr-xr-xres/drawable-mdpi/s_flag_finish2.pngbin0 -> 261 bytes
-rwxr-xr-xres/drawable-mdpi/s_flag_start0.pngbin0 -> 301 bytes
-rwxr-xr-xres/drawable-mdpi/s_flag_start1.pngbin0 -> 282 bytes
-rwxr-xr-xres/drawable-mdpi/s_flag_start2.pngbin0 -> 289 bytes
-rwxr-xr-xres/drawable-mdpi/s_helmet.pngbin0 -> 230 bytes
-rwxr-xr-xres/drawable-mdpi/s_lock0.pngbin0 -> 236 bytes
-rwxr-xr-xres/drawable-mdpi/s_lock1.pngbin0 -> 282 bytes
-rwxr-xr-xres/drawable-mdpi/s_lock2.pngbin0 -> 261 bytes
-rwxr-xr-xres/drawable-mdpi/s_medal_bronze.pngbin0 -> 238 bytes
-rwxr-xr-xres/drawable-mdpi/s_medal_gold.pngbin0 -> 250 bytes
-rwxr-xr-xres/drawable-mdpi/s_medal_silver.pngbin0 -> 254 bytes
-rwxr-xr-xres/drawable-mdpi/s_wheel1.pngbin0 -> 392 bytes
-rwxr-xr-xres/drawable-mdpi/s_wheel2.pngbin0 -> 383 bytes
-rwxr-xr-xres/drawable-xhdpi/btn_b_down.9.pngbin0 -> 169 bytes
-rwxr-xr-xres/drawable-xhdpi/btn_b_up.9.pngbin0 -> 169 bytes
-rwxr-xr-xres/drawable-xhdpi/btn_br_down.9.pngbin0 -> 172 bytes
-rwxr-xr-xres/drawable-xhdpi/btn_br_up.9.pngbin0 -> 174 bytes
-rwxr-xr-xres/drawable-xhdpi/btn_n_down.9.pngbin0 -> 157 bytes
-rwxr-xr-xres/drawable-xhdpi/btn_n_up.9.pngbin0 -> 169 bytes
-rwxr-xr-xres/drawable-xhdpi/btn_r_down.9.pngbin0 -> 166 bytes
-rwxr-xr-xres/drawable-xhdpi/btn_r_up.9.pngbin0 -> 173 bytes
-rwxr-xr-xres/drawable-xhdpi/codebrew.pngbin0 -> 11774 bytes
-rwxr-xr-xres/drawable-xhdpi/flag.pngbin0 -> 590 bytes
-rwxr-xr-xres/drawable-xhdpi/gd.pngbin0 -> 18596 bytes
-rw-r--r--res/drawable-xhdpi/ic_downloaded.pngbin0 -> 192 bytes
-rw-r--r--res/drawable-xhdpi/ic_downloaded_selected.pngbin0 -> 188 bytes
-rw-r--r--res/drawable-xhdpi/ic_installed.pngbin0 -> 563 bytes
-rw-r--r--res/drawable-xhdpi/ic_installed_selected.pngbin0 -> 560 bytes
-rwxr-xr-xres/drawable-xhdpi/ic_launcher.pngbin0 -> 14383 bytes
-rwxr-xr-xres/drawable-xhdpi/ic_menu_down.pngbin0 -> 247 bytes
-rwxr-xr-xres/drawable-xhdpi/ic_menu_up.pngbin0 -> 255 bytes
-rw-r--r--res/drawable-xhdpi/ic_sort_down.pngbin0 -> 179 bytes
-rw-r--r--res/drawable-xhdpi/ic_sort_up.pngbin0 -> 179 bytes
-rw-r--r--res/drawable-xhdpi/icon_xhdpi.pngbin0 -> 1055 bytes
-rwxr-xr-xres/drawable-xhdpi/levels_wheel0.pngbin0 -> 589 bytes
-rwxr-xr-xres/drawable-xhdpi/levels_wheel1.pngbin0 -> 608 bytes
-rwxr-xr-xres/drawable-xhdpi/levels_wheel2.pngbin0 -> 692 bytes
-rwxr-xr-xres/drawable-xhdpi/s_arrow_down.pngbin0 -> 199 bytes
-rwxr-xr-xres/drawable-xhdpi/s_arrow_up.pngbin0 -> 196 bytes
-rwxr-xr-xres/drawable-xhdpi/s_bluearm.pngbin0 -> 346 bytes
-rwxr-xr-xres/drawable-xhdpi/s_bluebody.pngbin0 -> 330 bytes
-rwxr-xr-xres/drawable-xhdpi/s_blueleg.pngbin0 -> 276 bytes
-rwxr-xr-xres/drawable-xhdpi/s_engine.pngbin0 -> 1366 bytes
-rwxr-xr-xres/drawable-xhdpi/s_fender.pngbin0 -> 1071 bytes
-rwxr-xr-xres/drawable-xhdpi/s_flag_finish0.pngbin0 -> 593 bytes
-rwxr-xr-xres/drawable-xhdpi/s_flag_finish1.pngbin0 -> 571 bytes
-rwxr-xr-xres/drawable-xhdpi/s_flag_finish2.pngbin0 -> 576 bytes
-rwxr-xr-xres/drawable-xhdpi/s_flag_start0.pngbin0 -> 533 bytes
-rwxr-xr-xres/drawable-xhdpi/s_flag_start1.pngbin0 -> 526 bytes
-rwxr-xr-xres/drawable-xhdpi/s_flag_start2.pngbin0 -> 574 bytes
-rwxr-xr-xres/drawable-xhdpi/s_helmet.pngbin0 -> 793 bytes
-rwxr-xr-xres/drawable-xhdpi/s_lock0.pngbin0 -> 315 bytes
-rwxr-xr-xres/drawable-xhdpi/s_lock1.pngbin0 -> 737 bytes
-rwxr-xr-xres/drawable-xhdpi/s_lock2.pngbin0 -> 369 bytes
-rwxr-xr-xres/drawable-xhdpi/s_medal_bronze.pngbin0 -> 481 bytes
-rwxr-xr-xres/drawable-xhdpi/s_medal_gold.pngbin0 -> 487 bytes
-rwxr-xr-xres/drawable-xhdpi/s_medal_silver.pngbin0 -> 417 bytes
-rwxr-xr-xres/drawable-xhdpi/s_steering.pngbin0 -> 134 bytes
-rwxr-xr-xres/drawable-xhdpi/s_wheel1.pngbin0 -> 697 bytes
-rwxr-xr-xres/drawable-xhdpi/s_wheel2.pngbin0 -> 606 bytes
-rwxr-xr-xres/drawable-xxhdpi/btn_b_down.9.pngbin0 -> 171 bytes
-rwxr-xr-xres/drawable-xxhdpi/btn_b_up.9.pngbin0 -> 165 bytes
-rwxr-xr-xres/drawable-xxhdpi/btn_br_down.9.pngbin0 -> 171 bytes
-rwxr-xr-xres/drawable-xxhdpi/btn_br_up.9.pngbin0 -> 170 bytes
-rwxr-xr-xres/drawable-xxhdpi/btn_n_down.9.pngbin0 -> 158 bytes
-rwxr-xr-xres/drawable-xxhdpi/btn_n_up.9.pngbin0 -> 154 bytes
-rwxr-xr-xres/drawable-xxhdpi/btn_r_down.9.pngbin0 -> 165 bytes
-rwxr-xr-xres/drawable-xxhdpi/btn_r_up.9.pngbin0 -> 163 bytes
-rw-r--r--res/drawable-xxhdpi/ic_downloaded.pngbin0 -> 223 bytes
-rw-r--r--res/drawable-xxhdpi/ic_downloaded_selected.pngbin0 -> 217 bytes
-rw-r--r--res/drawable-xxhdpi/ic_installed.pngbin0 -> 808 bytes
-rw-r--r--res/drawable-xxhdpi/ic_installed_selected.pngbin0 -> 807 bytes
-rwxr-xr-xres/drawable-xxhdpi/ic_menu_down.pngbin0 -> 353 bytes
-rwxr-xr-xres/drawable-xxhdpi/ic_menu_up.pngbin0 -> 352 bytes
-rw-r--r--res/drawable-xxhdpi/ic_sort_down.pngbin0 -> 217 bytes
-rw-r--r--res/drawable-xxhdpi/ic_sort_up.pngbin0 -> 217 bytes
-rw-r--r--res/drawable-xxhdpi/icon.pngbin0 -> 1406 bytes
-rwxr-xr-xres/drawable-xxhdpi/levels_wheel0.pngbin0 -> 869 bytes
-rwxr-xr-xres/drawable-xxhdpi/levels_wheel1.pngbin0 -> 963 bytes
-rwxr-xr-xres/drawable-xxhdpi/levels_wheel2.pngbin0 -> 953 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_arrow_down.pngbin0 -> 245 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_arrow_up.pngbin0 -> 231 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_bluearm.pngbin0 -> 474 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_bluebody.pngbin0 -> 429 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_blueleg.pngbin0 -> 392 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_engine.pngbin0 -> 2263 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_fender.pngbin0 -> 1769 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_flag_finish0.pngbin0 -> 894 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_flag_finish1.pngbin0 -> 870 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_flag_finish2.pngbin0 -> 895 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_flag_start0.pngbin0 -> 717 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_flag_start1.pngbin0 -> 743 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_flag_start2.pngbin0 -> 784 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_helmet.pngbin0 -> 1297 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_lock0.pngbin0 -> 436 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_lock1.pngbin0 -> 1184 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_lock2.pngbin0 -> 473 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_medal_bronze.pngbin0 -> 702 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_medal_gold.pngbin0 -> 706 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_medal_silver.pngbin0 -> 548 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_steering.pngbin0 -> 133 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_wheel1.pngbin0 -> 968 bytes
-rwxr-xr-xres/drawable-xxhdpi/s_wheel2.pngbin0 -> 972 bytes
-rw-r--r--res/drawable-xxxhdpi/icon.pngbin0 -> 1898 bytes
-rwxr-xr-xres/drawable/btn_b.xml8
-rwxr-xr-xres/drawable/btn_br.xml8
-rwxr-xr-xres/drawable/btn_n.xml8
-rwxr-xr-xres/drawable/btn_r.xml8
-rwxr-xr-xres/drawable/ic_menu.xml7
-rw-r--r--res/drawable/ic_sort.xml7
-rw-r--r--res/drawable/menu_item_color.xml8
-rwxr-xr-xres/layout/activity_gdtr.xml11
-rw-r--r--res/layout/levels_list_item.xml43
-rwxr-xr-xres/menu/gdtr.xml9
-rwxr-xr-xres/values-sw600dp/dimens.xml8
-rw-r--r--res/values-sw600dp/screen.xml4
-rwxr-xr-xres/values-sw720dp-land/dimens.xml9
-rw-r--r--res/values-sw720dp-land/screen.xml4
-rwxr-xr-xres/values-v11/styles.xml11
-rwxr-xr-xres/values-v14/styles.xml12
-rwxr-xr-xres/values/dimens.xml7
-rw-r--r--res/values/screen.xml4
-rwxr-xr-xres/values/strings.xml236
-rwxr-xr-xres/values/styles.xml21
-rwxr-xr-xsrc/org/happysanta/gd/API/API.java101
-rwxr-xr-xsrc/org/happysanta/gd/API/APIException.java9
-rw-r--r--src/org/happysanta/gd/API/DownloadFile.java144
-rw-r--r--src/org/happysanta/gd/API/DownloadHandler.java14
-rwxr-xr-xsrc/org/happysanta/gd/API/LevelsResponse.java64
-rw-r--r--src/org/happysanta/gd/API/NotificationsResponse.java76
-rw-r--r--src/org/happysanta/gd/API/Request.java143
-rw-r--r--src/org/happysanta/gd/API/Response.java26
-rwxr-xr-xsrc/org/happysanta/gd/API/ResponseHandler.java9
-rw-r--r--src/org/happysanta/gd/Callback.java7
-rwxr-xr-xsrc/org/happysanta/gd/Command.java11
-rwxr-xr-xsrc/org/happysanta/gd/CommandListener.java7
-rw-r--r--src/org/happysanta/gd/DoubleCallback.java7
-rw-r--r--src/org/happysanta/gd/FileDialog.java209
-rwxr-xr-xsrc/org/happysanta/gd/GDActivity.java1177
-rw-r--r--src/org/happysanta/gd/GDApplication.java24
-rwxr-xr-xsrc/org/happysanta/gd/Game/Bitmap.java184
-rwxr-xr-xsrc/org/happysanta/gd/Game/FPMath.java80
-rwxr-xr-xsrc/org/happysanta/gd/Game/GameView.java968
-rwxr-xr-xsrc/org/happysanta/gd/Game/Physics.java1336
-rwxr-xr-xsrc/org/happysanta/gd/Game/k.java34
-rwxr-xr-xsrc/org/happysanta/gd/Global.java21
-rwxr-xr-xsrc/org/happysanta/gd/Helpers.java309
-rw-r--r--src/org/happysanta/gd/KeyboardController.java303
-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
-rwxr-xr-xsrc/org/happysanta/gd/Menu/ActionMenuElement.java141
-rw-r--r--src/org/happysanta/gd/Menu/BigTextMenuElement.java30
-rw-r--r--src/org/happysanta/gd/Menu/ClickableMenuElement.java196
-rwxr-xr-xsrc/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java222
-rwxr-xr-xsrc/org/happysanta/gd/Menu/EmptyLineMenuElement.java42
-rwxr-xr-xsrc/org/happysanta/gd/Menu/HighScoreTextMenuElement.java100
-rw-r--r--src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java103
-rwxr-xr-xsrc/org/happysanta/gd/Menu/LevelMenuElement.java370
-rw-r--r--src/org/happysanta/gd/Menu/LevelsAdapter.java53
-rw-r--r--src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java86
-rw-r--r--src/org/happysanta/gd/Menu/LevelsMenuScreen.java429
-rwxr-xr-xsrc/org/happysanta/gd/Menu/Menu.java1554
-rw-r--r--src/org/happysanta/gd/Menu/MenuElement.java20
-rwxr-xr-xsrc/org/happysanta/gd/Menu/MenuElementOld.java32
-rwxr-xr-xsrc/org/happysanta/gd/Menu/MenuHandler.java12
-rwxr-xr-xsrc/org/happysanta/gd/Menu/MenuScreen.java277
-rw-r--r--src/org/happysanta/gd/Menu/NameInputMenuScreen.java175
-rw-r--r--src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java10
-rw-r--r--src/org/happysanta/gd/Menu/OptionsMenuElement.java301
-rwxr-xr-xsrc/org/happysanta/gd/Menu/SimpleMenuElement.java176
-rw-r--r--src/org/happysanta/gd/Menu/SimpleMenuElementNew.java77
-rwxr-xr-xsrc/org/happysanta/gd/Menu/TextMenuElement.java80
-rw-r--r--src/org/happysanta/gd/Menu/Views/LevelNameLeadingMarginSpan2.java38
-rw-r--r--src/org/happysanta/gd/Menu/Views/MenuHelmetView.java111
-rw-r--r--src/org/happysanta/gd/Menu/Views/MenuImageView.java34
-rw-r--r--src/org/happysanta/gd/Menu/Views/MenuLinearLayout.java68
-rw-r--r--src/org/happysanta/gd/Menu/Views/MenuRelativeLayout.java55
-rw-r--r--src/org/happysanta/gd/Menu/Views/MenuTextView.java73
-rw-r--r--src/org/happysanta/gd/Menu/Views/MenuTitleLinearLayout.java39
-rw-r--r--src/org/happysanta/gd/Menu/Views/MenuView.java12
-rw-r--r--src/org/happysanta/gd/Menu/Views/ObservableScrollView.java31
-rw-r--r--src/org/happysanta/gd/Settings.java215
-rw-r--r--src/org/happysanta/gd/Storage/HighScores.java152
-rw-r--r--src/org/happysanta/gd/Storage/Level.java300
-rw-r--r--src/org/happysanta/gd/Storage/LevelsDataSource.java293
-rw-r--r--src/org/happysanta/gd/Storage/LevelsManager.java503
-rw-r--r--src/org/happysanta/gd/Storage/LevelsSQLiteOpenHelper.java141
-rwxr-xr-xsrc/org/happysanta/gd/Util/HexDump.java124
-rw-r--r--src/org/happysanta/gd/WaitForNetworkConnection.java34
349 files changed, 15401 insertions, 0 deletions
diff --git a/.classpath b/.classpath
new file mode 100755
index 0000000..7bc01d9
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+ <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
+ <classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/.idea/.name b/.idea/.name
new file mode 100755
index 0000000..31ab503
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Gravity Defied \ No newline at end of file
diff --git a/.idea/artifacts/Gravity_Defied_Classic.xml b/.idea/artifacts/Gravity_Defied_Classic.xml
new file mode 100644
index 0000000..f3850df
--- /dev/null
+++ b/.idea/artifacts/Gravity_Defied_Classic.xml
@@ -0,0 +1,22 @@
+<component name="ArtifactManager">
+ <artifact type="apk" name="Gravity_Defied_Classic">
+ <output-path>$PROJECT_DIR$/out/artifacts/Gravity_Defied_Classic</output-path>
+ <properties id="android-properties">
+ <options>
+ <option name="keyAlias" value="ch1p" />
+ <option name="keyPassword" value="d2lkNHBpbmEyNTgzNTB6" />
+ <option name="keyStorePassword" value="d2lkNHBpbmEyNTgzNTB6" />
+ <option name="keyStoreUrl" value="file://$PROJECT_DIR$/../key/my-release-key.keystore" />
+ <option name="proGuardCfgFiles">
+ <list>
+ <option value="file://%MODULE_SDK_HOME%/tools/proguard/proguard-android.txt" />
+ </list>
+ </option>
+ <option name="signingMode" value="RELEASE_SIGNED" />
+ </options>
+ </properties>
+ <root id="archive" name="Gravity_Defied_Classic.apk">
+ <element id="android-final-package" facet="AGDTR/android/Android" />
+ </root>
+ </artifact>
+</component> \ No newline at end of file
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
new file mode 100755
index 0000000..cab819f
--- /dev/null
+++ b/.idea/codeStyleSettings.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectCodeStyleSettingsManager">
+ <option name="PER_PROJECT_SETTINGS">
+ <value>
+ <XML>
+ <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+ </XML>
+ </value>
+ </option>
+ <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
+ </component>
+</project>
+
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100755
index 0000000..08cf6dd
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="CompilerConfiguration">
+ <option name="DEFAULT_COMPILER" value="Javac" />
+ <resourceExtensions />
+ <wildcardResourcePatterns>
+ <entry name="!?*.java" />
+ <entry name="!?*.form" />
+ <entry name="!?*.class" />
+ <entry name="!?*.groovy" />
+ <entry name="!?*.scala" />
+ <entry name="!?*.flex" />
+ <entry name="!?*.kt" />
+ <entry name="!?*.clj" />
+ </wildcardResourcePatterns>
+ <annotationProcessing>
+ <profile default="true" name="Default" enabled="true">
+ <processorPath useClasspath="false">
+ <entry name="$PROJECT_DIR$/../../javalibs/androidannotations-3.0.1.jar" />
+ </processorPath>
+ </profile>
+ </annotationProcessing>
+ </component>
+</project>
+
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
new file mode 100755
index 0000000..e7bedf3
--- /dev/null
+++ b/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,3 @@
+<component name="CopyrightManager">
+ <settings default="" />
+</component> \ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100755
index 0000000..e206d70
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+
diff --git a/.idea/libraries/acra_4_5_0.xml b/.idea/libraries/acra_4_5_0.xml
new file mode 100644
index 0000000..0e485f4
--- /dev/null
+++ b/.idea/libraries/acra_4_5_0.xml
@@ -0,0 +1,9 @@
+<component name="libraryTable">
+ <library name="acra-4.5.0">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/libs/acra-4.5.0.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/android_support_v4.xml b/.idea/libraries/android_support_v4.xml
new file mode 100644
index 0000000..90805f2
--- /dev/null
+++ b/.idea/libraries/android_support_v4.xml
@@ -0,0 +1,9 @@
+<component name="libraryTable">
+ <library name="android-support-v4">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/libs/android-support-v4.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/libraries/android_support_v4_c1a500050aef26b42ae63e5fd8ee3115.xml b/.idea/libraries/android_support_v4_c1a500050aef26b42ae63e5fd8ee3115.xml
new file mode 100644
index 0000000..0fe9754
--- /dev/null
+++ b/.idea/libraries/android_support_v4_c1a500050aef26b42ae63e5fd8ee3115.xml
@@ -0,0 +1,9 @@
+<component name="libraryTable">
+ <library name="android-support-v4-c1a500050aef26b42ae63e5fd8ee3115">
+ <CLASSES>
+ <root url="jar://$PROJECT_DIR$/bin/dexedLibs/android-support-v4-c1a500050aef26b42ae63e5fd8ee3115.jar!/" />
+ </CLASSES>
+ <JAVADOC />
+ <SOURCES />
+ </library>
+</component> \ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100755
index 0000000..6c59f44
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="DaemonCodeAnalyzer">
+ <disable_hints />
+ </component>
+ <component name="EntryPointsManager">
+ <entry_points version="2.0" />
+ </component>
+ <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+ <OptionsSetting value="true" id="Add" />
+ <OptionsSetting value="true" id="Remove" />
+ <OptionsSetting value="true" id="Checkout" />
+ <OptionsSetting value="true" id="Update" />
+ <OptionsSetting value="true" id="Status" />
+ <OptionsSetting value="true" id="Edit" />
+ <ConfirmationsSetting value="0" id="Add" />
+ <ConfirmationsSetting value="0" id="Remove" />
+ </component>
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
+ <output url="file://$PROJECT_DIR$/out" />
+ </component>
+ <component name="RunManager">
+ <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
+ <module name="" />
+ <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
+ <option name="PROGRAM_PARAMETERS" />
+ <method />
+ </configuration>
+ <configuration default="true" type="Remote" factoryName="Remote">
+ <option name="USE_SOCKET_TRANSPORT" value="true" />
+ <option name="SERVER_MODE" value="false" />
+ <option name="SHMEM_ADDRESS" value="javadebug" />
+ <option name="HOST" value="localhost" />
+ <option name="PORT" value="5005" />
+ <method />
+ </configuration>
+ <configuration default="true" type="TestNG" factoryName="TestNG">
+ <module name="" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="SUITE_NAME" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="METHOD_NAME" />
+ <option name="GROUP_NAME" />
+ <option name="TEST_OBJECT" value="CLASS" />
+ <option name="VM_PARAMETERS" value="-ea" />
+ <option name="PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="OUTPUT_DIRECTORY" />
+ <option name="ANNOTATION_TYPE" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="moduleWithDependencies" />
+ </option>
+ <option name="USE_DEFAULT_REPORTERS" value="false" />
+ <option name="PROPERTIES_FILE" />
+ <envs />
+ <properties />
+ <listeners />
+ <method />
+ </configuration>
+ <configuration default="true" type="Applet" factoryName="Applet">
+ <module name="" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="HTML_FILE_NAME" />
+ <option name="HTML_USED" value="false" />
+ <option name="WIDTH" value="400" />
+ <option name="HEIGHT" value="300" />
+ <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
+ <option name="VM_PARAMETERS" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <method />
+ </configuration>
+ <configuration default="true" type="Application" factoryName="Application">
+ <option name="MAIN_CLASS_NAME" />
+ <option name="VM_PARAMETERS" />
+ <option name="PROGRAM_PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="ENABLE_SWING_INSPECTOR" value="false" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <module name="" />
+ <envs />
+ <method />
+ </configuration>
+ <configuration default="true" type="JUnit" factoryName="JUnit">
+ <module name="" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="METHOD_NAME" />
+ <option name="TEST_OBJECT" value="class" />
+ <option name="VM_PARAMETERS" value="-ea" />
+ <option name="PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="moduleWithDependencies" />
+ </option>
+ <envs />
+ <patterns />
+ <method />
+ </configuration>
+ <list size="0" />
+ <configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
+ <Host>localhost</Host>
+ <Port>5050</Port>
+ </configuration>
+ </component>
+ <component name="SvnBranchConfigurationManager">
+ <option name="mySupportsUserInfoFilter" value="true" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100755
index 0000000..3ccbf04
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ProjectModuleManager">
+ <modules>
+ <module fileurl="file://$PROJECT_DIR$/AGDTR.iml" filepath="$PROJECT_DIR$/AGDTR.iml" />
+ </modules>
+ </component>
+</project>
+
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
new file mode 100755
index 0000000..922003b
--- /dev/null
+++ b/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+<component name="DependencyValidationManager">
+ <state>
+ <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+ </state>
+</component> \ No newline at end of file
diff --git a/.idea/src.iml b/.idea/src.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/src.iml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$" />
+ <orderEntry type="inheritedJdk" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ </component>
+</module> \ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100755
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="Palette2">
+ <group name="Swing">
+ <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+ </item>
+ <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+ </item>
+ <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+ </item>
+ <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
+ <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+ </item>
+ <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+ <initial-values>
+ <property name="text" value="Button" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+ <initial-values>
+ <property name="text" value="RadioButton" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+ <initial-values>
+ <property name="text" value="CheckBox" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+ <initial-values>
+ <property name="text" value="Label" />
+ </initial-values>
+ </item>
+ <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+ <preferred-size width="150" height="-1" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+ </item>
+ <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+ <preferred-size width="150" height="50" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+ <preferred-size width="200" height="200" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+ <preferred-size width="200" height="200" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+ </item>
+ <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+ </item>
+ <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+ </item>
+ <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+ </item>
+ <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+ <preferred-size width="-1" height="20" />
+ </default-constraints>
+ </item>
+ <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+ <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+ </item>
+ <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+ <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+ </item>
+ </group>
+ </component>
+</project>
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100755
index 0000000..c80f219
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
+ </component>
+</project>
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100755
index 0000000..2ae2ba1
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,1767 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="AndroidConfiguredLogFilters">
+ <filters>
+ <filter>
+ <option name="logLevel" value="verbose" />
+ <option name="logMessagePattern" value="" />
+ <option name="logTagPattern" value="agcy" />
+ <option name="name" value="agcy (vk spy)" />
+ <option name="packageNamePattern" value="" />
+ <option name="pid" value="" />
+ </filter>
+ <filter>
+ <option name="logLevel" value="verbose" />
+ <option name="logMessagePattern" value="" />
+ <option name="logTagPattern" value="" />
+ <option name="name" value="com.vkontakte.android" />
+ <option name="packageNamePattern" value="com.vkontakte.android" />
+ <option name="pid" value="" />
+ </filter>
+ <filter>
+ <option name="logLevel" value="verbose" />
+ <option name="logMessagePattern" value="" />
+ <option name="logTagPattern" value="" />
+ <option name="name" value="app: com.ch1p.gd" />
+ <option name="packageNamePattern" value="com.ch1p.gd" />
+ <option name="pid" value="" />
+ </filter>
+ <filter>
+ <option name="name" value="app: org.happysanta.gd" />
+ <option name="packageNamePattern" value="org.happysanta.gd" />
+ </filter>
+ </filters>
+ </component>
+ <component name="AndroidLayoutPreviewToolWindow">
+ <option name="state">
+ <GlobalState>
+ <option name="visible" value="false" />
+ </GlobalState>
+ </option>
+ </component>
+ <component name="AndroidLayouts">
+ <shared>
+ <config />
+ </shared>
+ </component>
+ <component name="AndroidLogFilters">
+ <option name="TOOL_WINDOW_CONFIGURED_FILTER" value="app: org.happysanta.gd" />
+ </component>
+ <component name="ArtifactsWorkspaceSettings">
+ <artifacts-to-build>
+ <artifact name="Gravity_Defied_Classic" />
+ </artifacts-to-build>
+ </component>
+ <component name="ChangeListManager">
+ <list default="true" id="2577decc-ddce-4d96-879d-94a8591972de" name="Default" comment="" />
+ <ignored path="AGDTR.iws" />
+ <ignored path=".idea/workspace.xml" />
+ <ignored path="$PROJECT_DIR$/out/" />
+ <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+ <option name="TRACKING_ENABLED" value="true" />
+ <option name="SHOW_DIALOG" value="false" />
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+ <option name="LAST_RESOLUTION" value="IGNORE" />
+ </component>
+ <component name="ChangesViewManager" flattened_view="false" show_ignored="false" />
+ <component name="Commander">
+ <leftPanel />
+ <rightPanel />
+ <splitter proportion="0.5" />
+ </component>
+ <component name="CreatePatchCommitExecutor">
+ <option name="PATCH_PATH" value="" />
+ </component>
+ <component name="DaemonCodeAnalyzer">
+ <disable_hints />
+ </component>
+ <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
+ <component name="FavoritesManager">
+ <favorites_list name="AGDTR" />
+ </component>
+ <component name="FileEditorManager">
+ <leaf>
+ <file leaf-file-name="API.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/API.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="300" max-vertical-offset="1410">
+ <caret line="11" column="13" selection-start-line="11" selection-start-column="13" selection-end-line="11" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ResponseHandler.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/ResponseHandler.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="225">
+ <caret line="8" column="1" selection-start-line="6" selection-start-column="4" selection-end-line="8" selection-end-column="1" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Bitmap.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/Bitmap.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="515" max-vertical-offset="2610">
+ <caret line="9" column="13" selection-start-line="9" selection-start-column="13" selection-end-line="9" selection-end-column="13" />
+ <folding>
+ <element signature="imports" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Menu.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/Menu.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="22535" max-vertical-offset="23040">
+ <caret line="31" column="13" selection-start-line="31" selection-start-column="13" selection-end-line="31" selection-end-column="13" />
+ <folding>
+ <element signature="imports" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="MenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/MenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="390">
+ <caret line="7" column="17" selection-start-line="7" selection-start-column="17" selection-end-line="7" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="MenuElementOld.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/MenuElementOld.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="35" max-vertical-offset="540">
+ <caret line="6" column="17" selection-start-line="6" selection-start-column="17" selection-end-line="6" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="MenuHandler.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/MenuHandler.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="270">
+ <caret line="2" column="17" selection-start-line="2" selection-start-column="17" selection-end-line="2" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="MenuScreen.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/MenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3305" max-vertical-offset="3810">
+ <caret line="35" column="0" selection-start-line="35" selection-start-column="0" selection-end-line="35" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Helpers.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Helpers.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="335" max-vertical-offset="3645">
+ <caret line="21" column="13" selection-start-line="21" selection-start-column="13" selection-end-line="21" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="NameInputMenuScreen.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/NameInputMenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="2000" max-vertical-offset="2505">
+ <caret line="16" column="13" selection-start-line="16" selection-start-column="13" selection-end-line="16" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="OnMenuElementHighlightListener.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="240">
+ <caret line="5" column="17" selection-start-line="5" selection-start-column="17" selection-end-line="5" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="OptionsMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/OptionsMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3635" max-vertical-offset="4140">
+ <caret line="17" column="13" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="SimpleMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/SimpleMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="1715" max-vertical-offset="2220">
+ <caret line="18" column="13" selection-start-line="18" selection-start-column="13" selection-end-line="18" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="SimpleMenuElementNew.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/SimpleMenuElementNew.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="710" max-vertical-offset="1215">
+ <caret line="4" column="13" selection-start-line="4" selection-start-column="13" selection-end-line="4" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="TextMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/TextMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="560" max-vertical-offset="1065">
+ <caret line="17" column="13" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="HighScores.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/HighScores.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="950" max-vertical-offset="2010">
+ <caret line="4" column="13" selection-start-line="4" selection-start-column="13" selection-end-line="4" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Level.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/Level.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="3120">
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="LevelsDataSource.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/LevelsDataSource.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3480" max-vertical-offset="4275">
+ <caret line="14" column="13" selection-start-line="14" selection-start-column="13" selection-end-line="14" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="LevelsManager.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/LevelsManager.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="5510" max-vertical-offset="6450">
+ <caret line="41" column="13" selection-start-line="41" selection-start-column="13" selection-end-line="41" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="LevelsSQLiteOpenHelper.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/LevelsSQLiteOpenHelper.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="2085">
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Global.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Global.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="405">
+ <caret line="4" column="13" selection-start-line="4" selection-start-column="13" selection-end-line="4" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="FPMath.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/FPMath.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="755" max-vertical-offset="1260">
+ <caret line="68" column="30" selection-start-line="68" selection-start-column="30" selection-end-line="68" selection-end-column="30" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Reader.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/Reader.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="810">
+ <caret line="37" column="37" selection-start-line="37" selection-start-column="37" selection-end-line="37" selection-end-column="37" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ActionMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/ActionMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="1415" max-vertical-offset="1920">
+ <caret line="43" column="43" selection-start-line="43" selection-start-column="43" selection-end-line="43" selection-end-column="43" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="BigTextMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/BigTextMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="510">
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ClickableMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/ClickableMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="2060" max-vertical-offset="2565">
+ <caret line="112" column="11" selection-start-line="112" selection-start-column="11" selection-end-line="112" selection-end-column="11" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="DownloadLevelsMenuScreen.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="2970">
+ <caret line="85" column="97" selection-start-line="85" selection-start-column="97" selection-end-line="85" selection-end-column="97" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="EmptyLineMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/EmptyLineMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="555">
+ <caret line="9" column="13" selection-start-line="9" selection-start-column="13" selection-end-line="9" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="HighScoreTextMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="890" max-vertical-offset="1395">
+ <caret line="15" column="13" selection-start-line="15" selection-start-column="13" selection-end-line="15" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="InstalledLevelsMenuScreen.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="800" max-vertical-offset="1305">
+ <caret line="9" column="13" selection-start-line="9" selection-start-column="13" selection-end-line="9" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="LevelsAdapter.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/LevelsAdapter.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="185" max-vertical-offset="690">
+ <caret line="17" column="13" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="LevelMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/LevelMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="5100">
+ <caret line="304" column="41" selection-start-line="304" selection-start-column="41" selection-end-line="304" selection-end-column="41" />
+ <folding>
+ <element signature="e#10817#10818#0" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="LevelsCountTextMenuElement.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="65" max-vertical-offset="1215">
+ <caret line="13" column="13" selection-start-line="13" selection-start-column="13" selection-end-line="13" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="ObservableScrollView.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/Views/ObservableScrollView.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="480">
+ <caret line="5" column="13" selection-start-line="5" selection-start-column="13" selection-end-line="5" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="LevelsMenuScreen.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/LevelsMenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="1985" max-vertical-offset="6105">
+ <caret line="28" column="13" selection-start-line="28" selection-start-column="13" selection-end-line="28" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="GameView.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/GameView.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="13565" max-vertical-offset="14070">
+ <caret line="949" column="5" selection-start-line="949" selection-start-column="5" selection-end-line="949" selection-end-column="5" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="k.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/k.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="600">
+ <caret line="30" column="29" selection-start-line="27" selection-start-column="8" selection-end-line="30" selection-end-column="29" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Physics.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/Physics.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="5295" max-vertical-offset="19860">
+ <caret line="13" column="13" selection-start-line="13" selection-start-column="13" selection-end-line="13" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="InvalidTrackException.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/InvalidTrackException.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="240">
+ <caret line="2" column="0" selection-start-line="2" selection-start-column="0" selection-end-line="2" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Level.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/Level.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3140" max-vertical-offset="3645">
+ <caret line="11" column="0" selection-start-line="11" selection-start-column="0" selection-end-line="11" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="LevelHeader.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/LevelHeader.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="765">
+ <caret line="43" column="24" selection-start-line="43" selection-start-column="24" selection-end-line="43" selection-end-column="24" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Loader.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/Loader.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="4650">
+ <caret line="104" column="18" selection-start-line="104" selection-start-column="18" selection-end-line="104" selection-end-column="18" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="DownloadHandler.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/DownloadHandler.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="285">
+ <caret line="5" column="17" selection-start-line="5" selection-start-column="17" selection-end-line="5" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="NotificationsResponse.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/NotificationsResponse.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="270" max-vertical-offset="945">
+ <caret line="10" column="22" selection-start-line="10" selection-start-column="22" selection-end-line="10" selection-end-column="22" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="LevelsResponse.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/LevelsResponse.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="410" max-vertical-offset="915">
+ <caret line="56" column="4" selection-start-line="56" selection-start-column="4" selection-end-line="56" selection-end-column="4" />
+ <folding>
+ <element signature="e#1338#1339#0" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Request.java" pinned="false" current-in-tab="true">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/Request.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.31512606" vertical-offset="0" max-vertical-offset="1935">
+ <caret line="28" column="19" selection-start-line="28" selection-start-column="19" selection-end-line="28" selection-end-column="19" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Response.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/Response.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="420">
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="WaitForNetworkConnection.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/WaitForNetworkConnection.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="555">
+ <caret line="7" column="13" selection-start-line="7" selection-start-column="13" selection-end-line="7" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="Settings.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Settings.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="2760">
+ <caret line="92" column="13" selection-start-line="92" selection-start-column="13" selection-end-line="92" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file leaf-file-name="KeyboardController.java" pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/KeyboardController.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3815" max-vertical-offset="4320">
+ <caret line="96" column="29" selection-start-line="96" selection-start-column="29" selection-end-line="96" selection-end-column="29" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ </leaf>
+ </component>
+ <component name="FindManager">
+ <FindUsagesManager>
+ <setting name="OPEN_NEW_TAB" value="true" />
+ </FindUsagesManager>
+ </component>
+ <component name="GenerateSignedApkSettings">
+ <option name="KEY_STORE_PATH" value="$PROJECT_DIR$/../key/my-release-key.keystore" />
+ <option name="KEY_ALIAS" value="ch1p" />
+ </component>
+ <component name="Git.Settings">
+ <option name="PREVIOUS_COMMIT_AUTHORS">
+ <list>
+ <option value="ch1p" />
+ </list>
+ </option>
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+ </component>
+ <component name="IdeDocumentHistory">
+ <option name="CHANGED_PATHS">
+ <list>
+ <option value="$PROJECT_DIR$/src/org/happysanta/gd/GDActivity.java" />
+ <option value="$PROJECT_DIR$/src/org/happysanta/gd/API/Response.java" />
+ <option value="$PROJECT_DIR$/src/org/happysanta/gd/API/LevelsResponse.java" />
+ </list>
+ </option>
+ </component>
+ <component name="MavenProjectNavigator">
+ <treeState />
+ </component>
+ <component name="ProjectFrameBounds">
+ <option name="x" value="54" />
+ <option name="y" value="23" />
+ <option name="width" value="1386" />
+ <option name="height" value="877" />
+ </component>
+ <component name="ProjectLevelVcsManager" settingsEditedManually="true">
+ <OptionsSetting value="true" id="Add" />
+ <OptionsSetting value="true" id="Remove" />
+ <OptionsSetting value="true" id="Checkout" />
+ <OptionsSetting value="true" id="Update" />
+ <OptionsSetting value="true" id="Status" />
+ <OptionsSetting value="true" id="Edit" />
+ <ConfirmationsSetting value="2" id="Add" />
+ <ConfirmationsSetting value="0" id="Remove" />
+ </component>
+ <component name="ProjectReloadState">
+ <option name="STATE" value="0" />
+ </component>
+ <component name="ProjectStructureProblems">
+ <ignored-problems>
+ <problem id="invalid-module-dependency(module:AGDTR,com.android.ide.eclipse.adt.DEPENDENCIES)" />
+ <problem id="library-invalid-classes-path(library:project:android-support-v4)" />
+ <problem id="unused-library(library:project:android-support-v4)" />
+ <problem id="unused-library(library:project:android-support-v4-c1a500050aef26b42ae63e5fd8ee3115)" />
+ </ignored-problems>
+ </component>
+ <component name="ProjectView">
+ <navigator currentView="ProjectPane" proportions="" version="1">
+ <flattenPackages />
+ <showMembers />
+ <showModules />
+ <showLibraryContents />
+ <hideEmptyPackages />
+ <abbreviatePackageNames />
+ <autoscrollToSource />
+ <autoscrollFromSource />
+ <sortByType />
+ </navigator>
+ <panes>
+ <pane id="Scope" />
+ <pane id="PackagesPane" />
+ <pane id="ProjectPane">
+ <subPane>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="External Libraries" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ExternalLibrariesNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="&lt; Android API 19 Platform (1) &gt;" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="gd" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="gd" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="FileDialog.java" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.ClassesTreeStructureProvider$PsiClassOwnerTreeNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="gd" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Storage" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="gd" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Menu" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="gd" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Menu" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Views" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="gd" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Levels" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="gd" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Game" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ <PATH>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="Gravity Defied" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="src" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="gd" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ <PATH_ELEMENT>
+ <option name="myItemId" value="API" />
+ <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+ </PATH_ELEMENT>
+ </PATH>
+ </subPane>
+ </pane>
+ </panes>
+ </component>
+ <component name="PropertiesComponent">
+ <property name="GoToClass.includeLibraries" value="false" />
+ <property name="GoToClass.toSaveIncludeLibraries" value="false" />
+ <property name="GoToFile.includeJavaFiles" value="false" />
+ <property name="MemberChooser.sorted" value="false" />
+ <property name="MemberChooser.showClasses" value="true" />
+ <property name="MemberChooser.copyJavadoc" value="false" />
+ <property name="recentsLimit" value="5" />
+ <property name="FullScreen" value="false" />
+ <property name="project.structure.last.edited" value="Modules" />
+ <property name="project.structure.proportion" value="0.15" />
+ <property name="project.structure.side.proportion" value="0.2" />
+ <property name="options.lastSelected" value="preferences.keymap" />
+ <property name="options.splitter.main.proportions" value="0.3" />
+ <property name="options.splitter.details.proportions" value="0.2" />
+ <property name="options.searchVisible" value="true" />
+ <property name="restartRequiresConfirmation" value="true" />
+ <property name="last_opened_file_path" value="$USER_HOME$/Downloads" />
+ <property name="SearchEverywhereHistoryKey" value="&#9;FILE&#9;file:///Users/evgeny/Development/GD/AGDTR/src/com/grishka/agdtr/TextMenuElement.java" />
+ <property name="ExportedModule" value="AGDTR" />
+ <property name="ExportedApkPath" value="$PROJECT_DIR$/AGDTR_SIGNED.apk" />
+ <property name="AndroidRunProguardForReleaseBuild" value="false" />
+ <property name="AndroidTargetDevices" value="03b615d3f0b35eed" />
+ <property name="Repository.Attach.JavaDocs" value="false" />
+ <property name="Repository.Attach.Sources" value="false" />
+ </component>
+ <component name="RecentsManager">
+ <key name="CopyFile.RECENT_KEYS">
+ <recent name="$PROJECT_DIR$/res/drawable" />
+ </key>
+ <key name="MoveClassesOrPackagesDialog.RECENTS_KEY">
+ <recent name="org.happysanta.gd" />
+ <recent name="com.ch1p.gd" />
+ <recent name="com.grishka.agdtr" />
+ <recent name="com.grishka.agdtr.Menu.Views" />
+ <recent name="com.grishka.agdtr.Game" />
+ </key>
+ </component>
+ <component name="RunManager" selected="Android Application.GD">
+ <configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
+ <module name="" />
+ <option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
+ <option name="PROGRAM_PARAMETERS" />
+ <method />
+ </configuration>
+ <configuration default="true" type="AndroidTestRunConfigurationType" factoryName="Android Tests">
+ <module name="" />
+ <option name="TESTING_TYPE" value="0" />
+ <option name="INSTRUMENTATION_RUNNER_CLASS" value="" />
+ <option name="METHOD_NAME" value="" />
+ <option name="CLASS_NAME" value="" />
+ <option name="PACKAGE_NAME" value="" />
+ <option name="TARGET_SELECTION_MODE" value="EMULATOR" />
+ <option name="USE_LAST_SELECTED_DEVICE" value="false" />
+ <option name="PREFERRED_AVD" value="" />
+ <option name="USE_COMMAND_LINE" value="true" />
+ <option name="COMMAND_LINE" value="" />
+ <option name="WIPE_USER_DATA" value="false" />
+ <option name="DISABLE_BOOT_ANIMATION" value="false" />
+ <option name="NETWORK_SPEED" value="full" />
+ <option name="NETWORK_LATENCY" value="none" />
+ <option name="CLEAR_LOGCAT" value="false" />
+ <option name="SHOW_LOGCAT_AUTOMATICALLY" value="true" />
+ <option name="FILTER_LOGCAT_AUTOMATICALLY" value="true" />
+ <method />
+ </configuration>
+ <configuration default="true" type="Remote" factoryName="Remote">
+ <option name="USE_SOCKET_TRANSPORT" value="true" />
+ <option name="SERVER_MODE" value="false" />
+ <option name="SHMEM_ADDRESS" value="javadebug" />
+ <option name="HOST" value="localhost" />
+ <option name="PORT" value="5005" />
+ <method />
+ </configuration>
+ <configuration default="true" type="JarApplication" factoryName="JAR Application">
+ <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+ <envs />
+ <method />
+ </configuration>
+ <configuration default="true" type="GradleRunConfiguration" factoryName="Gradle">
+ <ExternalSystemSettings>
+ <option name="executionName" />
+ <option name="externalProjectPath" />
+ <option name="externalSystemIdString" value="GRADLE" />
+ <option name="scriptParameters" />
+ <option name="taskDescriptions">
+ <list />
+ </option>
+ <option name="taskNames">
+ <list />
+ </option>
+ <option name="vmOptions" />
+ </ExternalSystemSettings>
+ <method />
+ </configuration>
+ <configuration default="true" type="Applet" factoryName="Applet">
+ <module name="" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="HTML_FILE_NAME" />
+ <option name="HTML_USED" value="false" />
+ <option name="WIDTH" value="400" />
+ <option name="HEIGHT" value="300" />
+ <option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
+ <option name="VM_PARAMETERS" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <method />
+ </configuration>
+ <configuration default="true" type="TestNG" factoryName="TestNG">
+ <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+ <module name="" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="SUITE_NAME" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="METHOD_NAME" />
+ <option name="GROUP_NAME" />
+ <option name="TEST_OBJECT" value="CLASS" />
+ <option name="VM_PARAMETERS" value="-ea" />
+ <option name="PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="OUTPUT_DIRECTORY" />
+ <option name="ANNOTATION_TYPE" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="moduleWithDependencies" />
+ </option>
+ <option name="USE_DEFAULT_REPORTERS" value="false" />
+ <option name="PROPERTIES_FILE" />
+ <envs />
+ <properties />
+ <listeners />
+ <method />
+ </configuration>
+ <configuration default="true" type="Application" factoryName="Application">
+ <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="VM_PARAMETERS" />
+ <option name="PROGRAM_PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="ENABLE_SWING_INSPECTOR" value="false" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <module name="" />
+ <envs />
+ <method />
+ </configuration>
+ <configuration default="true" type="JUnit" factoryName="JUnit">
+ <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+ <module name="" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="PACKAGE_NAME" />
+ <option name="MAIN_CLASS_NAME" />
+ <option name="METHOD_NAME" />
+ <option name="TEST_OBJECT" value="class" />
+ <option name="VM_PARAMETERS" value="-ea" />
+ <option name="PARAMETERS" />
+ <option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
+ <option name="ENV_VARIABLES" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <option name="TEST_SEARCH_SCOPE">
+ <value defaultName="moduleWithDependencies" />
+ </option>
+ <envs />
+ <patterns />
+ <method />
+ </configuration>
+ <configuration default="true" type="AndroidRunConfigurationType" factoryName="Android Application">
+ <module name="" />
+ <option name="ACTIVITY_CLASS" value="" />
+ <option name="MODE" value="default_activity" />
+ <option name="DEPLOY" value="true" />
+ <option name="ARTIFACT_NAME" value="" />
+ <option name="TARGET_SELECTION_MODE" value="EMULATOR" />
+ <option name="USE_LAST_SELECTED_DEVICE" value="false" />
+ <option name="PREFERRED_AVD" value="" />
+ <option name="USE_COMMAND_LINE" value="true" />
+ <option name="COMMAND_LINE" value="" />
+ <option name="WIPE_USER_DATA" value="false" />
+ <option name="DISABLE_BOOT_ANIMATION" value="false" />
+ <option name="NETWORK_SPEED" value="full" />
+ <option name="NETWORK_LATENCY" value="none" />
+ <option name="CLEAR_LOGCAT" value="false" />
+ <option name="SHOW_LOGCAT_AUTOMATICALLY" value="true" />
+ <option name="FILTER_LOGCAT_AUTOMATICALLY" value="true" />
+ <method />
+ </configuration>
+ <configuration default="false" name="GD" type="AndroidRunConfigurationType" factoryName="Android Application">
+ <module name="AGDTR" />
+ <option name="ACTIVITY_CLASS" value="" />
+ <option name="MODE" value="default_activity" />
+ <option name="DEPLOY" value="true" />
+ <option name="ARTIFACT_NAME" value="Gravity_Defied_Classic" />
+ <option name="TARGET_SELECTION_MODE" value="USB_DEVICE" />
+ <option name="USE_LAST_SELECTED_DEVICE" value="false" />
+ <option name="PREFERRED_AVD" value="" />
+ <option name="USE_COMMAND_LINE" value="true" />
+ <option name="COMMAND_LINE" value="" />
+ <option name="WIPE_USER_DATA" value="false" />
+ <option name="DISABLE_BOOT_ANIMATION" value="false" />
+ <option name="NETWORK_SPEED" value="full" />
+ <option name="NETWORK_LATENCY" value="none" />
+ <option name="CLEAR_LOGCAT" value="false" />
+ <option name="SHOW_LOGCAT_AUTOMATICALLY" value="true" />
+ <option name="FILTER_LOGCAT_AUTOMATICALLY" value="true" />
+ <RunnerSettings RunnerId="AndroidDebugRunner" />
+ <ConfigurationWrapper RunnerId="AndroidDebugRunner" />
+ <method>
+ <option name="Make" enabled="false" />
+ <option name="BuildArtifacts" enabled="true">
+ <artifact name="Gravity_Defied_Classic" />
+ </option>
+ </method>
+ </configuration>
+ <list size="1">
+ <item index="0" class="java.lang.String" itemvalue="Android Application.GD" />
+ </list>
+ <configuration name="&lt;template&gt;" type="WebApp" default="true" selected="false">
+ <Host>localhost</Host>
+ <Port>5050</Port>
+ </configuration>
+ </component>
+ <component name="ShelveChangesManager" show_recycled="false" />
+ <component name="SliceManager">
+ <option name="analysisUIOptions">
+ <AnalysisUIOptions />
+ </option>
+ </component>
+ <component name="StructureViewFactory">
+ <option name="ACTIVE_ACTIONS" value=",ALPHA_COMPARATOR" />
+ </component>
+ <component name="SvnConfiguration">
+ <configuration />
+ <supportedVersion>125</supportedVersion>
+ </component>
+ <component name="TaskManager">
+ <task active="true" id="Default" summary="Default task">
+ <changelist id="2577decc-ddce-4d96-879d-94a8591972de" name="Default" comment="" />
+ <created>1396515407992</created>
+ <option name="number" value="Default" />
+ <updated>1396515407992</updated>
+ </task>
+ <task id="LOCAL-00001" summary="1.0.3 release">
+ <created>1402860904223</created>
+ <option name="number" value="00001" />
+ <option name="project" value="LOCAL" />
+ <updated>1402860904223</updated>
+ </task>
+ <task id="LOCAL-00002" summary="1.0.3 release (with committed files)">
+ <created>1402861981255</created>
+ <option name="number" value="00002" />
+ <option name="project" value="LOCAL" />
+ <updated>1402861981255</updated>
+ </task>
+ <task id="LOCAL-00003" summary="1.0.3 release (with committed files)">
+ <created>1402862022693</created>
+ <option name="number" value="00003" />
+ <option name="project" value="LOCAL" />
+ <updated>1402862022693</updated>
+ </task>
+ <task id="LOCAL-00004" summary="1.0.4">
+ <created>1402950475748</created>
+ <option name="number" value="00004" />
+ <option name="project" value="LOCAL" />
+ <updated>1402950475748</updated>
+ </task>
+ <option name="localTasksCounter" value="5" />
+ <servers />
+ </component>
+ <component name="TodoView" selected-index="0">
+ <todo-panel id="selected-file">
+ <are-packages-shown value="false" />
+ <are-modules-shown value="false" />
+ <flatten-packages value="false" />
+ <is-autoscroll-to-source value="true" />
+ </todo-panel>
+ <todo-panel id="all">
+ <are-packages-shown value="true" />
+ <are-modules-shown value="false" />
+ <flatten-packages value="false" />
+ <is-autoscroll-to-source value="true" />
+ </todo-panel>
+ <todo-panel id="default-changelist">
+ <are-packages-shown value="false" />
+ <are-modules-shown value="false" />
+ <flatten-packages value="false" />
+ <is-autoscroll-to-source value="false" />
+ </todo-panel>
+ </component>
+ <component name="ToolWindowManager">
+ <frame x="54" y="23" width="1386" height="877" extended-state="6" />
+ <editor active="true" />
+ <layout>
+ <window_info id="Palette&#9;" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.54210526" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32867134" sideWeight="0.5" order="1" side_tool="true" content_ui="tabs" />
+ <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2494382" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+ <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
+ <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.29697767" sideWeight="0.50074404" order="2" side_tool="true" content_ui="tabs" />
+ <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2082397" sideWeight="0.5" order="1" side_tool="true" content_ui="tabs" />
+ <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32894737" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ <window_info id="Build Variants" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.17525035" sideWeight="0.5009901" order="0" side_tool="true" content_ui="tabs" />
+ <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2996058" sideWeight="0.49962547" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Android" active="true" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.33771354" sideWeight="0.49962547" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3276316" sideWeight="0.49962547" order="13" side_tool="false" content_ui="tabs" />
+ <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.20730798" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+ <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.19027181" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+ <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.18080357" sideWeight="0.5" order="3" side_tool="false" content_ui="combo" />
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.29697767" sideWeight="0.49925596" order="12" side_tool="false" content_ui="tabs" />
+ <window_info id="Memory Monitor" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
+ <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24964234" sideWeight="0.5" order="3" side_tool="false" content_ui="combo" />
+ <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
+ <window_info id="Preview" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.35336193" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+ <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3188406" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
+ <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
+ </layout>
+ <layout-to-restore>
+ <window_info id="Palette&#9;" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="Changes" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.54210526" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2494382" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.35657895" sideWeight="0.50037456" order="2" side_tool="true" content_ui="tabs" />
+ <window_info id="Build Variants" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.17525035" sideWeight="0.5009901" order="0" side_tool="true" content_ui="tabs" />
+ <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32894737" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+ <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3276316" sideWeight="0.49962547" order="13" side_tool="false" content_ui="tabs" />
+ <window_info id="Application Servers" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+ <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.17602997" sideWeight="0.5" order="3" side_tool="false" content_ui="combo" />
+ <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.3" sideWeight="0.49962547" order="12" side_tool="false" content_ui="tabs" />
+ <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24964234" sideWeight="0.5" order="3" side_tool="false" content_ui="combo" />
+ <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="10" side_tool="false" content_ui="tabs" />
+ <window_info id="Designer" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+ <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32867134" sideWeight="0.5" order="1" side_tool="true" content_ui="tabs" />
+ <window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+ <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+ <window_info id="Preview" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.35336193" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+ <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.32105264" sideWeight="0.5" order="8" side_tool="false" content_ui="tabs" />
+ <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="9" side_tool="false" content_ui="tabs" />
+ <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.2082397" sideWeight="0.5" order="1" side_tool="true" content_ui="tabs" />
+ <window_info id="Messages" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.30394736" sideWeight="0.49962547" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Android" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.38421053" sideWeight="0.49962547" order="7" side_tool="false" content_ui="tabs" />
+ <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.20749064" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+ <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.19027181" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+ <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" weight="0.4" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+ <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="11" side_tool="false" content_ui="tabs" />
+ </layout-to-restore>
+ </component>
+ <component name="Vcs.Log.UiProperties">
+ <option name="RECENTLY_FILTERED_USER_GROUPS">
+ <collection />
+ </option>
+ <option name="RECENTLY_FILTERED_BRANCH_GROUPS">
+ <collection />
+ </option>
+ </component>
+ <component name="VcsContentAnnotationSettings">
+ <option name="myLimit" value="2678400000" />
+ </component>
+ <component name="VcsManagerConfiguration">
+ <option name="CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT" value="false" />
+ <option name="myTodoPanelSettings">
+ <TodoPanelSettings />
+ </option>
+ <MESSAGE value="1.0.3 release" />
+ <MESSAGE value="1.0.3 release (with committed files)" />
+ <MESSAGE value="1.0.4" />
+ <option name="LAST_COMMIT_MESSAGE" value="1.0.4" />
+ </component>
+ <component name="XDebuggerManager">
+ <breakpoint-manager>
+ <option name="time" value="8" />
+ </breakpoint-manager>
+ <watches-manager />
+ </component>
+ <component name="antWorkspaceConfiguration">
+ <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" />
+ <option name="FILTER_TARGETS" value="false" />
+ </component>
+ <component name="editorHistoryManager">
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/DownloadFile.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="960" max-vertical-offset="2055">
+ <caret line="18" column="36" selection-start-line="18" selection-start-column="36" selection-end-line="18" selection-end-column="36" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/DownloadHandler.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="285">
+ <caret line="5" column="17" selection-start-line="5" selection-start-column="17" selection-end-line="5" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/LevelsResponse.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="410" max-vertical-offset="915">
+ <caret line="56" column="4" selection-start-line="56" selection-start-column="4" selection-end-line="56" selection-end-column="4" />
+ <folding>
+ <element signature="e#1338#1339#0" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/Response.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="420">
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/ResponseHandler.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="225">
+ <caret line="8" column="1" selection-start-line="6" selection-start-column="4" selection-end-line="8" selection-end-column="1" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/Bitmap.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="515" max-vertical-offset="2610">
+ <caret line="9" column="13" selection-start-line="9" selection-start-column="13" selection-end-line="9" selection-end-column="13" />
+ <folding>
+ <element signature="imports" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/FPMath.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="755" max-vertical-offset="1260">
+ <caret line="68" column="30" selection-start-line="68" selection-start-column="30" selection-end-line="68" selection-end-column="30" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/GameView.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="13316" max-vertical-offset="14070">
+ <caret line="949" column="5" selection-start-line="949" selection-start-column="5" selection-end-line="949" selection-end-column="5" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/k.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="600">
+ <caret line="30" column="29" selection-start-line="27" selection-start-column="8" selection-end-line="30" selection-end-column="29" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Game/Physics.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="5295" max-vertical-offset="19860">
+ <caret line="13" column="13" selection-start-line="13" selection-start-column="13" selection-end-line="13" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/InvalidTrackException.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="240">
+ <caret line="2" column="0" selection-start-line="2" selection-start-column="0" selection-end-line="2" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/Level.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3140" max-vertical-offset="3645">
+ <caret line="11" column="0" selection-start-line="11" selection-start-column="0" selection-end-line="11" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/LevelHeader.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="765">
+ <caret line="43" column="24" selection-start-line="43" selection-start-column="24" selection-end-line="43" selection-end-column="24" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/Loader.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="4650">
+ <caret line="104" column="18" selection-start-line="104" selection-start-column="18" selection-end-line="104" selection-end-column="18" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Levels/Reader.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="810">
+ <caret line="37" column="37" selection-start-line="37" selection-start-column="37" selection-end-line="37" selection-end-column="37" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/ActionMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="1415" max-vertical-offset="1920">
+ <caret line="43" column="43" selection-start-line="43" selection-start-column="43" selection-end-line="43" selection-end-column="43" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/BigTextMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="510">
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/ClickableMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="2060" max-vertical-offset="2565">
+ <caret line="112" column="11" selection-start-line="112" selection-start-column="11" selection-end-line="112" selection-end-column="11" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="2970">
+ <caret line="85" column="97" selection-start-line="85" selection-start-column="97" selection-end-line="85" selection-end-column="97" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/EmptyLineMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="555">
+ <caret line="9" column="13" selection-start-line="9" selection-start-column="13" selection-end-line="9" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="800" max-vertical-offset="1305">
+ <caret line="9" column="13" selection-start-line="9" selection-start-column="13" selection-end-line="9" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/LevelMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="5100">
+ <caret line="304" column="41" selection-start-line="304" selection-start-column="41" selection-end-line="304" selection-end-column="41" />
+ <folding>
+ <element signature="e#10817#10818#0" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/LevelsMenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="1985" max-vertical-offset="6105">
+ <caret line="28" column="13" selection-start-line="28" selection-start-column="13" selection-end-line="28" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/Menu.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="22535" max-vertical-offset="23040">
+ <caret line="31" column="13" selection-start-line="31" selection-start-column="13" selection-end-line="31" selection-end-column="13" />
+ <folding>
+ <element signature="imports" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/MenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="390">
+ <caret line="7" column="17" selection-start-line="7" selection-start-column="17" selection-end-line="7" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/MenuElementOld.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="35" max-vertical-offset="540">
+ <caret line="6" column="17" selection-start-line="6" selection-start-column="17" selection-end-line="6" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/MenuHandler.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="270">
+ <caret line="2" column="17" selection-start-line="2" selection-start-column="17" selection-end-line="2" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/MenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3305" max-vertical-offset="3810">
+ <caret line="35" column="0" selection-start-line="35" selection-start-column="0" selection-end-line="35" selection-end-column="0" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/NameInputMenuScreen.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="2000" max-vertical-offset="2505">
+ <caret line="16" column="13" selection-start-line="16" selection-start-column="13" selection-end-line="16" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="240">
+ <caret line="5" column="17" selection-start-line="5" selection-start-column="17" selection-end-line="5" selection-end-column="17" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/OptionsMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3635" max-vertical-offset="4140">
+ <caret line="17" column="13" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/SimpleMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="1715" max-vertical-offset="2220">
+ <caret line="18" column="13" selection-start-line="18" selection-start-column="13" selection-end-line="18" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/SimpleMenuElementNew.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="710" max-vertical-offset="1215">
+ <caret line="4" column="13" selection-start-line="4" selection-start-column="13" selection-end-line="4" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/TextMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="560" max-vertical-offset="1065">
+ <caret line="17" column="13" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/HighScores.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="950" max-vertical-offset="2010">
+ <caret line="4" column="13" selection-start-line="4" selection-start-column="13" selection-end-line="4" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/Level.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="3120">
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/LevelsDataSource.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3480" max-vertical-offset="4275">
+ <caret line="14" column="13" selection-start-line="14" selection-start-column="13" selection-end-line="14" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/LevelsManager.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="5510" max-vertical-offset="6450">
+ <caret line="41" column="13" selection-start-line="41" selection-start-column="13" selection-end-line="41" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Storage/LevelsSQLiteOpenHelper.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="2085">
+ <caret line="6" column="13" selection-start-line="6" selection-start-column="13" selection-end-line="6" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Global.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="405">
+ <caret line="4" column="13" selection-start-line="4" selection-start-column="13" selection-end-line="4" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Settings.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="2760">
+ <caret line="92" column="13" selection-start-line="92" selection-start-column="13" selection-end-line="92" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/WaitForNetworkConnection.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="555">
+ <caret line="7" column="13" selection-start-line="7" selection-start-column="13" selection-end-line="7" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/KeyboardController.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="3815" max-vertical-offset="4320">
+ <caret line="96" column="29" selection-start-line="96" selection-start-column="29" selection-end-line="96" selection-end-column="29" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Helpers.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="335" max-vertical-offset="3645">
+ <caret line="21" column="13" selection-start-line="21" selection-start-column="13" selection-end-line="21" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="890" max-vertical-offset="1395">
+ <caret line="15" column="13" selection-start-line="15" selection-start-column="13" selection-end-line="15" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/LevelsAdapter.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="690">
+ <caret line="17" column="13" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="1215">
+ <caret line="13" column="13" selection-start-line="13" selection-start-column="13" selection-end-line="13" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/Menu/Views/ObservableScrollView.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="0" max-vertical-offset="480">
+ <caret line="5" column="13" selection-start-line="5" selection-start-column="13" selection-end-line="5" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/API.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="300" max-vertical-offset="1410">
+ <caret line="11" column="13" selection-start-line="11" selection-start-column="13" selection-end-line="11" selection-end-column="13" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/NotificationsResponse.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.0" vertical-offset="120" max-vertical-offset="945">
+ <caret line="10" column="22" selection-start-line="10" selection-start-column="22" selection-end-line="10" selection-end-column="22" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/org/happysanta/gd/API/Request.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state vertical-scroll-proportion="0.31512606" vertical-offset="0" max-vertical-offset="1935">
+ <caret line="28" column="19" selection-start-line="28" selection-start-column="19" selection-end-line="28" selection-end-column="19" />
+ <folding />
+ </state>
+ </provider>
+ </entry>
+ </component>
+ <component name="masterDetails">
+ <states>
+ <state key="ArtifactsStructureConfigurable.UI">
+ <settings>
+ <artifact-editor />
+ <last-edited>Gravity_Defied_Classic</last-edited>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ <option value="0.5" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ <state key="FacetStructureConfigurable.UI">
+ <settings>
+ <last-edited>Detection</last-edited>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ <state key="GlobalLibrariesConfigurable.UI">
+ <settings>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ <state key="JdkListConfigurable.UI">
+ <settings>
+ <last-edited>Android API 19 Platform (1)</last-edited>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ <state key="ModuleStructureConfigurable.UI">
+ <settings>
+ <last-edited>AGDTR</last-edited>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ <option value="0.6" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ <state key="ProjectJDKs.UI">
+ <settings>
+ <last-edited>1.7</last-edited>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ <state key="ProjectLibrariesConfigurable.UI">
+ <settings>
+ <last-edited>android-support-v4</last-edited>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ </states>
+ </component>
+</project> \ No newline at end of file
diff --git a/.project b/.project
new file mode 100755
index 0000000..f828f56
--- /dev/null
+++ b/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>AGDTR</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/AGDTR.iml b/AGDTR.iml
new file mode 100644
index 0000000..a138db1
--- /dev/null
+++ b/AGDTR.iml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+ <component name="FacetManager">
+ <facet type="android" name="Android">
+ <configuration />
+ </facet>
+ </component>
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+ </content>
+ <orderEntry type="jdk" jdkName="Android API 19 Platform (1)" jdkType="Android SDK" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" name="acra-4.5.0" level="project" />
+ <orderEntry type="library" name="android-support-v4" level="project" />
+ </component>
+</module>
+
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100755
index 0000000..737d563
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.happysanta.gd"
+ android:versionCode="29"
+ android:versionName="1.1.1">
+
+ <uses-sdk
+ android:minSdkVersion="8"
+ android:targetSdkVersion="19" />
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <application
+ android:allowBackup="true"
+ android:icon="@drawable/icon"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme"
+ android:hardwareAccelerated="true"
+ android:name=".GDApplication">
+ <activity
+ android:name=".GDActivity"
+ android:label="@string/app_name"
+ android:screenOrientation="portrait"
+ android:configChanges="keyboardHidden"
+ android:launchMode="singleInstance">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..67cecec
--- /dev/null
+++ b/README.md
@@ -0,0 +1,27 @@
+# Gravity Defied – Android port
+**Gravity Defied** is an iconic trial racing mobile game. It was originally developed by Codebrew Software in 2004 for J2ME platform.
+
+Codebrew has launched an Android version of the game in 2012, though it was totally remade. We are the ones who like classic version of Gravity Defied more, so we ported it to Android almost unchanged!
+
+This port includes all features of the original Gravity Defied. In addition, we have collected more than 1000 levels mods made by fans since 2007. You can install any mod and switch between mods directly from the game menu.
+
+***We are not associated with Codebrew Software in any fashion. All rights to the original Gravity Defied, it's name, logotype, brand and all that stuff belongs to Codebrew Software.***
+
+# Download
+You can download the last version from:
+
+* [Google Play](https://play.google.com/store/apps/details?id=org.happysanta.gd). Please note, that this (package name *org.happysanta.gd*) is **the only real** Gravity Defied at Google Play, and it's ads-free. Previously it has package name *com.ch1p.gd*, but unfortunately my developer account was suspended due to USA Crimea-related sanctions and the game with almost 1 million downloads disappeared from Google Play.
+* Our official site [gdtr.net](http://gdtr.net)
+
+# Authors
+### Port authors
+**[Gregory Klushnikov](https://vk.com/grishka)** - idea and the original J2ME to Android port.
+**[Evgeny Zinoviev](https://vk.com/ez)** - porting/levels manager/levels API/graphics/everything else development, graphics.
+
+### Codebrew GDTR Authors
+**Tors Björn Henrik Johansson** - system/game logic/interface, testing, levels design
+**Set Elis Norman** - graphics/physics/mathematics/system/tools programming, levels design
+**Per David Jacobsson** - physics programming, game graphics, levels design
+
+For more information, please visit official site of Codebrew Software: [codebrew.se](http://codebrew.se)
+
diff --git a/assets/RobotoCondensed-Regular.ttf b/assets/RobotoCondensed-Regular.ttf
new file mode 100755
index 0000000..713fd30
--- /dev/null
+++ b/assets/RobotoCondensed-Regular.ttf
Binary files differ
diff --git a/assets/levels.mrg b/assets/levels.mrg
new file mode 100755
index 0000000..e495c2a
--- /dev/null
+++ b/assets/levels.mrg
Binary files differ
diff --git a/libs/acra-4.5.0.jar b/libs/acra-4.5.0.jar
new file mode 100644
index 0000000..81d8cd0
--- /dev/null
+++ b/libs/acra-4.5.0.jar
Binary files differ
diff --git a/proguard-project.txt b/proguard-project.txt
new file mode 100755
index 0000000..f2fe155
--- /dev/null
+++ b/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/project.properties b/project.properties
new file mode 100755
index 0000000..4ab1256
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-19
diff --git a/psd/drawables/drawable-hdpi/flag_h.psd b/psd/drawables/drawable-hdpi/flag_h.psd
new file mode 100755
index 0000000..da067f2
--- /dev/null
+++ b/psd/drawables/drawable-hdpi/flag_h.psd
Binary files differ
diff --git a/psd/drawables/drawable-hdpi/helmet.psd b/psd/drawables/drawable-hdpi/helmet.psd
new file mode 100755
index 0000000..25807cc
--- /dev/null
+++ b/psd/drawables/drawable-hdpi/helmet.psd
Binary files differ
diff --git a/psd/drawables/drawable-hdpi/ic_downloaded.psd b/psd/drawables/drawable-hdpi/ic_downloaded.psd
new file mode 100644
index 0000000..f8b0ee9
--- /dev/null
+++ b/psd/drawables/drawable-hdpi/ic_downloaded.psd
Binary files differ
diff --git a/psd/drawables/drawable-hdpi/ic_menu_down.psd b/psd/drawables/drawable-hdpi/ic_menu_down.psd
new file mode 100644
index 0000000..ee4ec2b
--- /dev/null
+++ b/psd/drawables/drawable-hdpi/ic_menu_down.psd
Binary files differ
diff --git a/psd/drawables/drawable-hdpi/ic_menu_up.psd b/psd/drawables/drawable-hdpi/ic_menu_up.psd
new file mode 100644
index 0000000..45954b5
--- /dev/null
+++ b/psd/drawables/drawable-hdpi/ic_menu_up.psd
Binary files differ
diff --git a/psd/drawables/drawable-hdpi/ic_sort.psd b/psd/drawables/drawable-hdpi/ic_sort.psd
new file mode 100644
index 0000000..0ac55aa
--- /dev/null
+++ b/psd/drawables/drawable-hdpi/ic_sort.psd
Binary files differ
diff --git a/psd/drawables/drawable-mdpi/ic_downloaded.psd b/psd/drawables/drawable-mdpi/ic_downloaded.psd
new file mode 100644
index 0000000..fc23606
--- /dev/null
+++ b/psd/drawables/drawable-mdpi/ic_downloaded.psd
Binary files differ
diff --git a/psd/drawables/drawable-mdpi/ic_menu_down.psd b/psd/drawables/drawable-mdpi/ic_menu_down.psd
new file mode 100644
index 0000000..df1acf6
--- /dev/null
+++ b/psd/drawables/drawable-mdpi/ic_menu_down.psd
Binary files differ
diff --git a/psd/drawables/drawable-mdpi/ic_menu_up.psd b/psd/drawables/drawable-mdpi/ic_menu_up.psd
new file mode 100644
index 0000000..27f4713
--- /dev/null
+++ b/psd/drawables/drawable-mdpi/ic_menu_up.psd
Binary files differ
diff --git a/psd/drawables/drawable-mdpi/ic_sort.psd b/psd/drawables/drawable-mdpi/ic_sort.psd
new file mode 100644
index 0000000..2b5cdd1
--- /dev/null
+++ b/psd/drawables/drawable-mdpi/ic_sort.psd
Binary files differ
diff --git a/psd/drawables/drawable-mdpi/s_flag_mdpi.psd b/psd/drawables/drawable-mdpi/s_flag_mdpi.psd
new file mode 100755
index 0000000..cf7f2b6
--- /dev/null
+++ b/psd/drawables/drawable-mdpi/s_flag_mdpi.psd
Binary files differ
diff --git a/psd/drawables/drawable-mdpi/s_lock_mdpi.psd b/psd/drawables/drawable-mdpi/s_lock_mdpi.psd
new file mode 100755
index 0000000..d92c79d
--- /dev/null
+++ b/psd/drawables/drawable-mdpi/s_lock_mdpi.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/bluearm.psd b/psd/drawables/drawable-xhdpi/bluearm.psd
new file mode 100755
index 0000000..186eb66
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/bluearm.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/bluebody.psd b/psd/drawables/drawable-xhdpi/bluebody.psd
new file mode 100755
index 0000000..3c67ac3
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/bluebody.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/blueleg.psd b/psd/drawables/drawable-xhdpi/blueleg.psd
new file mode 100755
index 0000000..05a3c89
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/blueleg.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/btn_bottom_left.psd b/psd/drawables/drawable-xhdpi/btn_bottom_left.psd
new file mode 100755
index 0000000..442ead3
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/btn_bottom_left.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/btn_bottom_right.psd b/psd/drawables/drawable-xhdpi/btn_bottom_right.psd
new file mode 100755
index 0000000..9d9cb04
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/btn_bottom_right.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/btn_left_right.psd b/psd/drawables/drawable-xhdpi/btn_left_right.psd
new file mode 100755
index 0000000..fa7f0a1
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/btn_left_right.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/btn_middle.psd b/psd/drawables/drawable-xhdpi/btn_middle.psd
new file mode 100755
index 0000000..1b009e1
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/btn_middle.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/btn_top_bottom_middle.psd b/psd/drawables/drawable-xhdpi/btn_top_bottom_middle.psd
new file mode 100755
index 0000000..a1d331a
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/btn_top_bottom_middle.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/btn_top_left.psd b/psd/drawables/drawable-xhdpi/btn_top_left.psd
new file mode 100755
index 0000000..b596983
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/btn_top_left.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/btn_top_right.psd b/psd/drawables/drawable-xhdpi/btn_top_right.psd
new file mode 100755
index 0000000..5114d0c
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/btn_top_right.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/engine.psd b/psd/drawables/drawable-xhdpi/engine.psd
new file mode 100755
index 0000000..2c2f603
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/engine.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/engine_hdpi.psd b/psd/drawables/drawable-xhdpi/engine_hdpi.psd
new file mode 100755
index 0000000..e3238e4
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/engine_hdpi.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/engine_xx.psd b/psd/drawables/drawable-xhdpi/engine_xx.psd
new file mode 100755
index 0000000..c015101
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/engine_xx.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/fender.psd b/psd/drawables/drawable-xhdpi/fender.psd
new file mode 100755
index 0000000..da0cda0
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/fender.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/fender_hdpi.psd b/psd/drawables/drawable-xhdpi/fender_hdpi.psd
new file mode 100755
index 0000000..4b48f78
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/fender_hdpi.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/flag.psd b/psd/drawables/drawable-xhdpi/flag.psd
new file mode 100755
index 0000000..e79ea3e
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/flag.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/helmet1.psd b/psd/drawables/drawable-xhdpi/helmet1.psd
new file mode 100755
index 0000000..5af538d
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/helmet1.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/ic_downloaded.psd b/psd/drawables/drawable-xhdpi/ic_downloaded.psd
new file mode 100644
index 0000000..4fad0f8
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/ic_downloaded.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/ic_menu_down.psd b/psd/drawables/drawable-xhdpi/ic_menu_down.psd
new file mode 100644
index 0000000..40dfdfb
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/ic_menu_down.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/ic_menu_up.psd b/psd/drawables/drawable-xhdpi/ic_menu_up.psd
new file mode 100644
index 0000000..fa7e51c
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/ic_menu_up.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/ic_sort.psd b/psd/drawables/drawable-xhdpi/ic_sort.psd
new file mode 100644
index 0000000..4e74b2c
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/ic_sort.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/lock.psd b/psd/drawables/drawable-xhdpi/lock.psd
new file mode 100755
index 0000000..9ae2b21
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/lock.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/medal.psd b/psd/drawables/drawable-xhdpi/medal.psd
new file mode 100755
index 0000000..fdb3c39
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/medal.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/s_arrow_down.psd b/psd/drawables/drawable-xhdpi/s_arrow_down.psd
new file mode 100755
index 0000000..07874d1
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/s_arrow_down.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/s_arrow_up.psd b/psd/drawables/drawable-xhdpi/s_arrow_up.psd
new file mode 100755
index 0000000..b4e0a29
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/s_arrow_up.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/s_steering.psd b/psd/drawables/drawable-xhdpi/s_steering.psd
new file mode 100755
index 0000000..be955e4
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/s_steering.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/wheel1.psd b/psd/drawables/drawable-xhdpi/wheel1.psd
new file mode 100755
index 0000000..39d48ec
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/wheel1.psd
Binary files differ
diff --git a/psd/drawables/drawable-xhdpi/wheel_1x.psd b/psd/drawables/drawable-xhdpi/wheel_1x.psd
new file mode 100755
index 0000000..402f681
--- /dev/null
+++ b/psd/drawables/drawable-xhdpi/wheel_1x.psd
Binary files differ
diff --git a/psd/drawables/drawable-xxhdpi/flag_xxh.psd b/psd/drawables/drawable-xxhdpi/flag_xxh.psd
new file mode 100755
index 0000000..7415f8d
--- /dev/null
+++ b/psd/drawables/drawable-xxhdpi/flag_xxh.psd
Binary files differ
diff --git a/psd/drawables/drawable-xxhdpi/helmet1.psd b/psd/drawables/drawable-xxhdpi/helmet1.psd
new file mode 100755
index 0000000..b7aab39
--- /dev/null
+++ b/psd/drawables/drawable-xxhdpi/helmet1.psd
Binary files differ
diff --git a/psd/drawables/drawable-xxhdpi/ic_downloaded.psd b/psd/drawables/drawable-xxhdpi/ic_downloaded.psd
new file mode 100644
index 0000000..32c0ed2
--- /dev/null
+++ b/psd/drawables/drawable-xxhdpi/ic_downloaded.psd
Binary files differ
diff --git a/psd/drawables/drawable-xxhdpi/ic_menu_down.psd b/psd/drawables/drawable-xxhdpi/ic_menu_down.psd
new file mode 100644
index 0000000..27b6986
--- /dev/null
+++ b/psd/drawables/drawable-xxhdpi/ic_menu_down.psd
Binary files differ
diff --git a/psd/drawables/drawable-xxhdpi/ic_menu_up.psd b/psd/drawables/drawable-xxhdpi/ic_menu_up.psd
new file mode 100644
index 0000000..3f244d7
--- /dev/null
+++ b/psd/drawables/drawable-xxhdpi/ic_menu_up.psd
Binary files differ
diff --git a/psd/drawables/drawable-xxhdpi/ic_sort.psd b/psd/drawables/drawable-xxhdpi/ic_sort.psd
new file mode 100644
index 0000000..2dae8b9
--- /dev/null
+++ b/psd/drawables/drawable-xxhdpi/ic_sort.psd
Binary files differ
diff --git a/psd/drawables/drawable-xxhdpi/medal_xx.psd b/psd/drawables/drawable-xxhdpi/medal_xx.psd
new file mode 100755
index 0000000..7b5175a
--- /dev/null
+++ b/psd/drawables/drawable-xxhdpi/medal_xx.psd
Binary files differ
diff --git a/psd/icon/icon_512.psd b/psd/icon/icon_512.psd
new file mode 100644
index 0000000..983d370
--- /dev/null
+++ b/psd/icon/icon_512.psd
Binary files differ
diff --git a/psd/icon/icon_hdpi.psd b/psd/icon/icon_hdpi.psd
new file mode 100644
index 0000000..f8e88c6
--- /dev/null
+++ b/psd/icon/icon_hdpi.psd
Binary files differ
diff --git a/psd/icon/icon_mdpi.psd b/psd/icon/icon_mdpi.psd
new file mode 100644
index 0000000..09788de
--- /dev/null
+++ b/psd/icon/icon_mdpi.psd
Binary files differ
diff --git a/psd/icon/icon_xhdpi.psd b/psd/icon/icon_xhdpi.psd
new file mode 100644
index 0000000..5640b8f
--- /dev/null
+++ b/psd/icon/icon_xhdpi.psd
Binary files differ
diff --git a/psd/icon/icon_xxhdpi.psd b/psd/icon/icon_xxhdpi.psd
new file mode 100644
index 0000000..22b5fe9
--- /dev/null
+++ b/psd/icon/icon_xxhdpi.psd
Binary files differ
diff --git a/psd/icon/icon_xxxhdpi.psd b/psd/icon/icon_xxxhdpi.psd
new file mode 100644
index 0000000..fa6caa5
--- /dev/null
+++ b/psd/icon/icon_xxxhdpi.psd
Binary files differ
diff --git a/res/drawable-hdpi/btn_b_down.9.png b/res/drawable-hdpi/btn_b_down.9.png
new file mode 100755
index 0000000..57e53cc
--- /dev/null
+++ b/res/drawable-hdpi/btn_b_down.9.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_b_up.9.png b/res/drawable-hdpi/btn_b_up.9.png
new file mode 100755
index 0000000..c1304e9
--- /dev/null
+++ b/res/drawable-hdpi/btn_b_up.9.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_br_down.9.png b/res/drawable-hdpi/btn_br_down.9.png
new file mode 100755
index 0000000..19df859
--- /dev/null
+++ b/res/drawable-hdpi/btn_br_down.9.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_br_up.9.png b/res/drawable-hdpi/btn_br_up.9.png
new file mode 100755
index 0000000..7308e2c
--- /dev/null
+++ b/res/drawable-hdpi/btn_br_up.9.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_n_down.9.png b/res/drawable-hdpi/btn_n_down.9.png
new file mode 100755
index 0000000..c0a17ce
--- /dev/null
+++ b/res/drawable-hdpi/btn_n_down.9.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_n_up.9.png b/res/drawable-hdpi/btn_n_up.9.png
new file mode 100755
index 0000000..c27d0d5
--- /dev/null
+++ b/res/drawable-hdpi/btn_n_up.9.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_r_down.9.png b/res/drawable-hdpi/btn_r_down.9.png
new file mode 100755
index 0000000..7c55b6d
--- /dev/null
+++ b/res/drawable-hdpi/btn_r_down.9.png
Binary files differ
diff --git a/res/drawable-hdpi/btn_r_up.9.png b/res/drawable-hdpi/btn_r_up.9.png
new file mode 100755
index 0000000..6ac30d9
--- /dev/null
+++ b/res/drawable-hdpi/btn_r_up.9.png
Binary files differ
diff --git a/res/drawable-hdpi/codebrew.png b/res/drawable-hdpi/codebrew.png
new file mode 100755
index 0000000..a6b9f38
--- /dev/null
+++ b/res/drawable-hdpi/codebrew.png
Binary files differ
diff --git a/res/drawable-hdpi/gd.png b/res/drawable-hdpi/gd.png
new file mode 100755
index 0000000..6e7d883
--- /dev/null
+++ b/res/drawable-hdpi/gd.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_downloaded.png b/res/drawable-hdpi/ic_downloaded.png
new file mode 100644
index 0000000..0628b7e
--- /dev/null
+++ b/res/drawable-hdpi/ic_downloaded.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_downloaded_selected.png b/res/drawable-hdpi/ic_downloaded_selected.png
new file mode 100644
index 0000000..f6c4079
--- /dev/null
+++ b/res/drawable-hdpi/ic_downloaded_selected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_installed.png b/res/drawable-hdpi/ic_installed.png
new file mode 100644
index 0000000..3a0880d
--- /dev/null
+++ b/res/drawable-hdpi/ic_installed.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_installed_selected.png b/res/drawable-hdpi/ic_installed_selected.png
new file mode 100644
index 0000000..3a0880d
--- /dev/null
+++ b/res/drawable-hdpi/ic_installed_selected.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..96a442e
--- /dev/null
+++ b/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_down.png b/res/drawable-hdpi/ic_menu_down.png
new file mode 100755
index 0000000..5b42c4b
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_down.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_menu_up.png b/res/drawable-hdpi/ic_menu_up.png
new file mode 100755
index 0000000..01c9e81
--- /dev/null
+++ b/res/drawable-hdpi/ic_menu_up.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_sort_down.png b/res/drawable-hdpi/ic_sort_down.png
new file mode 100644
index 0000000..d121018
--- /dev/null
+++ b/res/drawable-hdpi/ic_sort_down.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_sort_up.png b/res/drawable-hdpi/ic_sort_up.png
new file mode 100644
index 0000000..6546b4f
--- /dev/null
+++ b/res/drawable-hdpi/ic_sort_up.png
Binary files differ
diff --git a/res/drawable-hdpi/icon.png b/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..99f917e
--- /dev/null
+++ b/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/res/drawable-hdpi/levels_wheel0.png b/res/drawable-hdpi/levels_wheel0.png
new file mode 100755
index 0000000..d68bb36
--- /dev/null
+++ b/res/drawable-hdpi/levels_wheel0.png
Binary files differ
diff --git a/res/drawable-hdpi/levels_wheel1.png b/res/drawable-hdpi/levels_wheel1.png
new file mode 100755
index 0000000..3a1a638
--- /dev/null
+++ b/res/drawable-hdpi/levels_wheel1.png
Binary files differ
diff --git a/res/drawable-hdpi/levels_wheel2.png b/res/drawable-hdpi/levels_wheel2.png
new file mode 100755
index 0000000..ae5bb08
--- /dev/null
+++ b/res/drawable-hdpi/levels_wheel2.png
Binary files differ
diff --git a/res/drawable-hdpi/s_arrow_down.png b/res/drawable-hdpi/s_arrow_down.png
new file mode 100755
index 0000000..456bf38
--- /dev/null
+++ b/res/drawable-hdpi/s_arrow_down.png
Binary files differ
diff --git a/res/drawable-hdpi/s_arrow_up.png b/res/drawable-hdpi/s_arrow_up.png
new file mode 100755
index 0000000..b529873
--- /dev/null
+++ b/res/drawable-hdpi/s_arrow_up.png
Binary files differ
diff --git a/res/drawable-hdpi/s_bluearm.png b/res/drawable-hdpi/s_bluearm.png
new file mode 100755
index 0000000..a09323e
--- /dev/null
+++ b/res/drawable-hdpi/s_bluearm.png
Binary files differ
diff --git a/res/drawable-hdpi/s_bluebody.png b/res/drawable-hdpi/s_bluebody.png
new file mode 100755
index 0000000..8a5241b
--- /dev/null
+++ b/res/drawable-hdpi/s_bluebody.png
Binary files differ
diff --git a/res/drawable-hdpi/s_blueleg.png b/res/drawable-hdpi/s_blueleg.png
new file mode 100755
index 0000000..2a1923a
--- /dev/null
+++ b/res/drawable-hdpi/s_blueleg.png
Binary files differ
diff --git a/res/drawable-hdpi/s_engine.png b/res/drawable-hdpi/s_engine.png
new file mode 100755
index 0000000..12e94db
--- /dev/null
+++ b/res/drawable-hdpi/s_engine.png
Binary files differ
diff --git a/res/drawable-hdpi/s_fender.png b/res/drawable-hdpi/s_fender.png
new file mode 100755
index 0000000..5ddef54
--- /dev/null
+++ b/res/drawable-hdpi/s_fender.png
Binary files differ
diff --git a/res/drawable-hdpi/s_flag_finish0.png b/res/drawable-hdpi/s_flag_finish0.png
new file mode 100755
index 0000000..a0acc28
--- /dev/null
+++ b/res/drawable-hdpi/s_flag_finish0.png
Binary files differ
diff --git a/res/drawable-hdpi/s_flag_finish1.png b/res/drawable-hdpi/s_flag_finish1.png
new file mode 100755
index 0000000..204fc15
--- /dev/null
+++ b/res/drawable-hdpi/s_flag_finish1.png
Binary files differ
diff --git a/res/drawable-hdpi/s_flag_finish2.png b/res/drawable-hdpi/s_flag_finish2.png
new file mode 100755
index 0000000..899f700
--- /dev/null
+++ b/res/drawable-hdpi/s_flag_finish2.png
Binary files differ
diff --git a/res/drawable-hdpi/s_flag_start0.png b/res/drawable-hdpi/s_flag_start0.png
new file mode 100755
index 0000000..3f2aa12
--- /dev/null
+++ b/res/drawable-hdpi/s_flag_start0.png
Binary files differ
diff --git a/res/drawable-hdpi/s_flag_start1.png b/res/drawable-hdpi/s_flag_start1.png
new file mode 100755
index 0000000..5caaddc
--- /dev/null
+++ b/res/drawable-hdpi/s_flag_start1.png
Binary files differ
diff --git a/res/drawable-hdpi/s_flag_start2.png b/res/drawable-hdpi/s_flag_start2.png
new file mode 100755
index 0000000..0ef4e81
--- /dev/null
+++ b/res/drawable-hdpi/s_flag_start2.png
Binary files differ
diff --git a/res/drawable-hdpi/s_helmet.png b/res/drawable-hdpi/s_helmet.png
new file mode 100755
index 0000000..c6b728b
--- /dev/null
+++ b/res/drawable-hdpi/s_helmet.png
Binary files differ
diff --git a/res/drawable-hdpi/s_lock0.png b/res/drawable-hdpi/s_lock0.png
new file mode 100755
index 0000000..6750eb7
--- /dev/null
+++ b/res/drawable-hdpi/s_lock0.png
Binary files differ
diff --git a/res/drawable-hdpi/s_lock1.png b/res/drawable-hdpi/s_lock1.png
new file mode 100755
index 0000000..6187ff7
--- /dev/null
+++ b/res/drawable-hdpi/s_lock1.png
Binary files differ
diff --git a/res/drawable-hdpi/s_lock2.png b/res/drawable-hdpi/s_lock2.png
new file mode 100755
index 0000000..9e3313f
--- /dev/null
+++ b/res/drawable-hdpi/s_lock2.png
Binary files differ
diff --git a/res/drawable-hdpi/s_medal_bronze.png b/res/drawable-hdpi/s_medal_bronze.png
new file mode 100755
index 0000000..c092f3e
--- /dev/null
+++ b/res/drawable-hdpi/s_medal_bronze.png
Binary files differ
diff --git a/res/drawable-hdpi/s_medal_gold.png b/res/drawable-hdpi/s_medal_gold.png
new file mode 100755
index 0000000..fab2932
--- /dev/null
+++ b/res/drawable-hdpi/s_medal_gold.png
Binary files differ
diff --git a/res/drawable-hdpi/s_medal_silver.png b/res/drawable-hdpi/s_medal_silver.png
new file mode 100755
index 0000000..1d46358
--- /dev/null
+++ b/res/drawable-hdpi/s_medal_silver.png
Binary files differ
diff --git a/res/drawable-hdpi/s_steering.png b/res/drawable-hdpi/s_steering.png
new file mode 100755
index 0000000..32aa001
--- /dev/null
+++ b/res/drawable-hdpi/s_steering.png
Binary files differ
diff --git a/res/drawable-hdpi/s_wheel1.png b/res/drawable-hdpi/s_wheel1.png
new file mode 100755
index 0000000..8812bf8
--- /dev/null
+++ b/res/drawable-hdpi/s_wheel1.png
Binary files differ
diff --git a/res/drawable-hdpi/s_wheel2.png b/res/drawable-hdpi/s_wheel2.png
new file mode 100755
index 0000000..08ca382
--- /dev/null
+++ b/res/drawable-hdpi/s_wheel2.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_b_down.9.png b/res/drawable-mdpi/btn_b_down.9.png
new file mode 100755
index 0000000..10246bd
--- /dev/null
+++ b/res/drawable-mdpi/btn_b_down.9.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_b_up.9.png b/res/drawable-mdpi/btn_b_up.9.png
new file mode 100755
index 0000000..994e065
--- /dev/null
+++ b/res/drawable-mdpi/btn_b_up.9.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_br_down.9.png b/res/drawable-mdpi/btn_br_down.9.png
new file mode 100755
index 0000000..bb787a1
--- /dev/null
+++ b/res/drawable-mdpi/btn_br_down.9.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_br_up.9.png b/res/drawable-mdpi/btn_br_up.9.png
new file mode 100755
index 0000000..166a816
--- /dev/null
+++ b/res/drawable-mdpi/btn_br_up.9.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_n_down.9.png b/res/drawable-mdpi/btn_n_down.9.png
new file mode 100755
index 0000000..feb0d4a
--- /dev/null
+++ b/res/drawable-mdpi/btn_n_down.9.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_n_up.9.png b/res/drawable-mdpi/btn_n_up.9.png
new file mode 100755
index 0000000..0fb595d
--- /dev/null
+++ b/res/drawable-mdpi/btn_n_up.9.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_r_down.9.png b/res/drawable-mdpi/btn_r_down.9.png
new file mode 100755
index 0000000..99f3109
--- /dev/null
+++ b/res/drawable-mdpi/btn_r_down.9.png
Binary files differ
diff --git a/res/drawable-mdpi/btn_r_up.9.png b/res/drawable-mdpi/btn_r_up.9.png
new file mode 100755
index 0000000..6004172
--- /dev/null
+++ b/res/drawable-mdpi/btn_r_up.9.png
Binary files differ
diff --git a/res/drawable-mdpi/codebrew.png b/res/drawable-mdpi/codebrew.png
new file mode 100755
index 0000000..5e46ad2
--- /dev/null
+++ b/res/drawable-mdpi/codebrew.png
Binary files differ
diff --git a/res/drawable-mdpi/gd.png b/res/drawable-mdpi/gd.png
new file mode 100755
index 0000000..1ad92b5
--- /dev/null
+++ b/res/drawable-mdpi/gd.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_downloaded.png b/res/drawable-mdpi/ic_downloaded.png
new file mode 100644
index 0000000..b61fcb1
--- /dev/null
+++ b/res/drawable-mdpi/ic_downloaded.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_downloaded_selected.png b/res/drawable-mdpi/ic_downloaded_selected.png
new file mode 100644
index 0000000..d11cb91
--- /dev/null
+++ b/res/drawable-mdpi/ic_downloaded_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_installed.png b/res/drawable-mdpi/ic_installed.png
new file mode 100644
index 0000000..be79bf9
--- /dev/null
+++ b/res/drawable-mdpi/ic_installed.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_installed_selected.png b/res/drawable-mdpi/ic_installed_selected.png
new file mode 100644
index 0000000..fb14899
--- /dev/null
+++ b/res/drawable-mdpi/ic_installed_selected.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..359047d
--- /dev/null
+++ b/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_down.png b/res/drawable-mdpi/ic_menu_down.png
new file mode 100755
index 0000000..8e81039
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_down.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_menu_up.png b/res/drawable-mdpi/ic_menu_up.png
new file mode 100755
index 0000000..102f9d0
--- /dev/null
+++ b/res/drawable-mdpi/ic_menu_up.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_sort_down.png b/res/drawable-mdpi/ic_sort_down.png
new file mode 100644
index 0000000..7fa1bc5
--- /dev/null
+++ b/res/drawable-mdpi/ic_sort_down.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_sort_up.png b/res/drawable-mdpi/ic_sort_up.png
new file mode 100644
index 0000000..f2be63f
--- /dev/null
+++ b/res/drawable-mdpi/ic_sort_up.png
Binary files differ
diff --git a/res/drawable-mdpi/icon.png b/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..570f8a7
--- /dev/null
+++ b/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/res/drawable-mdpi/levels_wheel0.png b/res/drawable-mdpi/levels_wheel0.png
new file mode 100755
index 0000000..89c03a4
--- /dev/null
+++ b/res/drawable-mdpi/levels_wheel0.png
Binary files differ
diff --git a/res/drawable-mdpi/levels_wheel1.png b/res/drawable-mdpi/levels_wheel1.png
new file mode 100755
index 0000000..42fe489
--- /dev/null
+++ b/res/drawable-mdpi/levels_wheel1.png
Binary files differ
diff --git a/res/drawable-mdpi/levels_wheel2.png b/res/drawable-mdpi/levels_wheel2.png
new file mode 100755
index 0000000..7e4f1a4
--- /dev/null
+++ b/res/drawable-mdpi/levels_wheel2.png
Binary files differ
diff --git a/res/drawable-mdpi/s_arrow_down.png b/res/drawable-mdpi/s_arrow_down.png
new file mode 100755
index 0000000..2dccc77
--- /dev/null
+++ b/res/drawable-mdpi/s_arrow_down.png
Binary files differ
diff --git a/res/drawable-mdpi/s_arrow_up.png b/res/drawable-mdpi/s_arrow_up.png
new file mode 100755
index 0000000..ebfe3ee
--- /dev/null
+++ b/res/drawable-mdpi/s_arrow_up.png
Binary files differ
diff --git a/res/drawable-mdpi/s_bluearm.png b/res/drawable-mdpi/s_bluearm.png
new file mode 100755
index 0000000..651c0e5
--- /dev/null
+++ b/res/drawable-mdpi/s_bluearm.png
Binary files differ
diff --git a/res/drawable-mdpi/s_bluebody.png b/res/drawable-mdpi/s_bluebody.png
new file mode 100755
index 0000000..4075175
--- /dev/null
+++ b/res/drawable-mdpi/s_bluebody.png
Binary files differ
diff --git a/res/drawable-mdpi/s_blueleg.png b/res/drawable-mdpi/s_blueleg.png
new file mode 100755
index 0000000..081b341
--- /dev/null
+++ b/res/drawable-mdpi/s_blueleg.png
Binary files differ
diff --git a/res/drawable-mdpi/s_engine.png b/res/drawable-mdpi/s_engine.png
new file mode 100755
index 0000000..9d6846d
--- /dev/null
+++ b/res/drawable-mdpi/s_engine.png
Binary files differ
diff --git a/res/drawable-mdpi/s_fender.png b/res/drawable-mdpi/s_fender.png
new file mode 100755
index 0000000..f4abce0
--- /dev/null
+++ b/res/drawable-mdpi/s_fender.png
Binary files differ
diff --git a/res/drawable-mdpi/s_flag_finish0.png b/res/drawable-mdpi/s_flag_finish0.png
new file mode 100755
index 0000000..a973627
--- /dev/null
+++ b/res/drawable-mdpi/s_flag_finish0.png
Binary files differ
diff --git a/res/drawable-mdpi/s_flag_finish1.png b/res/drawable-mdpi/s_flag_finish1.png
new file mode 100755
index 0000000..16a8dc1
--- /dev/null
+++ b/res/drawable-mdpi/s_flag_finish1.png
Binary files differ
diff --git a/res/drawable-mdpi/s_flag_finish2.png b/res/drawable-mdpi/s_flag_finish2.png
new file mode 100755
index 0000000..b20115d
--- /dev/null
+++ b/res/drawable-mdpi/s_flag_finish2.png
Binary files differ
diff --git a/res/drawable-mdpi/s_flag_start0.png b/res/drawable-mdpi/s_flag_start0.png
new file mode 100755
index 0000000..132a136
--- /dev/null
+++ b/res/drawable-mdpi/s_flag_start0.png
Binary files differ
diff --git a/res/drawable-mdpi/s_flag_start1.png b/res/drawable-mdpi/s_flag_start1.png
new file mode 100755
index 0000000..c97e652
--- /dev/null
+++ b/res/drawable-mdpi/s_flag_start1.png
Binary files differ
diff --git a/res/drawable-mdpi/s_flag_start2.png b/res/drawable-mdpi/s_flag_start2.png
new file mode 100755
index 0000000..89f8eb5
--- /dev/null
+++ b/res/drawable-mdpi/s_flag_start2.png
Binary files differ
diff --git a/res/drawable-mdpi/s_helmet.png b/res/drawable-mdpi/s_helmet.png
new file mode 100755
index 0000000..81c303c
--- /dev/null
+++ b/res/drawable-mdpi/s_helmet.png
Binary files differ
diff --git a/res/drawable-mdpi/s_lock0.png b/res/drawable-mdpi/s_lock0.png
new file mode 100755
index 0000000..e76031e
--- /dev/null
+++ b/res/drawable-mdpi/s_lock0.png
Binary files differ
diff --git a/res/drawable-mdpi/s_lock1.png b/res/drawable-mdpi/s_lock1.png
new file mode 100755
index 0000000..0610fa1
--- /dev/null
+++ b/res/drawable-mdpi/s_lock1.png
Binary files differ
diff --git a/res/drawable-mdpi/s_lock2.png b/res/drawable-mdpi/s_lock2.png
new file mode 100755
index 0000000..3d9bd9b
--- /dev/null
+++ b/res/drawable-mdpi/s_lock2.png
Binary files differ
diff --git a/res/drawable-mdpi/s_medal_bronze.png b/res/drawable-mdpi/s_medal_bronze.png
new file mode 100755
index 0000000..d8a533d
--- /dev/null
+++ b/res/drawable-mdpi/s_medal_bronze.png
Binary files differ
diff --git a/res/drawable-mdpi/s_medal_gold.png b/res/drawable-mdpi/s_medal_gold.png
new file mode 100755
index 0000000..e4d546f
--- /dev/null
+++ b/res/drawable-mdpi/s_medal_gold.png
Binary files differ
diff --git a/res/drawable-mdpi/s_medal_silver.png b/res/drawable-mdpi/s_medal_silver.png
new file mode 100755
index 0000000..19046d6
--- /dev/null
+++ b/res/drawable-mdpi/s_medal_silver.png
Binary files differ
diff --git a/res/drawable-mdpi/s_wheel1.png b/res/drawable-mdpi/s_wheel1.png
new file mode 100755
index 0000000..3c19f2c
--- /dev/null
+++ b/res/drawable-mdpi/s_wheel1.png
Binary files differ
diff --git a/res/drawable-mdpi/s_wheel2.png b/res/drawable-mdpi/s_wheel2.png
new file mode 100755
index 0000000..50c4168
--- /dev/null
+++ b/res/drawable-mdpi/s_wheel2.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_b_down.9.png b/res/drawable-xhdpi/btn_b_down.9.png
new file mode 100755
index 0000000..92a3505
--- /dev/null
+++ b/res/drawable-xhdpi/btn_b_down.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_b_up.9.png b/res/drawable-xhdpi/btn_b_up.9.png
new file mode 100755
index 0000000..ab7ead4
--- /dev/null
+++ b/res/drawable-xhdpi/btn_b_up.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_br_down.9.png b/res/drawable-xhdpi/btn_br_down.9.png
new file mode 100755
index 0000000..09c1576
--- /dev/null
+++ b/res/drawable-xhdpi/btn_br_down.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_br_up.9.png b/res/drawable-xhdpi/btn_br_up.9.png
new file mode 100755
index 0000000..a8d3bb7
--- /dev/null
+++ b/res/drawable-xhdpi/btn_br_up.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_n_down.9.png b/res/drawable-xhdpi/btn_n_down.9.png
new file mode 100755
index 0000000..66fe3d9
--- /dev/null
+++ b/res/drawable-xhdpi/btn_n_down.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_n_up.9.png b/res/drawable-xhdpi/btn_n_up.9.png
new file mode 100755
index 0000000..cf89db9
--- /dev/null
+++ b/res/drawable-xhdpi/btn_n_up.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_r_down.9.png b/res/drawable-xhdpi/btn_r_down.9.png
new file mode 100755
index 0000000..d69ebf5
--- /dev/null
+++ b/res/drawable-xhdpi/btn_r_down.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/btn_r_up.9.png b/res/drawable-xhdpi/btn_r_up.9.png
new file mode 100755
index 0000000..3876775
--- /dev/null
+++ b/res/drawable-xhdpi/btn_r_up.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/codebrew.png b/res/drawable-xhdpi/codebrew.png
new file mode 100755
index 0000000..6fb6b6b
--- /dev/null
+++ b/res/drawable-xhdpi/codebrew.png
Binary files differ
diff --git a/res/drawable-xhdpi/flag.png b/res/drawable-xhdpi/flag.png
new file mode 100755
index 0000000..498ff5d
--- /dev/null
+++ b/res/drawable-xhdpi/flag.png
Binary files differ
diff --git a/res/drawable-xhdpi/gd.png b/res/drawable-xhdpi/gd.png
new file mode 100755
index 0000000..78cae06
--- /dev/null
+++ b/res/drawable-xhdpi/gd.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_downloaded.png b/res/drawable-xhdpi/ic_downloaded.png
new file mode 100644
index 0000000..d0c8756
--- /dev/null
+++ b/res/drawable-xhdpi/ic_downloaded.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_downloaded_selected.png b/res/drawable-xhdpi/ic_downloaded_selected.png
new file mode 100644
index 0000000..3c07967
--- /dev/null
+++ b/res/drawable-xhdpi/ic_downloaded_selected.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_installed.png b/res/drawable-xhdpi/ic_installed.png
new file mode 100644
index 0000000..4e6434e
--- /dev/null
+++ b/res/drawable-xhdpi/ic_installed.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_installed_selected.png b/res/drawable-xhdpi/ic_installed_selected.png
new file mode 100644
index 0000000..654d72b
--- /dev/null
+++ b/res/drawable-xhdpi/ic_installed_selected.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..71c6d76
--- /dev/null
+++ b/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_down.png b/res/drawable-xhdpi/ic_menu_down.png
new file mode 100755
index 0000000..7239a6e
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_down.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_menu_up.png b/res/drawable-xhdpi/ic_menu_up.png
new file mode 100755
index 0000000..19cd859
--- /dev/null
+++ b/res/drawable-xhdpi/ic_menu_up.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sort_down.png b/res/drawable-xhdpi/ic_sort_down.png
new file mode 100644
index 0000000..da1ce31
--- /dev/null
+++ b/res/drawable-xhdpi/ic_sort_down.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_sort_up.png b/res/drawable-xhdpi/ic_sort_up.png
new file mode 100644
index 0000000..10a836a
--- /dev/null
+++ b/res/drawable-xhdpi/ic_sort_up.png
Binary files differ
diff --git a/res/drawable-xhdpi/icon_xhdpi.png b/res/drawable-xhdpi/icon_xhdpi.png
new file mode 100644
index 0000000..7253661
--- /dev/null
+++ b/res/drawable-xhdpi/icon_xhdpi.png
Binary files differ
diff --git a/res/drawable-xhdpi/levels_wheel0.png b/res/drawable-xhdpi/levels_wheel0.png
new file mode 100755
index 0000000..381feca
--- /dev/null
+++ b/res/drawable-xhdpi/levels_wheel0.png
Binary files differ
diff --git a/res/drawable-xhdpi/levels_wheel1.png b/res/drawable-xhdpi/levels_wheel1.png
new file mode 100755
index 0000000..6c5a67f
--- /dev/null
+++ b/res/drawable-xhdpi/levels_wheel1.png
Binary files differ
diff --git a/res/drawable-xhdpi/levels_wheel2.png b/res/drawable-xhdpi/levels_wheel2.png
new file mode 100755
index 0000000..f2db650
--- /dev/null
+++ b/res/drawable-xhdpi/levels_wheel2.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_arrow_down.png b/res/drawable-xhdpi/s_arrow_down.png
new file mode 100755
index 0000000..c3e83d0
--- /dev/null
+++ b/res/drawable-xhdpi/s_arrow_down.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_arrow_up.png b/res/drawable-xhdpi/s_arrow_up.png
new file mode 100755
index 0000000..dce8db7
--- /dev/null
+++ b/res/drawable-xhdpi/s_arrow_up.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_bluearm.png b/res/drawable-xhdpi/s_bluearm.png
new file mode 100755
index 0000000..0d58122
--- /dev/null
+++ b/res/drawable-xhdpi/s_bluearm.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_bluebody.png b/res/drawable-xhdpi/s_bluebody.png
new file mode 100755
index 0000000..fba7752
--- /dev/null
+++ b/res/drawable-xhdpi/s_bluebody.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_blueleg.png b/res/drawable-xhdpi/s_blueleg.png
new file mode 100755
index 0000000..7ea58e3
--- /dev/null
+++ b/res/drawable-xhdpi/s_blueleg.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_engine.png b/res/drawable-xhdpi/s_engine.png
new file mode 100755
index 0000000..9945c5b
--- /dev/null
+++ b/res/drawable-xhdpi/s_engine.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_fender.png b/res/drawable-xhdpi/s_fender.png
new file mode 100755
index 0000000..9681018
--- /dev/null
+++ b/res/drawable-xhdpi/s_fender.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_flag_finish0.png b/res/drawable-xhdpi/s_flag_finish0.png
new file mode 100755
index 0000000..b0719c1
--- /dev/null
+++ b/res/drawable-xhdpi/s_flag_finish0.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_flag_finish1.png b/res/drawable-xhdpi/s_flag_finish1.png
new file mode 100755
index 0000000..4724105
--- /dev/null
+++ b/res/drawable-xhdpi/s_flag_finish1.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_flag_finish2.png b/res/drawable-xhdpi/s_flag_finish2.png
new file mode 100755
index 0000000..e807367
--- /dev/null
+++ b/res/drawable-xhdpi/s_flag_finish2.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_flag_start0.png b/res/drawable-xhdpi/s_flag_start0.png
new file mode 100755
index 0000000..cf6b6c4
--- /dev/null
+++ b/res/drawable-xhdpi/s_flag_start0.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_flag_start1.png b/res/drawable-xhdpi/s_flag_start1.png
new file mode 100755
index 0000000..984e31b
--- /dev/null
+++ b/res/drawable-xhdpi/s_flag_start1.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_flag_start2.png b/res/drawable-xhdpi/s_flag_start2.png
new file mode 100755
index 0000000..eab3854
--- /dev/null
+++ b/res/drawable-xhdpi/s_flag_start2.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_helmet.png b/res/drawable-xhdpi/s_helmet.png
new file mode 100755
index 0000000..423fecc
--- /dev/null
+++ b/res/drawable-xhdpi/s_helmet.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_lock0.png b/res/drawable-xhdpi/s_lock0.png
new file mode 100755
index 0000000..e79b525
--- /dev/null
+++ b/res/drawable-xhdpi/s_lock0.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_lock1.png b/res/drawable-xhdpi/s_lock1.png
new file mode 100755
index 0000000..57db71c
--- /dev/null
+++ b/res/drawable-xhdpi/s_lock1.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_lock2.png b/res/drawable-xhdpi/s_lock2.png
new file mode 100755
index 0000000..cfbd9a1
--- /dev/null
+++ b/res/drawable-xhdpi/s_lock2.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_medal_bronze.png b/res/drawable-xhdpi/s_medal_bronze.png
new file mode 100755
index 0000000..e5020ea
--- /dev/null
+++ b/res/drawable-xhdpi/s_medal_bronze.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_medal_gold.png b/res/drawable-xhdpi/s_medal_gold.png
new file mode 100755
index 0000000..65312a1
--- /dev/null
+++ b/res/drawable-xhdpi/s_medal_gold.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_medal_silver.png b/res/drawable-xhdpi/s_medal_silver.png
new file mode 100755
index 0000000..ff3947c
--- /dev/null
+++ b/res/drawable-xhdpi/s_medal_silver.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_steering.png b/res/drawable-xhdpi/s_steering.png
new file mode 100755
index 0000000..64c6d05
--- /dev/null
+++ b/res/drawable-xhdpi/s_steering.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_wheel1.png b/res/drawable-xhdpi/s_wheel1.png
new file mode 100755
index 0000000..0b3f226
--- /dev/null
+++ b/res/drawable-xhdpi/s_wheel1.png
Binary files differ
diff --git a/res/drawable-xhdpi/s_wheel2.png b/res/drawable-xhdpi/s_wheel2.png
new file mode 100755
index 0000000..3c36d79
--- /dev/null
+++ b/res/drawable-xhdpi/s_wheel2.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_b_down.9.png b/res/drawable-xxhdpi/btn_b_down.9.png
new file mode 100755
index 0000000..99d346c
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_b_down.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_b_up.9.png b/res/drawable-xxhdpi/btn_b_up.9.png
new file mode 100755
index 0000000..afc06e2
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_b_up.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_br_down.9.png b/res/drawable-xxhdpi/btn_br_down.9.png
new file mode 100755
index 0000000..2aa90ad
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_br_down.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_br_up.9.png b/res/drawable-xxhdpi/btn_br_up.9.png
new file mode 100755
index 0000000..215140c
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_br_up.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_n_down.9.png b/res/drawable-xxhdpi/btn_n_down.9.png
new file mode 100755
index 0000000..d4fa25d
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_n_down.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_n_up.9.png b/res/drawable-xxhdpi/btn_n_up.9.png
new file mode 100755
index 0000000..2d7591e
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_n_up.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_r_down.9.png b/res/drawable-xxhdpi/btn_r_down.9.png
new file mode 100755
index 0000000..0c3d5ad
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_r_down.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/btn_r_up.9.png b/res/drawable-xxhdpi/btn_r_up.9.png
new file mode 100755
index 0000000..8fa316c
--- /dev/null
+++ b/res/drawable-xxhdpi/btn_r_up.9.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_downloaded.png b/res/drawable-xxhdpi/ic_downloaded.png
new file mode 100644
index 0000000..22a6f96
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_downloaded.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_downloaded_selected.png b/res/drawable-xxhdpi/ic_downloaded_selected.png
new file mode 100644
index 0000000..d219cdb
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_downloaded_selected.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_installed.png b/res/drawable-xxhdpi/ic_installed.png
new file mode 100644
index 0000000..215d7a8
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_installed.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_installed_selected.png b/res/drawable-xxhdpi/ic_installed_selected.png
new file mode 100644
index 0000000..6b28a23
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_installed_selected.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_down.png b/res/drawable-xxhdpi/ic_menu_down.png
new file mode 100755
index 0000000..6e4ec09
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_menu_down.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_menu_up.png b/res/drawable-xxhdpi/ic_menu_up.png
new file mode 100755
index 0000000..d7e1f46
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_menu_up.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_sort_down.png b/res/drawable-xxhdpi/ic_sort_down.png
new file mode 100644
index 0000000..e0a45f1
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_sort_down.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_sort_up.png b/res/drawable-xxhdpi/ic_sort_up.png
new file mode 100644
index 0000000..759d28a
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_sort_up.png
Binary files differ
diff --git a/res/drawable-xxhdpi/icon.png b/res/drawable-xxhdpi/icon.png
new file mode 100644
index 0000000..4429116
--- /dev/null
+++ b/res/drawable-xxhdpi/icon.png
Binary files differ
diff --git a/res/drawable-xxhdpi/levels_wheel0.png b/res/drawable-xxhdpi/levels_wheel0.png
new file mode 100755
index 0000000..8ed49b2
--- /dev/null
+++ b/res/drawable-xxhdpi/levels_wheel0.png
Binary files differ
diff --git a/res/drawable-xxhdpi/levels_wheel1.png b/res/drawable-xxhdpi/levels_wheel1.png
new file mode 100755
index 0000000..7020e8d
--- /dev/null
+++ b/res/drawable-xxhdpi/levels_wheel1.png
Binary files differ
diff --git a/res/drawable-xxhdpi/levels_wheel2.png b/res/drawable-xxhdpi/levels_wheel2.png
new file mode 100755
index 0000000..d190665
--- /dev/null
+++ b/res/drawable-xxhdpi/levels_wheel2.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_arrow_down.png b/res/drawable-xxhdpi/s_arrow_down.png
new file mode 100755
index 0000000..517557d
--- /dev/null
+++ b/res/drawable-xxhdpi/s_arrow_down.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_arrow_up.png b/res/drawable-xxhdpi/s_arrow_up.png
new file mode 100755
index 0000000..fcb5a2a
--- /dev/null
+++ b/res/drawable-xxhdpi/s_arrow_up.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_bluearm.png b/res/drawable-xxhdpi/s_bluearm.png
new file mode 100755
index 0000000..3209303
--- /dev/null
+++ b/res/drawable-xxhdpi/s_bluearm.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_bluebody.png b/res/drawable-xxhdpi/s_bluebody.png
new file mode 100755
index 0000000..e8429f9
--- /dev/null
+++ b/res/drawable-xxhdpi/s_bluebody.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_blueleg.png b/res/drawable-xxhdpi/s_blueleg.png
new file mode 100755
index 0000000..91bf7ad
--- /dev/null
+++ b/res/drawable-xxhdpi/s_blueleg.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_engine.png b/res/drawable-xxhdpi/s_engine.png
new file mode 100755
index 0000000..8a76af3
--- /dev/null
+++ b/res/drawable-xxhdpi/s_engine.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_fender.png b/res/drawable-xxhdpi/s_fender.png
new file mode 100755
index 0000000..dc196eb
--- /dev/null
+++ b/res/drawable-xxhdpi/s_fender.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_flag_finish0.png b/res/drawable-xxhdpi/s_flag_finish0.png
new file mode 100755
index 0000000..74f6882
--- /dev/null
+++ b/res/drawable-xxhdpi/s_flag_finish0.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_flag_finish1.png b/res/drawable-xxhdpi/s_flag_finish1.png
new file mode 100755
index 0000000..16c9d5b
--- /dev/null
+++ b/res/drawable-xxhdpi/s_flag_finish1.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_flag_finish2.png b/res/drawable-xxhdpi/s_flag_finish2.png
new file mode 100755
index 0000000..476c13a
--- /dev/null
+++ b/res/drawable-xxhdpi/s_flag_finish2.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_flag_start0.png b/res/drawable-xxhdpi/s_flag_start0.png
new file mode 100755
index 0000000..d9e512f
--- /dev/null
+++ b/res/drawable-xxhdpi/s_flag_start0.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_flag_start1.png b/res/drawable-xxhdpi/s_flag_start1.png
new file mode 100755
index 0000000..4cef022
--- /dev/null
+++ b/res/drawable-xxhdpi/s_flag_start1.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_flag_start2.png b/res/drawable-xxhdpi/s_flag_start2.png
new file mode 100755
index 0000000..7d302ee
--- /dev/null
+++ b/res/drawable-xxhdpi/s_flag_start2.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_helmet.png b/res/drawable-xxhdpi/s_helmet.png
new file mode 100755
index 0000000..b0d1a78
--- /dev/null
+++ b/res/drawable-xxhdpi/s_helmet.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_lock0.png b/res/drawable-xxhdpi/s_lock0.png
new file mode 100755
index 0000000..7f629a6
--- /dev/null
+++ b/res/drawable-xxhdpi/s_lock0.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_lock1.png b/res/drawable-xxhdpi/s_lock1.png
new file mode 100755
index 0000000..b829b7c
--- /dev/null
+++ b/res/drawable-xxhdpi/s_lock1.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_lock2.png b/res/drawable-xxhdpi/s_lock2.png
new file mode 100755
index 0000000..be683c9
--- /dev/null
+++ b/res/drawable-xxhdpi/s_lock2.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_medal_bronze.png b/res/drawable-xxhdpi/s_medal_bronze.png
new file mode 100755
index 0000000..176bff6
--- /dev/null
+++ b/res/drawable-xxhdpi/s_medal_bronze.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_medal_gold.png b/res/drawable-xxhdpi/s_medal_gold.png
new file mode 100755
index 0000000..cfde974
--- /dev/null
+++ b/res/drawable-xxhdpi/s_medal_gold.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_medal_silver.png b/res/drawable-xxhdpi/s_medal_silver.png
new file mode 100755
index 0000000..7f4d8db
--- /dev/null
+++ b/res/drawable-xxhdpi/s_medal_silver.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_steering.png b/res/drawable-xxhdpi/s_steering.png
new file mode 100755
index 0000000..426ebb8
--- /dev/null
+++ b/res/drawable-xxhdpi/s_steering.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_wheel1.png b/res/drawable-xxhdpi/s_wheel1.png
new file mode 100755
index 0000000..e624d55
--- /dev/null
+++ b/res/drawable-xxhdpi/s_wheel1.png
Binary files differ
diff --git a/res/drawable-xxhdpi/s_wheel2.png b/res/drawable-xxhdpi/s_wheel2.png
new file mode 100755
index 0000000..e394f00
--- /dev/null
+++ b/res/drawable-xxhdpi/s_wheel2.png
Binary files differ
diff --git a/res/drawable-xxxhdpi/icon.png b/res/drawable-xxxhdpi/icon.png
new file mode 100644
index 0000000..930d068
--- /dev/null
+++ b/res/drawable-xxxhdpi/icon.png
Binary files differ
diff --git a/res/drawable/btn_b.xml b/res/drawable/btn_b.xml
new file mode 100755
index 0000000..cce745e
--- /dev/null
+++ b/res/drawable/btn_b.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:drawable="@drawable/btn_b_up" />
+ <item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/btn_b_down" />
+ <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/btn_b_up" />
+ <item android:state_enabled="true" android:drawable="@drawable/btn_b_up" />
+</selector> \ No newline at end of file
diff --git a/res/drawable/btn_br.xml b/res/drawable/btn_br.xml
new file mode 100755
index 0000000..f0fff90
--- /dev/null
+++ b/res/drawable/btn_br.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:drawable="@drawable/btn_br_up" />
+ <item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/btn_br_down" />
+ <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/btn_br_up" />
+ <item android:state_enabled="true" android:drawable="@drawable/btn_br_up" />
+</selector> \ No newline at end of file
diff --git a/res/drawable/btn_n.xml b/res/drawable/btn_n.xml
new file mode 100755
index 0000000..a14d953
--- /dev/null
+++ b/res/drawable/btn_n.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:drawable="@drawable/btn_n_up" />
+ <item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/btn_n_down" />
+ <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/btn_n_up" />
+ <item android:state_enabled="true" android:drawable="@drawable/btn_n_up" />
+</selector> \ No newline at end of file
diff --git a/res/drawable/btn_r.xml b/res/drawable/btn_r.xml
new file mode 100755
index 0000000..30bea53
--- /dev/null
+++ b/res/drawable/btn_r.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_enabled="false" android:drawable="@drawable/btn_r_up" />
+ <item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/btn_r_down" />
+ <item android:state_focused="true" android:state_enabled="true" android:drawable="@drawable/btn_r_up" />
+ <item android:state_enabled="true" android:drawable="@drawable/btn_r_up" />
+</selector> \ No newline at end of file
diff --git a/res/drawable/ic_menu.xml b/res/drawable/ic_menu.xml
new file mode 100755
index 0000000..ea3c508
--- /dev/null
+++ b/res/drawable/ic_menu.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/ic_menu_down" />
+ <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/ic_menu_down" />
+ <item android:state_focused="false" android:state_pressed="false" android:drawable="@drawable/ic_menu_up" />
+</selector> \ No newline at end of file
diff --git a/res/drawable/ic_sort.xml b/res/drawable/ic_sort.xml
new file mode 100644
index 0000000..9de17ca
--- /dev/null
+++ b/res/drawable/ic_sort.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/ic_sort_down" />
+ <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/ic_sort_down" />
+ <item android:state_focused="false" android:state_pressed="false" android:drawable="@drawable/ic_sort_up" />
+</selector> \ No newline at end of file
diff --git a/res/drawable/menu_item_color.xml b/res/drawable/menu_item_color.xml
new file mode 100644
index 0000000..b0b7835
--- /dev/null
+++ b/res/drawable/menu_item_color.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:color="#00a000" />
+ <item android:state_focused="true" android:color="#00a000" />
+ <item android:state_selected="true" android:color="#00a000" />
+ <item android:color="#000000" />
+</selector> \ No newline at end of file
diff --git a/res/layout/activity_gdtr.xml b/res/layout/activity_gdtr.xml
new file mode 100755
index 0000000..e2e3918
--- /dev/null
+++ b/res/layout/activity_gdtr.xml
@@ -0,0 +1,11 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingBottom="@dimen/activity_vertical_margin"
+ android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ tools:context=".GDTRActivity">
+
+</RelativeLayout>
diff --git a/res/layout/levels_list_item.xml b/res/layout/levels_list_item.xml
new file mode 100644
index 0000000..def6e9f
--- /dev/null
+++ b/res/layout/levels_list_item.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingTop="7dp"
+ android:paddingBottom="7dp">
+
+ <org.happysanta.gd.Menu.Views.MenuHelmetView
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:id="@+id/level_name"
+ android:layout_width="match_parent"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:paddingTop="7dp"
+ android:lineSpacingMultiplier="1.1"
+ android:lineSpacingExtra="0px"
+ android:textSize="20sp"
+ android:textColor="@drawable/menu_item_color" />
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/level_count"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="16sp" />
+
+ </LinearLayout>
+</LinearLayout> \ No newline at end of file
diff --git a/res/menu/gdtr.xml b/res/menu/gdtr.xml
new file mode 100755
index 0000000..81f2f88
--- /dev/null
+++ b/res/menu/gdtr.xml
@@ -0,0 +1,9 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <item
+ android:id="@+id/action_settings"
+ android:orderInCategory="100"
+ android:showAsAction="never"
+ android:title="@string/action_settings" />
+
+</menu>
diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml
new file mode 100755
index 0000000..46aef0a
--- /dev/null
+++ b/res/values-sw600dp/dimens.xml
@@ -0,0 +1,8 @@
+<resources>
+
+ <!--
+ Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw600dp devices (e.g. 7" tablets) here.
+ -->
+
+</resources>
diff --git a/res/values-sw600dp/screen.xml b/res/values-sw600dp/screen.xml
new file mode 100644
index 0000000..6cdc84e
--- /dev/null
+++ b/res/values-sw600dp/screen.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="screen_type">tablet</string>
+</resources> \ No newline at end of file
diff --git a/res/values-sw720dp-land/dimens.xml b/res/values-sw720dp-land/dimens.xml
new file mode 100755
index 0000000..c8d523f
--- /dev/null
+++ b/res/values-sw720dp-land/dimens.xml
@@ -0,0 +1,9 @@
+<resources>
+
+ <!--
+ Customize dimensions originally defined in res/values/dimens.xml (such as
+ screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
+ -->
+ <dimen name="activity_horizontal_margin">128dp</dimen>
+
+</resources>
diff --git a/res/values-sw720dp-land/screen.xml b/res/values-sw720dp-land/screen.xml
new file mode 100644
index 0000000..6cdc84e
--- /dev/null
+++ b/res/values-sw720dp-land/screen.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="screen_type">tablet</string>
+</resources> \ No newline at end of file
diff --git a/res/values-v11/styles.xml b/res/values-v11/styles.xml
new file mode 100755
index 0000000..bf0782f
--- /dev/null
+++ b/res/values-v11/styles.xml
@@ -0,0 +1,11 @@
+<resources>
+
+ <!--
+ Base application theme for API 11+. This theme completely replaces
+ AppBaseTheme from res/values/styles.xml on API 11+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.NoActionBar">
+ <!-- API 11 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/res/values-v14/styles.xml b/res/values-v14/styles.xml
new file mode 100755
index 0000000..1ab2b36
--- /dev/null
+++ b/res/values-v14/styles.xml
@@ -0,0 +1,12 @@
+<resources>
+
+ <!--
+ Base application theme for API 14+. This theme completely replaces
+ AppBaseTheme from BOTH res/values/styles.xml and
+ res/values-v11/styles.xml on API 14+ devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.Holo.Light.NoActionBar">
+ <!-- API 14 theme customizations can go here. -->
+ </style>
+
+</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
new file mode 100755
index 0000000..3c6cff8
--- /dev/null
+++ b/res/values/dimens.xml
@@ -0,0 +1,7 @@
+<resources>
+
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
diff --git a/res/values/screen.xml b/res/values/screen.xml
new file mode 100644
index 0000000..94b8e65
--- /dev/null
+++ b/res/values/screen.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="screen_type">phone</string>
+</resources> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100755
index 0000000..d116c82
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="no">No</string>
+ <string name="yes">Yes</string>
+ <string name="back">Back</string>
+ <string name="ok">Ok</string>
+ <string name="cancel">Cancel</string>
+ <string name="go_to_main">Go to Main</string>
+ <string name="on">On</string>
+ <string name="off">Off</string>
+
+ <string name="app_name">Gravity Defied</string>
+ <string name="action_settings">Settings</string>
+ <string name="exit">Exit Game</string>
+ <string name="main">Main</string>
+ <string name="play_menu">Play Menu</string>
+ <string name="options">Options</string>
+ <string name="help">Help</string>
+ <string name="about">About</string>
+
+ <string name="play">Play</string>
+ <string name="start">Start</string>
+
+ <string name="mods">Mods</string>
+ <string name="highscores">High Scores</string>
+ <string name="finished">Finished!</string>
+ <string name="ingame">Ingame</string>
+ <string name="enter_name">Enter Name</string>
+ <string name="confirm_clear">Confirm Clear</string>
+ <string name="confirm_reset">Confirm Reset</string>
+ <string name="level">Level</string>
+ <string name="track">Track</string>
+ <string name="league">League</string>
+ <string name="restart">Restart</string>
+ <string name="restart_with_new_level">Restart with new level</string>
+ <string name="send_logs">Send logs</string>
+ <string name="next">Next</string>
+ <string name="_continue">Continue</string>
+ <string name="name">Name</string>
+ <string name="time">Time</string>
+
+ <string name="perspective">Perspective</string>
+ <string name="shadows">Shadows</string>
+ <string name="driver_sprite">Driver sprite</string>
+ <string name="bike_sprite">Bike sprite</string>
+ <string name="input">Input</string>
+ <string name="look_ahead">Look ahead</string>
+ <string name="vibrate_on_touch">Vibrate on touch</string>
+ <string name="keyboard_in_menu">Keyboard in menu</string>
+ <string name="clear_highscore">Clear highscore</string>
+ <string name="full_reset">Full Reset</string>
+ <string name="reset">Reset</string>
+ <string name="reset_text">Master reset. Application will be restarted.</string>
+
+ <string name="installed_mods">Installed mods</string>
+ <string name="download_mods">Download mods</string>
+ <string name="download_options">Download options</string>
+ <string name="install_mrg">Install levels.mrg</string>
+ <string name="installed_levels_text">Here you can manage installed levels.</string>
+ <string name="download_levels_text">Here you can download and install new levels.</string>
+
+ <string name="cleared">Cleared</string>
+ <string name="cleared_text">Highscores have been cleared</string>
+ <string name="erase_text1">Clearing the highscores cannot be undone. It will remove all the registered times on all tracks.</string>
+ <string name="erase_text2">Would you like to clear the highscores?</string>
+ <string name="reset_text1">A full reset cannot be undone. It will relock all tracks and leagues and clear back all settings to default. A full reset will restart the application.</string>
+ <string name="reset_text2">Would you like to do a full reset?</string>
+
+ <string name="objective">Objective</string>
+ <string name="objective_text">Race to the finish line as fast as you can without crashing. By leaning forward and backward you can adjust the rotation of your bike. By landing on both wheels after jumping, your bike won\'t crash as easily. Beware, the levels tend to get harder and harder...</string>
+
+ <string name="keys">Keys</string>
+ <string name="keyset_text"><![CDATA[
+ <b>Keyset 1</b><br/>
+ 2 accelerates, 8 brakes, 6 leans forward and 4 leans backward. 1 accelerates and leans backward. 3 accelerates and leans forward. 7 brakes and leans backward. 9 brakes and leans forward.<br/><br/>
+ <b>Keyset 2</b><br/>
+ 1 accelerates, 4 brakes, 6 leans forward and 5 leans backward.<br/><br/>
+ <b>Keyset 3</b><br/>
+ 3 accelerates, 6 brakes, 5 leans forward and 4 leans backward.
+ ]]></string>
+
+ <string name="unlocking">Unlocking</string>
+ <string name="unlocking_text">By completing the easier levels, new levels will be unlocked. You will also gain access to higher leagues where more advanced bikes with different characteristics are available.</string>
+
+ <string name="highscore_text">The three best times on every track are saved for each league. When beating a time on a track you will be asked to enter your name. The highscores can be viewed from the Play Menu. By pressing left and right in the highscore view you can view the highscore for a specific league. The highscore can be cleared from the options menu.</string>
+ <string name="no_highscores">No Highscores</string>
+
+ <string name="options_text"><![CDATA[
+ <b>Perspective: On/Off</b><br/>
+ Default: &lt;On&gt;<br/>
+ Turns on and off the perspective view of the tracks.<br/><br/>
+
+ <b>Shadows: On/Off</b><br/>
+ Default: &lt;On&gt;<br/>
+ Turns on and off the shadows.<br/><br/>
+
+ <b>Driver Sprite: On / Off</b><br/>
+ Default: &lt;On&gt;<br/>
+ &lt;On&gt; uses a texture for the driver. &lt;.Off&gt; uses line graphics.<br/><br/>
+
+ <b>Bike Sprite: On / Off</b><br/>
+ Default: &lt;On&gt;<br/>
+ &lt;On&gt; uses a texture for the bike. &lt;Off&gt; uses line graphics.<br/><br/>
+
+ <b>Input: Keyset 1,2,3</b><br/>
+ Default: &lt;1&gt;<br/>
+ Determines which type of input should be used when playing. See "Keys" in the help menu for more info.<br/><br/>
+
+ <b>Look ahead: On/Off</b><br/>
+ Default: &lt;On&gt;<br/>
+ Turns on and off smart camera movement.<br/><br/>
+
+ <b>Vibrate on touch: On/Off</b><br/>
+ Default: &lt;On&gt;<br/>
+ Enables haptic feedback when you press control keys.<br/><br/>
+
+ <b>Keyboard in menu: On/Off</b><br/>
+ Default: &lt;On&gt;<br/>
+ Turns on and off keyboard in menu.<br/><br/>
+
+ <b>Clear highscore</b><br/>
+ Lets you clear the highscores. Here you can also do a "Full Reset" which will reset the game to original state (clear settings, highscores, unlocked levels and leagues).
+ ]]></string>
+ <string name="about_text"><![CDATA[
+ <b>Gravity Defied Classic</b> ported to Android by Gregory Klyushnikov and Eugene Zinoviev<br/>
+ Кузница винрара<br/>
+ Happy Santa LLC<br/>
+ http://gdtr.net \u00A9 2014<br/><br/>
+
+ <b>Gravity Defied - Trial Racing</b> by Codebrew Software<br/>
+ http://codebrew.se \u00A9 2004
+ ]]></string>
+ <string name="ported_text"><![CDATA[
+ <font color="#999999">Ported by</font><br/>
+ <font color="#000000">Кузница винрара</font><br/>
+ <font color="#999999">and</font><br/>
+ <font color="#000000">Happy Santa LLC</font>
+ ]]></string>
+
+ <string name="crashed">Crashed</string>
+ <string name="wheelie">Wheelie!</string>
+ <string name="finished1">Finished</string>
+ <string name="enjoy">Enjoy...</string>
+ <string name="congratulations">Congratulations! You have successfully unlocked a new league: </string>
+ <string name="league_unlocked">League unlocked</string>
+ <string name="league_unlocked_text">You have successfully unlocked a new league: </string>
+ <string name="level_completed_text">You have completed all tracks at this level.</string>
+ <string name="complete_to_unlock">Complete more tracks to unlock this track/league combo.</string>
+ <string name="tracks_completed_tpl"><![CDATA[%1$d of %2$d tracks in <b>%3$s</b> completed.]]></string>
+
+ <string name="LEAGUE">LEAGUE</string>
+
+ <string-array name="finished_places">
+ <item>First place!</item>
+ <item>Second place!</item>
+ <item>Third place!</item>
+ </string-array>
+
+ <string-array name="on_off">
+ <item>On</item>
+ <item>Off</item>
+ </string-array>
+
+ <string-array name="keyset">
+ <item>Keyset 1</item>
+ <item>Keyset 2</item>
+ <item>Keyset 3</item>
+ </string-array>
+
+ <string-array name="leagues">
+ <item>100cc</item>
+ <item>175cc</item>
+ <item>220cc</item>
+ </string-array>
+
+ <string-array name="leagues_full">
+ <item>100cc</item>
+ <item>175cc</item>
+ <item>220cc</item>
+ <item>325cc</item>
+ </string-array>
+
+ <string-array name="difficulty">
+ <item>Easy</item>
+ <item>Medium</item>
+ <item>Hard</item>
+ </string-array>
+
+ <string name="download_error">Cannot download levels list.</string>
+ <string name="no_internet_connection">No internet connection</string>
+ <string name="waiting_for_network">Waiting for network connection&#8230;</string>
+ <string name="levels_count_tpl"><![CDATA[%1$s <font color="#909090">(%2$s)</font>]]></string>
+ <string name="active_name_tpl"><![CDATA[%1$s <font color="#00a000">(Active)</font>]]></string>
+
+ <string name="sort_by">Sort by:</string>
+ <string-array name="sort_variants">
+ <item>Popularity</item>
+ <item>Most recent</item>
+ <item>Oldest</item>
+ <item>Tracks count</item>
+ </string-array>
+
+ <string name="author_tpl"><![CDATA[<font color="#888888">Author:</font> %1$s]]></string>
+ <string name="added_tpl"><![CDATA[<font color="#888888">Added:</font> %1$s]]></string>
+ <string name="installed_tpl"><![CDATA[<font color="#888888">Installed:</font> %1$s]]></string>
+ <string name="tracks_tpl"><![CDATA[<font color="#888888">Tracks:</font> %1$s]]></string>
+ <string name="install_kb">Install (%1$s Kb)</string>
+ <string name="install">Install</string>
+ <string name="installing">Installing..</string>
+ <string name="load_this_game">Load this game</string>
+ <string name="enter_levels_name_title">Levels name</string>
+ <string name="enter_levels_name">Enter levels pack name:</string>
+ <string name="error">Error</string>
+ <string name="oops">Oops..</string>
+ <string name="please_wait">Please wait..</string>
+ <string name="success">Success</string>
+ <string name="successfully_installed">Levels successfully installed.</string>
+ <string name="open_installed">Open installed</string>
+ <string name="installed">Installed</string>
+ <string name="delete">Delete</string>
+ <string name="deleting">Deleting..</string>
+ <string name="downloading">Downloading..</string>
+ <string name="delete_levels">Delete levels</string>
+ <string name="delete_levels_confirmation">Are you sure you want to delete these levels? This action cannot be undone.</string>
+ <string name="active">Active</string>
+ <string name="unlock_next">Unlock next level</string>
+
+ <string name="e_external_storage_is_not_readable">External storage is not readable.</string>
+ <string name="e_downloading_was_interrupted">Downloading was interrupted</string>
+ <string name="e_no_space_left">No space left on device</string>
+ <string name="e_cannot_save_level">Cannot save level into database</string>
+ <string name="e_no_network_connection">No network connection.</string>
+ <string name="e_level_damaged">Looks like this level is damaged.\nYou can skip it and unlock next level.</string>
+
+</resources>
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100755
index 0000000..f8ce291
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,21 @@
+<resources>
+
+ <!--
+ Base application theme, dependent on API level. This theme is replaced
+ by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+ -->
+ <style name="AppBaseTheme" parent="android:Theme.NoTitleBar">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ <item name="android:windowContentOverlay">@null</item>
+ </style>
+
+</resources>
diff --git a/src/org/happysanta/gd/API/API.java b/src/org/happysanta/gd/API/API.java
new file mode 100755
index 0000000..8e1ee0d
--- /dev/null
+++ b/src/org/happysanta/gd/API/API.java
@@ -0,0 +1,101 @@
+package org.happysanta.gd.API;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.*;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.happysanta.gd.Helpers.getDeviceName;
+
+public class API {
+
+ public static final String URL = "http://gdtr.net/api.php";
+ public static final String DEBUG_URL = "http://dev.gdtr.net/api.php";
+ public static final String MRG_URL = "http://gdtr.net/mrg/%d.mrg";
+ public static final int VERSION = 2;
+
+ public static Request getLevels(int offset, int limit, LevelsSortType sort, ResponseHandler handler)
+ throws Exception {
+ List<NameValuePair> params = new LinkedList<NameValuePair>();
+ params.add(new BasicNameValuePair("sort", sort.toString()));
+ params.add(new BasicNameValuePair("offset", String.valueOf(offset)));
+ params.add(new BasicNameValuePair("limit", String.valueOf(limit)));
+
+ return new Request("getLevels", params, handler);
+ }
+
+ public static Request getNotifications(boolean installedFromAPK, ResponseHandler handler) {
+ List<NameValuePair> params = new LinkedList<NameValuePair>();
+ params.add(new BasicNameValuePair("apk", String.valueOf(installedFromAPK ? 1 : 0)));
+ return new Request("getNotifications", params, handler);
+ }
+
+ public static Request sendStats(String statsJSON, String installationID, int useCheats, ResponseHandler handler) {
+ List<NameValuePair> params = new LinkedList<NameValuePair>();
+ params.add(new BasicNameValuePair("stats", statsJSON));
+ params.add(new BasicNameValuePair("id", installationID));
+ params.add(new BasicNameValuePair("use_cheats", String.valueOf(useCheats)));
+ return new Request("sendStats", params, handler);
+ }
+
+ public static Request sendKeyboardLogs(String log, ResponseHandler handler) {
+ List<NameValuePair> params = new LinkedList<NameValuePair>();
+ params.add(new BasicNameValuePair("log", log));
+ params.add(new BasicNameValuePair("device", getDeviceName()));
+ return new Request("sendKeyboardLogs", params, handler, true);
+ }
+
+ public static DownloadFile downloadMrg(long id, FileOutputStream output, DownloadHandler handler) {
+ return new DownloadFile(String.format(MRG_URL, id), output, handler);
+ }
+
+ public static String getMrgURL(long id) {
+ return String.format(MRG_URL, id);
+ }
+
+ public static enum LevelsSortType {
+ POPULAR("popular"), TRACKS("tracks"), RECENT("recent"), OLDEST("oldest");
+
+ private final String text;
+
+ private LevelsSortType(final String text) {
+ this.text = text;
+ }
+
+ @Override
+ public String toString() {
+ return text;
+ }
+ }
+
+ public static LevelsSortType getSortTypeById(int id) {
+ switch (id) {
+ case 0:
+ return LevelsSortType.POPULAR;
+ case 1:
+ return LevelsSortType.RECENT;
+ case 2:
+ return LevelsSortType.OLDEST;
+ case 3:
+ return LevelsSortType.TRACKS;
+ }
+ return null;
+ }
+
+ public static int getIdBySortType(LevelsSortType type) {
+ switch (type) {
+ case POPULAR:
+ return 0;
+ case RECENT:
+ return 1;
+ case OLDEST:
+ return 2;
+ case TRACKS:
+ return 3;
+ }
+ return 0;
+ }
+
+}
diff --git a/src/org/happysanta/gd/API/APIException.java b/src/org/happysanta/gd/API/APIException.java
new file mode 100755
index 0000000..6cf2c14
--- /dev/null
+++ b/src/org/happysanta/gd/API/APIException.java
@@ -0,0 +1,9 @@
+package org.happysanta.gd.API;
+
+public class APIException extends java.lang.Exception {
+
+ public APIException(String message) {
+ super(message);
+ }
+
+}
diff --git a/src/org/happysanta/gd/API/DownloadFile.java b/src/org/happysanta/gd/API/DownloadFile.java
new file mode 100644
index 0000000..2920c27
--- /dev/null
+++ b/src/org/happysanta/gd/API/DownloadFile.java
@@ -0,0 +1,144 @@
+package org.happysanta.gd.API;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.os.PowerManager;
+import org.apache.http.HttpException;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import static org.happysanta.gd.Helpers.getGDActivity;
+
+public class DownloadFile {
+
+ private String urlString;
+ private DownloadHandler handler;
+ private FileOutputStream output;
+ private AsyncDownloadTask task;
+
+ public DownloadFile(String url, FileOutputStream output) {
+ this.urlString = url;
+ this.output = output;
+ }
+
+ public DownloadFile(String url, FileOutputStream output, DownloadHandler handler) {
+ this(url, output);
+ this.handler = handler;
+ }
+
+ public void setDownloadHandler(DownloadHandler handler) {
+ this.handler = handler;
+ }
+
+ public void start() {
+ task = new AsyncDownloadTask();
+ task.execute();
+ }
+
+ public void cancel() {
+ if (task != null) {
+ task.cancel(true);
+ task = null;
+ }
+ }
+
+ protected class AsyncDownloadTask extends AsyncTask<Void, Integer, Throwable> {
+
+ private PowerManager.WakeLock lock;
+
+ @Override
+ protected Throwable doInBackground(Void... params) {
+ // OutputStream output = (FileOutputStream)params[1];
+ InputStream input = null;
+ HttpURLConnection connection = null;
+
+ try {
+ URL url = new URL(urlString);
+ connection = (HttpURLConnection) url.openConnection();
+ connection.connect();
+
+ // expect HTTP 200 OK, so we don't mistakenly save error report
+ // instead of the file
+ if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ return new HttpException("Server returned HTTP " + connection.getResponseCode()
+ + " " + connection.getResponseMessage());
+ }
+
+ // this will be useful to display download percentage
+ // might be -1: server did not report the length
+ int fileLength = connection.getContentLength();
+
+ // download the file
+ input = connection.getInputStream();
+
+ byte data[] = new byte[4096];
+ long total = 0;
+ int count;
+ while ((count = input.read(data)) != -1) {
+ // allow canceling with back button
+ if (isCancelled()) {
+ input.close();
+ return null;
+ }
+
+ total += count;
+
+ // publishing the progress....
+ if (fileLength > 0) // only if total length is known
+ publishProgress((int) (total * 100 / fileLength));
+
+ output.write(data, 0, count);
+ }
+ } catch (Exception e) {
+ return e;
+ } finally {
+ try {
+ if (output != null)
+ output.close();
+ if (input != null)
+ input.close();
+ } catch (IOException ignored) {
+ }
+
+ if (connection != null)
+ connection.disconnect();
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+
+ // take CPU lock to prevent CPU from going off if the user
+ // presses the power button during download
+ PowerManager pm = (PowerManager) getGDActivity().getSystemService(Context.POWER_SERVICE);
+ lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+ getClass().getName());
+ lock.acquire();
+
+ handler.onStart();
+ }
+
+ @Override
+ protected void onProgressUpdate(Integer... progress) {
+ super.onProgressUpdate(progress);
+
+ handler.onProgress(progress[0]);
+ }
+
+ @Override
+ protected void onPostExecute(Throwable error) {
+ lock.release();
+ handler.onFinish(error);
+ }
+
+ }
+
+
+}
diff --git a/src/org/happysanta/gd/API/DownloadHandler.java b/src/org/happysanta/gd/API/DownloadHandler.java
new file mode 100644
index 0000000..ec43651
--- /dev/null
+++ b/src/org/happysanta/gd/API/DownloadHandler.java
@@ -0,0 +1,14 @@
+package org.happysanta.gd.API;
+
+/**
+ * Created by evgeny on 6/10/14.
+ */
+public interface DownloadHandler {
+
+ public abstract void onStart();
+
+ public abstract void onFinish(Throwable error);
+
+ public abstract void onProgress(int progress);
+
+} \ No newline at end of file
diff --git a/src/org/happysanta/gd/API/LevelsResponse.java b/src/org/happysanta/gd/API/LevelsResponse.java
new file mode 100755
index 0000000..b62a6e6
--- /dev/null
+++ b/src/org/happysanta/gd/API/LevelsResponse.java
@@ -0,0 +1,64 @@
+package org.happysanta.gd.API;
+
+import org.happysanta.gd.Storage.Level;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.Vector;
+
+public class LevelsResponse {
+
+ protected Level levels[] = null;
+ protected int totalCount = 0;
+
+ public LevelsResponse(Response response) {
+ parse(response);
+ }
+
+ protected void parse(Response response) {
+ JSONArray json = response.getJSON();
+ try {
+ JSONObject object = json.getJSONObject(1);
+ Vector<Level> levels = new Vector<>();
+ totalCount = object.getInt("count");
+ JSONArray items = object.getJSONArray("items");
+
+ try {
+ JSONObject item;
+ JSONArray tracks;
+ for (int i = 0; i < items.length(); i++) {
+ item = items.getJSONObject(i);
+ tracks = item.getJSONArray("tracks");
+
+ levels.addElement(new Level(
+ 0,
+ item.getString("name"),
+ item.getJSONObject("author").getString("name"),
+ tracks.getInt(0),
+ tracks.getInt(1),
+ tracks.getInt(2),
+ item.getInt("added"),
+ item.getInt("size"),
+ item.getInt("id")
+ ));
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ } finally {
+ this.levels = levels.toArray(new Level[0]);
+ }
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public int getTotalCount() {
+ return totalCount;
+ }
+
+ public Level[] getLevels() {
+ return levels;
+ }
+
+}
diff --git a/src/org/happysanta/gd/API/NotificationsResponse.java b/src/org/happysanta/gd/API/NotificationsResponse.java
new file mode 100644
index 0000000..06dca09
--- /dev/null
+++ b/src/org/happysanta/gd/API/NotificationsResponse.java
@@ -0,0 +1,76 @@
+package org.happysanta.gd.API;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+public class NotificationsResponse {
+
+ private String title;
+ private String message;
+ private String url;
+ private int buttonsCount = 1;
+ private String[] buttons = new String[2];
+ private boolean empty = true;
+ private boolean isURL = false;
+
+ public NotificationsResponse(Response response) {
+ parse(response);
+ }
+
+ protected void parse(Response response) {
+ JSONArray json = response.getJSON();
+ try {
+ JSONArray jsonResponse = json.getJSONArray(1);
+ if (jsonResponse.length() > 0) {
+ JSONObject notification = jsonResponse.getJSONObject(0);
+ title = notification.getString("title");
+ message = notification.getString("message");
+ buttons[0] = notification.getString("button_ok");
+ if (notification.has("button_cancel")) {
+ buttonsCount = 2;
+ buttons[1] = notification.getString("button_cancel");
+ }
+ if (notification.has("open_url")) {
+ url = notification.getString("open_url");
+ isURL = true;
+ }
+ empty = false;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean isEmpty() {
+ return empty;
+ }
+
+ public boolean hasURL() {
+ return isURL;
+ }
+
+ public String getURL() {
+ return url;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public boolean hasTwoButtons() {
+ return buttonsCount == 2;
+ }
+
+ public String getOKButton() {
+ return buttons[0];
+ }
+
+ public String getCancelButton() {
+ return buttons[1];
+ }
+
+}
diff --git a/src/org/happysanta/gd/API/Request.java b/src/org/happysanta/gd/API/Request.java
new file mode 100644
index 0000000..d8bfa6e
--- /dev/null
+++ b/src/org/happysanta/gd/API/Request.java
@@ -0,0 +1,143 @@
+package org.happysanta.gd.API;
+
+import android.os.AsyncTask;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Locale;
+
+import static org.happysanta.gd.Helpers.getAppVersion;
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class Request {
+
+ // enum Method { GET, POST };
+
+ private List<NameValuePair> params;
+ private ResponseHandler handler;
+ private AsyncRequestTask task;
+ private String apiURL;
+
+ public Request(String method, List<NameValuePair> params, ResponseHandler handler, boolean useDebugURL) {
+ construct(method, params, handler, useDebugURL ? API.DEBUG_URL : API.URL);
+ }
+
+ public Request(String method, List<NameValuePair> params, ResponseHandler handler) {
+ construct(method, params, handler, API.URL);
+ }
+
+ private void construct(String method, List<NameValuePair> params, ResponseHandler handler, String apiURL) {
+ this.apiURL = apiURL;
+
+ params.add(new BasicNameValuePair("v", String.valueOf(API.VERSION)));
+ params.add(new BasicNameValuePair("method", method));
+ params.add(new BasicNameValuePair("app_version", getAppVersion()));
+ params.add(new BasicNameValuePair("app_lang", Locale.getDefault().getDisplayLanguage()));
+
+ this.params = params;
+ this.handler = handler;
+
+ go();
+ }
+
+ private void go() {
+ task = new AsyncRequestTask();
+ task.execute(apiURL);
+ }
+
+ public void cancel() {
+ if (task != null) {
+ task.cancel(true);
+ task = null;
+ }
+ }
+
+ private void onDone(String result) {
+ Response response;
+ logDebug("API.Request.onDone()");
+
+ try {
+ response = new Response(result);
+ } catch (APIException e) {
+ handler.onError(e);
+ return;
+ } catch (Exception e) {
+ // e.printStackTrace();
+ handler.onError(new APIException(result == null ? "Network error" : "JSON parsing error"));
+ return;
+ // exception = new Exception();
+ }
+
+ // handler.onResponse(response);
+
+ if (response != null)
+ handler.onResponse(response);
+ else
+ handler.onError(new APIException("JSON parsing error"));
+ }
+
+ protected class AsyncRequestTask extends AsyncTask<String, Void, String> {
+
+ @Override
+ protected String doInBackground(String... objects) {
+ String url = objects[0];
+
+ DefaultHttpClient client = new DefaultHttpClient();
+ HttpPost post = new HttpPost(url);
+ try {
+ post.setEntity(new UrlEncodedFormEntity(params));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ return null;
+ }
+ String result = null;
+ InputStream is = null;
+
+ try {
+ HttpResponse response = client.execute(post);
+ HttpEntity entity = response.getEntity();
+ is = entity.getContent();
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"), 8);
+ StringBuilder sb = new StringBuilder();
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (isCancelled()) break;
+ sb.append(line + "\n");
+ }
+ result = sb.toString();
+ } catch (java.lang.Exception e) {
+ logDebug("API request failed: " + e.getMessage());
+ // e.printStackTrace();
+ return null;
+ } finally {
+ try {
+ if (is != null) is.close();
+ } catch (IOException e) {
+ // e.printStackTrace();
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public void onPostExecute(String result) {
+ onDone(result);
+ }
+
+ }
+
+}
diff --git a/src/org/happysanta/gd/API/Response.java b/src/org/happysanta/gd/API/Response.java
new file mode 100644
index 0000000..827fae4
--- /dev/null
+++ b/src/org/happysanta/gd/API/Response.java
@@ -0,0 +1,26 @@
+package org.happysanta.gd.API;
+
+import org.happysanta.gd.API.*;
+import org.json.JSONArray;
+import org.json.JSONException;
+
+public class Response {
+
+ JSONArray jsonArray;
+
+ public Response(String result) throws JSONException, APIException {
+ jsonArray = new JSONArray(result);
+ if (!isOK()) {
+ throw new APIException(jsonArray.getString(1));
+ }
+ }
+
+ public boolean isOK() throws JSONException {
+ return jsonArray.getString(0).equals("ok");
+ }
+
+ public JSONArray getJSON() {
+ return jsonArray;
+ }
+
+}
diff --git a/src/org/happysanta/gd/API/ResponseHandler.java b/src/org/happysanta/gd/API/ResponseHandler.java
new file mode 100755
index 0000000..7b39c99
--- /dev/null
+++ b/src/org/happysanta/gd/API/ResponseHandler.java
@@ -0,0 +1,9 @@
+package org.happysanta.gd.API;
+
+public interface ResponseHandler {
+
+ public void onResponse(Response response);
+
+ public void onError(APIException error);
+
+}
diff --git a/src/org/happysanta/gd/Callback.java b/src/org/happysanta/gd/Callback.java
new file mode 100644
index 0000000..a2a2c3f
--- /dev/null
+++ b/src/org/happysanta/gd/Callback.java
@@ -0,0 +1,7 @@
+package org.happysanta.gd;
+
+public interface Callback {
+
+ public abstract void onDone(Object... objects);
+
+}
diff --git a/src/org/happysanta/gd/Command.java b/src/org/happysanta/gd/Command.java
new file mode 100755
index 0000000..821ddc9
--- /dev/null
+++ b/src/org/happysanta/gd/Command.java
@@ -0,0 +1,11 @@
+package org.happysanta.gd;
+
+public class Command {
+
+ public String title;
+
+ public Command(String title, int unused1, int unused2) {
+ this.title = title;
+ }
+
+}
diff --git a/src/org/happysanta/gd/CommandListener.java b/src/org/happysanta/gd/CommandListener.java
new file mode 100755
index 0000000..7af87e8
--- /dev/null
+++ b/src/org/happysanta/gd/CommandListener.java
@@ -0,0 +1,7 @@
+package org.happysanta.gd;
+
+public interface CommandListener {
+
+ public void commandAction(Command cmd);
+
+}
diff --git a/src/org/happysanta/gd/DoubleCallback.java b/src/org/happysanta/gd/DoubleCallback.java
new file mode 100644
index 0000000..f7d6b7e
--- /dev/null
+++ b/src/org/happysanta/gd/DoubleCallback.java
@@ -0,0 +1,7 @@
+package org.happysanta.gd;
+
+public interface DoubleCallback extends Callback {
+
+ public abstract void onFail();
+
+}
diff --git a/src/org/happysanta/gd/FileDialog.java b/src/org/happysanta/gd/FileDialog.java
new file mode 100644
index 0000000..78b0326
--- /dev/null
+++ b/src/org/happysanta/gd/FileDialog.java
@@ -0,0 +1,209 @@
+package org.happysanta.gd;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Environment;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class FileDialog {
+ private static final String PARENT_DIR = "..";
+ private final String TAG = getClass().getName();
+ private String[] fileList;
+ private File currentPath;
+
+ public interface FileSelectedListener {
+ void fileSelected(File file);
+ }
+
+ public interface DirectorySelectedListener {
+ void directorySelected(File directory);
+ }
+
+ private ListenerList<FileSelectedListener> fileListenerList = new ListenerList<FileDialog.FileSelectedListener>();
+ private ListenerList<DirectorySelectedListener> dirListenerList = new ListenerList<FileDialog.DirectorySelectedListener>();
+ private final Activity activity;
+ private boolean selectDirectoryOption = false;
+ private String fileEndsWith;
+
+ public FileDialog(Activity activity, File path, String fileEndsWith) {
+ this.activity = activity;
+ this.fileEndsWith = fileEndsWith != null ? fileEndsWith.toLowerCase() : fileEndsWith;
+ if (!path.exists()) path = Environment.getExternalStorageDirectory();
+ // logDebug("FileDialog contrustor, path = " + path);
+ loadFileList(path);
+ }
+
+ /**
+ * @return file dialog
+ */
+ public Dialog createFileDialog() {
+ Dialog dialog = null;
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+
+ builder.setTitle(currentPath.getPath());
+ if (selectDirectoryOption) {
+ builder.setPositiveButton("Select directory", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ Helpers.logDebug(currentPath.getParent());
+ // Log.d(TAG, currentPath.getPath());
+ fireDirectorySelectedEvent(currentPath);
+ }
+ });
+ }
+
+ builder.setItems(fileList, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ String fileChosen = fileList[which];
+ File chosenFile = getChosenFile(fileChosen);
+ if (chosenFile.isDirectory()) {
+ loadFileList(chosenFile);
+ dialog.cancel();
+ dialog.dismiss();
+ showDialog();
+ } else fireFileSelectedEvent(chosenFile);
+ }
+ });
+
+ dialog = builder.show();
+ return dialog;
+ }
+
+
+ public void addFileListener(FileSelectedListener listener) {
+ fileListenerList.add(listener);
+ }
+
+ public void removeFileListener(FileSelectedListener listener) {
+ fileListenerList.remove(listener);
+ }
+
+ public void setSelectDirectoryOption(boolean selectDirectoryOption) {
+ this.selectDirectoryOption = selectDirectoryOption;
+ }
+
+ public void addDirectoryListener(DirectorySelectedListener listener) {
+ dirListenerList.add(listener);
+ }
+
+ public void removeDirectoryListener(DirectorySelectedListener listener) {
+ dirListenerList.remove(listener);
+ }
+
+ /**
+ * Show file dialog
+ */
+ public void showDialog() {
+ createFileDialog().show();
+ }
+
+ private void fireFileSelectedEvent(final File file) {
+ fileListenerList.fireEvent(new ListenerList.FireHandler<FileSelectedListener>() {
+ public void fireEvent(FileSelectedListener listener) {
+ listener.fileSelected(file);
+ }
+ });
+ }
+
+ private void fireDirectorySelectedEvent(final File directory) {
+ dirListenerList.fireEvent(new ListenerList.FireHandler<DirectorySelectedListener>() {
+ public void fireEvent(DirectorySelectedListener listener) {
+ listener.directorySelected(directory);
+ }
+ });
+ }
+
+ private void loadFileList(File path) {
+ this.currentPath = path;
+
+ ArrayList<String> dirs = new ArrayList<>();
+ ArrayList<String> files = new ArrayList<>();
+ ArrayList<String> totalList = new ArrayList<>();
+
+ if (path.exists()) {
+ if (path.getParentFile() != null) dirs.add(PARENT_DIR);
+ FilenameFilter filter = new FilenameFilter() {
+ public boolean accept(File dir, String filename) {
+ File sel = new File(dir, filename);
+ if (!sel.canRead()) return false;
+ if (sel.isHidden()) return false;
+ if (selectDirectoryOption) return sel.isDirectory();
+ else {
+ boolean endsWith = fileEndsWith != null ? filename.toLowerCase().endsWith(fileEndsWith) : true;
+ return endsWith || sel.isDirectory();
+ }
+ }
+ };
+
+ File[] list = path.listFiles(filter);
+ try {
+ if (list != null && list.length > 0) {
+ for (File file : list) {
+ if (file.isDirectory())
+ dirs.add(file.getName() + "/");
+ else
+ files.add(file.getName());
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ Comparator<String> comparator = new Comparator<String>() {
+ @Override
+ public int compare(String lhs, String rhs) {
+ return lhs.compareTo(rhs);
+ }
+ };
+
+ Collections.sort(dirs, comparator);
+ Collections.sort(files, comparator);
+
+ totalList.addAll(dirs);
+ totalList.addAll(files);
+ }
+
+ fileList = totalList.toArray(new String[]{});
+ }
+
+ private File getChosenFile(String fileChosen) {
+ if (fileChosen.equals(PARENT_DIR)) return currentPath.getParentFile();
+ else return new File(currentPath, fileChosen);
+ }
+}
+
+class ListenerList<L> {
+ private List<L> listenerList = new ArrayList<L>();
+
+ public interface FireHandler<L> {
+ void fireEvent(L listener);
+ }
+
+ public void add(L listener) {
+ listenerList.add(listener);
+ }
+
+ public void fireEvent(FireHandler<L> fireHandler) {
+ List<L> copy = new ArrayList<L>(listenerList);
+ for (L l : copy) {
+ fireHandler.fireEvent(l);
+ }
+ }
+
+ public void remove(L listener) {
+ listenerList.remove(listener);
+ }
+
+ public List<L> getListenerList() {
+ return listenerList;
+ }
+} \ No newline at end of file
diff --git a/src/org/happysanta/gd/GDActivity.java b/src/org/happysanta/gd/GDActivity.java
new file mode 100755
index 0000000..88876a6
--- /dev/null
+++ b/src/org/happysanta/gd/GDActivity.java
@@ -0,0 +1,1177 @@
+package org.happysanta.gd;
+
+import android.app.Activity;
+import android.app.AlarmManager;
+import android.app.AlertDialog;
+import android.app.PendingIntent;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.text.Html;
+import android.view.*;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import org.happysanta.gd.API.*;
+import org.happysanta.gd.Game.*;
+import org.happysanta.gd.Levels.Loader;
+import org.happysanta.gd.Menu.Views.MenuHelmetView;
+import org.happysanta.gd.Menu.Views.MenuImageView;
+import org.happysanta.gd.Menu.Views.MenuLinearLayout;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+import org.happysanta.gd.Menu.Views.MenuTitleLinearLayout;
+import org.happysanta.gd.Menu.Views.ObservableScrollView;
+import org.happysanta.gd.Storage.LevelsManager;
+import org.acra.util.Installation;
+import org.json.JSONObject;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class GDActivity extends Activity implements Runnable {
+
+ public static GDActivity shared = null;
+ public static final int MENU_TITLE_LAYOUT_TOP_PADDING = 25;
+ public static final int MENU_TITLE_LAYOUT_BOTTOM_PADDING = 13;
+ public static final int MENU_TITLE_LAYOUT_X_PADDING = 30;
+ public static final int MENU_TITLE_FONT_SIZE = 30;
+ public static final int GAME_MENU_BUTTON_LAYOUT_WIDTH = 40;
+ public static final int GAME_MENU_BUTTON_LAYOUT_HEIGHT = 56;
+
+ private static final long IMAGES_DELAY = 1000L;
+ private static final long IMAGES_DELAY_DEBUG = 100L;
+
+ public int m_longI = 0;
+
+ private boolean wasPaused = false;
+ private boolean wasStarted = false;
+ private boolean wasDestroyed = false;
+ private boolean restartingStarted = false;
+ public boolean alive = false;
+ public boolean m_cZ = true;
+ private boolean menuShown = false;
+ public boolean fullResetting = false;
+ public boolean exiting = false;
+
+ public GameView gameView = null;
+ // public MenuView menuView = null;
+ public Loader levelLoader;
+ public Physics physEngine;
+ public org.happysanta.gd.Menu.Menu menu;
+ public boolean m_caseZ;
+ public int m_nullI;
+ public long m_forJ;
+ // public long seconds;
+ public long startedTime = 0;
+ public long finishedTime = 0;
+ public long pausedTime = 0;
+ public long pausedTimeStarted = 0;
+ public long m_byteJ;
+ public boolean inited = false;
+ public boolean m_ifZ;
+ private Thread thread;
+ private MenuImageView menuBtn;
+ public MenuTitleLinearLayout titleLayout;
+ public ObservableScrollView scrollView;
+ private FrameLayout frame;
+ private MenuLinearLayout menuLayout;
+ private KeyboardController keyboardController;
+ private boolean isNormalAndroid = true;
+ private boolean buttonCoordsCalculated = false;
+ public TextView menuTitleTextView;
+ private boolean menuReady = false;
+ private ArrayList<Command> commands = new ArrayList<Command>();
+ private MenuLinearLayout keyboardLayout;
+ private MenuTextView portedTextView;
+ private int buttonHeight = 60;
+ public LevelsManager levelsManager;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ shared = this;
+
+ if (Helpers.isSDK10OrLower()) {
+ isNormalAndroid = false;
+ }
+
+ final GDActivity self = this;
+ Request request = API.getNotifications(Global.INSTALLED_FROM_APK, new ResponseHandler() {
+ @Override
+ public void onResponse(final Response apiResponse) {
+ try {
+ final NotificationsResponse response = new NotificationsResponse(apiResponse);
+ if (!response.isEmpty()) {
+ final Runnable onOk = new Runnable() {
+ @Override
+ public void run() {
+ if (response.hasURL()) {
+ String url = response.getURL();
+ try {
+ Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
+ startActivity(browserIntent);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ };
+
+ if (response.hasTwoButtons()) {
+ AlertDialog.Builder alert = new AlertDialog.Builder(self)
+ .setTitle(response.getTitle())
+ .setMessage(response.getMessage())
+ .setPositiveButton(response.getOKButton(), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onOk.run();
+ }
+ })
+ .setNegativeButton(response.getCancelButton(), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+
+ }
+ });
+ alert.show();
+ } else {
+ AlertDialog alertDialog = new AlertDialog.Builder(self)
+ .setTitle(response.getTitle())
+ .setMessage(response.getMessage())
+ .setPositiveButton(response.getOKButton(), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ onOk.run();
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ }
+ })
+ .create();
+ alertDialog.show();
+ }
+ }
+ } catch (Exception e) {
+ // e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void onError(APIException error) {
+
+ }
+ });
+
+ if (true) {
+ gameView = new GameView(this);
+
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+
+ scrollView = new ObservableScrollView(this);
+ scrollView.setBackgroundColor(0x00ffffff);
+ scrollView.setFillViewport(true);
+ scrollView.setOnScrollListener(new ObservableScrollView.OnScrollListener() {
+ @Override
+ public void onScroll(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
+ if (isMenuShown() && menu != null && menu.currentMenu != null) {
+ int h = scrollView.getChildAt(0).getHeight() - scrollView.getHeight();
+ double p = 100.0 * y / h;
+ if (p > 100f)
+ p = 100f;
+
+ menu.currentMenu.onScroll(p);
+ }
+ }
+ });
+ scrollView.setVisibility(View.GONE);
+
+ frame = new FrameLayout(this);
+ frame.setBackgroundColor(0xffffffff);
+
+ titleLayout = new MenuTitleLinearLayout(this);
+ titleLayout.setBackgroundColor(0x00ffffff);
+ titleLayout.setGravity(Gravity.TOP);
+ titleLayout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+ titleLayout.setPadding(Helpers.getDp(MENU_TITLE_LAYOUT_X_PADDING), Helpers.getDp(MENU_TITLE_LAYOUT_TOP_PADDING), Helpers.getDp(MENU_TITLE_LAYOUT_X_PADDING), Helpers.getDp(MENU_TITLE_LAYOUT_BOTTOM_PADDING));
+
+ menuTitleTextView = new TextView(this);
+ menuTitleTextView.setText(getString(R.string.main));
+ menuTitleTextView.setTextColor(0xff000000);
+ menuTitleTextView.setTypeface(Global.robotoCondensedTypeface);
+ menuTitleTextView.setTextSize(MENU_TITLE_FONT_SIZE);
+ menuTitleTextView.setLineSpacing(0f, 1.1f);
+ menuTitleTextView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ));
+ menuTitleTextView.setVisibility(android.view.View.GONE);
+
+ titleLayout.addView(menuTitleTextView);
+
+ scrollView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, 1));
+
+ // Keyboard
+ String[] buttonResources = {
+ "btn_br", "btn_br", "btn_b",
+ "btn_br", "btn_br", "btn_b",
+ "btn_r", "btn_r", "btn_n"
+ };
+ if (getString(R.string.screen_type).equals("tablet")) {
+ buttonHeight = 85;
+ } else if (Global.density < 1.5) {
+ buttonHeight = 55;
+ }
+
+ keyboardLayout = new MenuLinearLayout(this, true);
+ keyboardLayout.setOrientation(LinearLayout.VERTICAL);
+
+ keyboardController = new KeyboardController(this);
+
+ for (int i = 0; i < 3; i++) {
+ LinearLayout row = new LinearLayout(this);
+ row.setPadding(Helpers.getDp(KeyboardController.PADDING), i == 0 ? Helpers.getDp(KeyboardController.PADDING) : 0, Helpers.getDp(KeyboardController.PADDING), 0);
+ row.setOrientation(LinearLayout.HORIZONTAL);
+ row.setBackgroundColor(0xc6ffffff);
+ for (int j = 0; j < 3; j++) {
+ LinearLayout btn = new LinearLayout(this);
+ TextView btnText = new TextView(this);
+ btnText.setText(String.valueOf(i * 3 + j + 1));
+ btnText.setTextColor(0xff000000);
+ btnText.setTextSize(17);
+ btn.setBackgroundResource(getResources().getIdentifier(buttonResources[i * 3 + j], "drawable", getPackageName()));
+ btn.addView(btnText, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+ btn.setGravity(Gravity.CENTER);
+ btn.setWeightSum(1);
+
+ row.addView(btn, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, Helpers.getDp(buttonHeight), 1));
+
+ keyboardController.addButton(btn, j, i);
+ }
+
+ keyboardLayout.addView(row);
+ }
+
+ keyboardLayout.setGravity(Gravity.BOTTOM);
+ keyboardLayout.setPadding(0, 0, 0, Helpers.getDp(KeyboardController.PADDING));
+ keyboardLayout.setOnTouchListener(keyboardController);
+ keyboardLayout.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM));
+
+ hideKeyboardLayout();
+
+ menuBtn = new MenuImageView(this);
+ menuBtn.setImageResource(R.drawable.ic_menu);
+ menuBtn.setScaleType(ImageView.ScaleType.CENTER);
+ menuBtn.setLayoutParams(new FrameLayout.LayoutParams(Helpers.getDp(GAME_MENU_BUTTON_LAYOUT_WIDTH), Helpers.getDp(GAME_MENU_BUTTON_LAYOUT_HEIGHT), Gravity.RIGHT | Gravity.TOP));
+ menuBtn.setOnClickListener(new android.view.View.OnClickListener() {
+ @Override
+ public void onClick(android.view.View v) {
+ gameView.showMenu();
+ }
+ });
+ menuBtn.setVisibility(android.view.View.GONE);
+
+ menuLayout = new MenuLinearLayout(this);
+ menuLayout.setOrientation(LinearLayout.VERTICAL);
+ menuLayout.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT
+ ));
+
+ portedTextView = new MenuTextView(this);
+ portedTextView.setTypeface(Global.robotoCondensedTypeface);
+ portedTextView.setTextSize(15);
+ portedTextView.setLineSpacing(0f, 1.2f);
+ portedTextView.setText(Html.fromHtml(getString(R.string.ported_text)));
+ portedTextView.setGravity(Gravity.CENTER);
+ portedTextView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM));
+ portedTextView.setPadding(0, 0, 0, Helpers.getDp(10));
+
+ menuLayout.addView(titleLayout);
+ menuLayout.addView(scrollView);
+
+ frame.addView(menuLayout);
+ frame.addView(keyboardLayout);
+ frame.addView(menuBtn);
+ frame.addView(portedTextView);
+
+ gameView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT, 1));
+ frame.addView(gameView, 0);
+
+ setContentView(frame);
+
+ gameView._doIV(1); // flag for 1st image, as I understand..
+ thread = null;
+ m_caseZ = false;
+ m_nullI = 2;
+ m_forJ = 0;
+ m_byteJ = 0;
+ inited = false;
+ m_ifZ = false;
+ wasDestroyed = false;
+ restartingStarted = false;
+
+ frame.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ frame.getViewTreeObserver().removeOnPreDrawListener(this);
+ // setButtonsLayoutHeight();
+ doStart();
+ return true;
+ }
+ });
+
+
+
+ /* gameView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ gameView.getViewTreeObserver().removeOnPreDrawListener(this);
+ doStart();
+ return true;
+ }
+ }); */
+
+ /* alive = true;
+ m_cZ = false;
+
+ Thread.currentThread().setName("main_thread");
+
+ if (thread == null) {
+ thread = new Thread(this);
+ thread.setName("game_thread");
+ } */
+
+ /*synchronized (thread) {
+ thread.start();
+ try {
+ thread.wait();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+ for (int i = 1; i <= 4; i++) {
+ menu.load(i);
+ }
+
+ wasStarted = true;*/
+ }
+ }
+
+ protected void doStart() {
+ alive = true;
+ m_cZ = false;
+
+ Thread.currentThread().setName("main_thread");
+
+ if (thread == null) {
+ thread = new Thread(this);
+ thread.setName("game_thread");
+ thread.start();
+ }
+
+ wasStarted = true;
+ }
+
+ // protected boolean viewDone = false;
+
+ @Override
+ public void run() {
+ Helpers.logDebug("!!! run()");
+ long l1;
+
+ if (!inited) {
+ Helpers.logDebug("run(): initing");
+ try {
+ // Game view
+ /* gameView = new GameView(shared);
+ gameView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT, 1));
+ frame.addView(gameView, 0); */
+
+ /* gameView._doIV(1);
+ thread = null;
+ m_caseZ = false;
+ m_nullI = 2;
+ m_forJ = 0L;
+ seconds = 0L;
+ m_byteJ = 0L;
+ inited = false;
+ m_ifZ = false; */
+
+ long imageDelay = Global.DEBUG ? IMAGES_DELAY_DEBUG : IMAGES_DELAY; // delay of first image
+ Thread.yield();
+
+ /*gameView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ gameView.getViewTreeObserver().removeOnPreDrawListener(this);
+ viewDone = true;
+ logDebug("gameView is ready");
+ //doStart();
+ return true;
+ }
+ });
+
+ logDebug("before while..");
+ while (!viewDone) {
+ // Thread.sleep(1);
+ }
+ logDebug("after while..");*/
+
+ // do we really need this?!
+ /*while (gameView == null || gameView.getParent() == null) {
+ try {
+ Thread.sleep(100);
+ } catch (Exception x) {}
+ }*/
+
+ MenuHelmetView.clearStaticFields();
+
+ levelsManager = new LevelsManager();
+ try {
+ levelLoader = new Loader(levelsManager.getCurrentLevelsFile());
+ } catch (IOException e) {
+ e.printStackTrace();
+ // logDebug("Reset level id now");
+ levelsManager.resetId();
+ levelsManager.reload();
+
+ levelLoader = new Loader(levelsManager.getCurrentLevelsFile());
+ }
+
+ physEngine = new Physics(levelLoader);
+ gameView.setPhysicsEngine(physEngine);
+
+ // logDebug(levelsManager.getLevelsStat());
+ sendStats();
+
+ /* synchronized (Thread.currentThread()) {
+ Thread.currentThread().notify();
+ } */
+ menu = new org.happysanta.gd.Menu.Menu();
+ // menu = null;
+ // menu.hideKeyboard();
+ for (int i = 1; i <= 4; i++) {
+ menu.load(i);
+ }
+
+ // menu = new Menu();
+ // menu.hideKeyboard();
+
+ /*menu.load(1);
+ menu.load(2);
+ menu.load(3);
+
+ Runnable createMenuRunnable = new Runnable() {
+ @Override
+ public void run() {
+ menu.load(4);
+ synchronized (this) {
+ notify();
+ }
+ }
+ };
+
+ synchronized (createMenuRunnable) {
+ // logDebug("before runOnUiThread()");
+ runOnUiThread(createMenuRunnable);
+ try {
+ // logDebug("before wait()");
+ createMenuRunnable.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }*/
+
+ portedTextView.setVisibility(View.VISIBLE);
+
+ gameView.setMenu(menu);
+ gameView._doIIV(-50, 150);
+ setMode(1);
+
+ // Show first image
+ Helpers.logDebug("show first image");
+ long l2;
+ for (; imageDelay > 0L; imageDelay -= l2)
+ l2 = _avJ();
+
+ // Show second image
+ portedTextView.setVisibility(View.GONE);
+ Helpers.logDebug("show second image");
+ imageDelay = Global.DEBUG ? IMAGES_DELAY_DEBUG : IMAGES_DELAY;
+ gameView._doIV(2);
+ long l3;
+ for (long l4 = imageDelay; l4 > 0L; l4 -= l3)
+ l3 = _avJ();
+
+ while (m_longI < 10)
+ _avJ();
+
+ gameView._doIV(0);
+ Helpers.logDebug("images DONE");
+ inited = true;
+
+ } catch (Exception _ex) {
+ _ex.printStackTrace();
+ // Log.w("GDTR", _ex);
+ throw new RuntimeException(_ex);
+ }
+ }
+
+ // logDebug("inited, continue");
+
+ restart(false);
+ // logDebug("showMenu() now");
+
+ /*if (menu != null) */
+ menu.showMenu(0);
+ if (/*menu != null && */menu.canStartTrack())
+ restart(true);
+ l1 = 0L;
+
+ // try {
+ Helpers.logDebug("start main loop");
+ while (alive) {
+ /*if (!alive) {
+ logDebug("!alive");
+ break;
+ }*/
+
+ // try {
+ if (physEngine._bytevI() != menu._jvI()) {
+ int j = gameView._intII(menu._jvI());
+ physEngine._doIV(j);
+ menu._intIV(j);
+ }
+
+ if (menuShown) {
+ menu.showMenu(1);
+ if (menu.canStartTrack())
+ restart(true);
+ }
+
+ for (int i1 = m_nullI; i1 > 0 && alive; i1--) {
+ /* if (m_ifZ)
+ seconds += 20L; */
+ if (m_forJ == 0L)
+ m_forJ = System.currentTimeMillis();
+ int k = 0;
+ if (/*physEngine != null && */(k = physEngine._dovI()) == 3 && m_byteJ == 0L) {
+ m_byteJ = System.currentTimeMillis() + 3000L;
+ gameView.showInfoMessage(getString(R.string.crashed), 3000);
+ //m_di.postInvalidate();
+ //m_di.serviceRepaints();
+ }
+ if (m_byteJ != 0L && m_byteJ < System.currentTimeMillis())
+ restart(true);
+ if (k == 5) {
+ finishedTime = System.currentTimeMillis();
+ gameView.showInfoMessage(getString(R.string.crashed), 3000);
+ //m_di.postInvalidate();
+ //m_di.serviceRepaints();
+ try {
+ long l2 = 1000L;
+ if (m_byteJ > 0L)
+ l2 = Math.min(m_byteJ - System.currentTimeMillis(), 1000L);
+ if (l2 > 0L)
+ Thread.sleep(l2);
+ } catch (InterruptedException _ex) {
+ }
+ restart(true);
+ } else if (k == 4) {
+ // logDebug("k == 4");
+ m_forJ = 0;
+ // seconds = 0;
+ startedTime = 0;
+ finishedTime = 0;
+ pausedTime = 0;
+ } else if (k == 1 || k == 2) {
+ finishedTime = System.currentTimeMillis();
+ // logDebug("game-run: k = " + k);
+ /* if (k == 2)
+ seconds -= 10L; */
+ goalLoop();
+ // menu.setLastTrackTime(seconds / 10L);
+ menu.setLastTrackTime((finishedTime - startedTime) / 10);
+ menu.showMenu(2);
+
+ if (menu.canStartTrack())
+ restart(true);
+ if (!alive) {
+ Helpers.logDebug("!alive (2)");
+ break;
+ }
+ }
+ m_ifZ = k != 4;
+ if (m_ifZ && startedTime == 0) {
+ startedTime = System.currentTimeMillis();
+ }
+ }
+
+ if (!alive) {
+ Helpers.logDebug("!alive (3)");
+ break;
+ }
+
+ //try {
+ /*if (physEngine != null)*/
+ physEngine._charvV();
+ long l;
+ if ((l = System.currentTimeMillis()) - l1 < 30L) {
+ try {
+ synchronized (this) {
+ wait(Math.max(30L - (l - l1), 1L));
+ }
+ } catch (InterruptedException interruptedexception) {
+ }
+ l1 = System.currentTimeMillis();
+ } else {
+ l1 = l;
+ }
+ //m_di.postInvalidate();
+ /*} catch (Exception exception) {
+ exception.printStackTrace();
+ }*/
+ }
+ // } catch (Exception e) {
+ // e.printStackTrace();
+ //}
+
+ Helpers.logDebug("game thread finished, destroyApp(false) next");
+
+ // finish();
+ destroyApp(false);
+ // return;
+ }
+
+ @Override
+ protected void onResume() {
+ Helpers.logDebug("@@@ [GDActivity \"+hashCode()+\"] onResume()");
+ super.onResume();
+ Helpers.logDebug("[GDActivity \"+hashCode()+\"] onResume(), inited = " + inited);
+ if (wasPaused && wasStarted) {
+ // logDebug("onResume(): wasPaused && wasResumed");
+ // start();
+ m_cZ = false;
+ wasPaused = false;
+
+ // Menu.HelmetRotation.start();
+ }
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+
+ Helpers.logDebug("@@@ [GDActivity " + hashCode() + "] onPause()");
+
+ wasPaused = true;
+ m_cZ = true;
+ Helpers.logDebug("inited : " + inited);
+ if (!menuShown && inited)
+ gameToMenu();
+
+ // menu.helmetRotationStop();
+ // Menu.HelmetRotation.stop();
+ // if (menu != null)
+ // menu.saveAll();
+ // levelsManager.updateLevelSettings();
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ Helpers.logDebug("@@@ [GDActivity " + hashCode() + "] onDestroy()");
+ destroyApp(false);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ Helpers.logDebug("@@@ [GDActivity " + hashCode() + "] onStop()");
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ Helpers.logDebug("@@@ [GDActivity " + hashCode() + "] onStart()");
+ }
+
+ @Override
+ protected void onRestart() {
+ super.onRestart();
+ Helpers.logDebug("@@@ [GDActivity " + hashCode() + "] onRestart()");
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (gameView != null && menu != null && inited) {
+ if (menuShown)
+ menu.back();
+ else
+ gameView.showMenu();
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(android.view.Menu menu) {
+ menu.clear();
+ int id = 1;
+ for (Command cmd : commands) {
+ MenuItem item = menu.add(0, id, 0, cmd.title);
+ id++;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ gameView.commandAction(commands.get(item.getItemId() - 1));
+ return true;
+ }
+
+ public void setMode(int j) {
+ physEngine._byteIV(j);
+ }
+
+ public boolean isMenuShown() {
+ return menuShown;
+ }
+
+ // @UiThread
+ public void setMenu(final LinearLayout layout) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ scrollView.removeAllViews();
+ if (layout.getParent() != null) {
+ ((ViewManager) layout.getParent()).removeView(layout);
+ }
+ scrollView.addView(layout);
+ }
+ });
+ }
+
+ public void goalLoop() {
+ if (!alive) {
+ return;
+ }
+
+ long l1 = 0L;
+ if (!physEngine.m_NZ)
+ gameView.showInfoMessage(getString(R.string.wheelie), 1000);
+ else
+ gameView.showInfoMessage(getString(R.string.finished1), 1000);
+ for (long l2 = System.currentTimeMillis() + 1000L; l2 > System.currentTimeMillis(); gameView.postInvalidate()) {
+ if (menuShown) {
+ //m_di.postInvalidate();
+ return;
+ }
+ for (int j = m_nullI; j > 0; j--)
+ if (physEngine._dovI() == 5)
+ try {
+ long l3;
+ if ((l3 = l2 - System.currentTimeMillis()) > 0L)
+ Thread.sleep(l3);
+ return;
+ } catch (InterruptedException _ex) {
+ return;
+ }
+
+ physEngine._charvV();
+ long l;
+ if ((l = System.currentTimeMillis()) - l1 < 30L) {
+ try {
+ synchronized (this) {
+ wait(Math.max(30L - (l - l1), 1L));
+ }
+ } catch (InterruptedException interruptedexception) {
+ }
+ l1 = System.currentTimeMillis();
+ } else {
+ l1 = l;
+ }
+ }
+ }
+
+ public void restart(boolean flag) {
+ // logDebug("[GDActivity] restart()");
+ if (!alive) {
+ return;
+ }
+
+ physEngine._doZV(true);
+ // logDebug("[GDActivity] restart(): 1");
+ m_forJ = 0;
+ // seconds = 0;
+ startedTime = 0;
+ finishedTime = 0;
+ pausedTime = 0;
+ m_byteJ = 0;
+ if (flag)
+ gameView.showInfoMessage(levelLoader.getLevelName(menu.getSelectedLevel(), menu.getSelectedTrack()), 3000);
+ // logDebug("[GDActivity] restart(): 2");
+ gameView._casevV();
+ // logDebug("[GDActivity] restart(): 3");
+ }
+
+ public void destroyApp(final boolean restart) {
+ if (wasDestroyed) {
+ return;
+ }
+
+ wasDestroyed = true;
+ alive = false;
+
+ final GDActivity self = this;
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Helpers.logDebug("[GDActivity " + self.hashCode() + "] destroyApp()");
+ inited = false;
+ m_caseZ = true;
+
+ synchronized (gameView) {
+ destroyResources();
+
+ if (exiting || restart) {
+ finish();
+ }
+
+ if (restart) {
+ doRestartApp();
+ }
+ }
+ }
+ });
+ }
+
+ private void destroyResources() {
+ Helpers.logDebug("[GDActivity " + hashCode() + "] destroyResources()");
+
+ // if (thread != null) thread.interrupt();
+ if (gameView != null) gameView.destroy();
+
+ menuShown = false;
+ if (menu != null) {
+ if (!fullResetting) menu.saveAll();
+ menu.destroy();
+ }
+
+ if (levelsManager != null) levelsManager.closeDataSource();
+ }
+
+ public int getButtonsLayoutHeight() {
+ return buttonHeight * 3 + KeyboardController.PADDING * 2;
+ }
+
+ // @UiThread
+ public void hideKeyboardLayout() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ keyboardLayout.setVisibility(android.view.View.GONE);
+
+ LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) scrollView.getLayoutParams();
+ params.setMargins(0, 0, 0, 0);
+ scrollView.setLayoutParams(params);
+ }
+ });
+ }
+
+ // @UiThread
+ public void showKeyboardLayout() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ keyboardLayout.setVisibility(android.view.View.VISIBLE);
+
+ LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) scrollView.getLayoutParams();
+ params.setMargins(0, 0, 0, Helpers.getDp(getButtonsLayoutHeight()));
+ scrollView.setLayoutParams(params);
+ }
+ });
+ }
+
+ public void addCommand(Command cmd) {
+ if (!commands.contains(cmd))
+ commands.add(cmd);
+ if (isNormalAndroid)
+ invalidateOptionsMenu();
+ }
+
+ public void removeCommand(Command cmd) {
+ commands.remove(cmd);
+ if (isNormalAndroid)
+ invalidateOptionsMenu();
+ }
+
+ public void gameToMenu() {
+ Helpers.logDebug("gameToMenu()");
+
+ if (gameView == null) {
+ Helpers.logDebug("gameToMenu(): gameView == null");
+ return;
+ }
+
+ pausedTimeStarted = System.currentTimeMillis();
+
+ gameView.removeMenuCommand();
+ menuShown = true;
+ // menu.helmetRotationStart();
+ // Menu.HelmetRotation.start();
+ if (menu != null)
+ menu.addCommands();
+
+ // hideKeyboardLayout();
+ if (!Settings.isKeyboardInMenuEnabled())
+ hideKeyboardLayout();
+ else
+ showKeyboardLayout();
+
+ gameToMenuUpdateUi();
+ }
+
+ // @UiThread
+ protected void gameToMenuUpdateUi() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ menuBtn.setVisibility(android.view.View.GONE);
+ menuTitleTextView.setVisibility(android.view.View.VISIBLE);
+ scrollView.setVisibility(android.view.View.VISIBLE);
+ }
+ });
+ }
+
+ public void menuToGame() {
+ Helpers.logDebug("menuToGame()");
+
+ if (pausedTimeStarted > 0 && startedTime > 0) {
+ pausedTime += (System.currentTimeMillis() - pausedTimeStarted);
+ pausedTimeStarted = 0;
+ }
+
+ if (menu != null) menu.removeCommands();
+ menuShown = false;
+ // menu.helmetRotationStop();
+ // Menu.HelmetRotation.stop();
+ if (gameView != null) gameView.addMenuCommand();
+ showKeyboardLayout();
+ // menu.showKeyboard();
+
+ menuToGameUpdateUi();
+
+ keyboardController.clearLogBuffer();
+ }
+
+ // @UiThread
+ protected void menuToGameUpdateUi() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ menuBtn.setVisibility(android.view.View.VISIBLE);
+ menuTitleTextView.setVisibility(android.view.View.GONE);
+ scrollView.setVisibility(android.view.View.GONE);
+
+ // Clear menu
+ scrollView.removeAllViews();
+ menuTitleTextView.setText("");
+ menu.menuDisabled = true;
+ // menu.currentMenu = null;
+ }
+ });
+ }
+
+ public void scrollTextMenuUp() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ int y = scrollView.getScrollY();
+ scrollView.scrollTo(0, y - Helpers.getDp(20));
+ }
+ });
+ }
+
+ public void scrollTextMenuDown() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ int y = scrollView.getScrollY();
+ scrollView.scrollTo(0, y + Helpers.getDp(20));
+ }
+ });
+ }
+
+ public void scrollToView(final View view) {
+ final GDActivity gd = Helpers.getGDActivity();
+ final ObservableScrollView scrollView = gd.scrollView;
+
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ Rect scrollBounds = new Rect();
+ scrollView.getHitRect(scrollBounds);
+
+ if (!view.getLocalVisibleRect(scrollBounds)
+ || scrollBounds.height() < view.getHeight()) {
+ int top = view.getTop(),
+ height = view.getHeight(),
+ scrollY = scrollView.getScrollY(),
+ scrollHeight = scrollView.getHeight(),
+ y = top;
+
+ /*logDebug("top = " + top);
+ logDebug("height = " + height);
+ logDebug("scrollY = " + scrollY);
+ logDebug("scrollHeight = " + scrollHeight);*/
+
+ if (top < scrollY) {
+ // scroll to y
+ } else if (top + height > scrollY + scrollHeight) {
+ y = top + height - scrollHeight;
+ if (y < 0)
+ y = 0;
+ }
+
+ // logDebug("View is not visible, scroll to y = " + y);
+ scrollView.scrollTo(0, y);
+ } else {
+ // logDebug("View is visible");
+ }
+ }
+ });
+ }
+
+ private long _avJ() {
+ m_longI++;
+ long l = System.currentTimeMillis();
+ if (m_longI < 1 || m_longI > 10) { // maybe < 1 not needed?
+ m_longI--;
+ try {
+ Thread.sleep(100L);
+ } catch (InterruptedException _ex) {
+ }
+ }
+ return System.currentTimeMillis() - l;
+ }
+
+ public void restartApp() {
+ if (!restartingStarted) {
+ destroyApp(true);
+ restartingStarted = true;
+ }
+ }
+
+ private void doRestartApp() {
+ Intent mStartActivity = new Intent(this, GDActivity.class);
+ int mPendingIntentId = 123456;
+ PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
+ AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+ mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
+ }
+
+ private void sendStats() {
+ long lastTs = Settings.getLastSendStats();
+ Helpers.logDebug("sendStats: lastTs = " + lastTs);
+ if (lastTs == 0) {
+ Helpers.logDebug("sendStats: set it to current ts and return");
+ Settings.setLastSendStats(Helpers.getTimestamp());
+ return;
+ }
+
+ // if (Helpers.getTimestamp() < lastTs + 3600 * 8) {
+ if (Helpers.getTimestamp() < lastTs + 10) {
+ Helpers.logDebug("sendStats: just return");
+ return;
+ }
+
+ final GDActivity self = this;
+ Thread statsThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ HashMap<String, Double> stats = levelsManager.getLevelsStat();
+
+ JSONObject statsJSON = new JSONObject(stats);
+ String id = Installation.id(self);
+ int useCheats = org.happysanta.gd.Menu.Menu.isNameCheat(Settings.getName()) ? 1 : 0;
+
+ API.sendStats(statsJSON.toString(), id, useCheats, new ResponseHandler() {
+ @Override
+ public void onResponse(Response response) {
+ Helpers.logDebug("send stats OK");
+ Settings.setLastSendStats(Helpers.getTimestamp());
+ }
+
+ @Override
+ public void onError(APIException error) {
+ Helpers.logDebug("send stats error: " + error.getMessage());
+ // logDebug(error);
+ // error.printStackTrace();
+ }
+ });
+ } catch (Exception e) {
+ Helpers.logDebug("send stats exception: " + e.getMessage());
+ // e.printStackTrace();
+ }
+ }
+ };
+ statsThread.start();
+ }
+
+ public void sendKeyboardLogs() {
+ final ProgressDialog progressDialog = ProgressDialog.show(this, getString(R.string.please_wait), getString(R.string.please_wait), true);
+ API.sendKeyboardLogs(keyboardController.getLog(), new ResponseHandler() {
+ @Override
+ public void onResponse(Response response) {
+ progressDialog.dismiss();
+ keyboardController.clearLogBuffer();
+ Helpers.showAlert(getString(R.string.ok), "Done", null);
+ }
+
+ @Override
+ public void onError(APIException error) {
+ progressDialog.dismiss();
+ Helpers.showAlert(getString(R.string.error), "Unable to send logs. Maybe log is empty?", null);
+ }
+ });
+ }
+
+ private class ButtonCoords {
+
+ public int x = 0;
+ public int y = 0;
+ public int w = 0;
+ public int h = 0;
+
+ public ButtonCoords() {
+ }
+
+ public boolean in(float x, float y) {
+ if (x < this.x || x > this.x + this.w || y < this.y || y > this.y + this.h) {
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/src/org/happysanta/gd/GDApplication.java b/src/org/happysanta/gd/GDApplication.java
new file mode 100644
index 0000000..120a5a7
--- /dev/null
+++ b/src/org/happysanta/gd/GDApplication.java
@@ -0,0 +1,24 @@
+package org.happysanta.gd;
+
+import android.app.Application;
+import org.acra.*;
+import org.acra.annotation.*;
+
+import static org.acra.ReportField.*;
+
+@ReportsCrashes(
+ formKey = "",
+ formUri = "http://gdtr.net/report.php",
+ customReportContent = {APP_VERSION_NAME, APP_VERSION_CODE, ANDROID_VERSION, PHONE_MODEL, PRODUCT, DISPLAY, STACK_TRACE, LOGCAT, USER_CRASH_DATE, INSTALLATION_ID, CUSTOM_DATA}
+)
+public class GDApplication extends Application {
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ if (Global.ACRA_ENABLED) {
+ ACRA.init(this);
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/org/happysanta/gd/Game/Bitmap.java b/src/org/happysanta/gd/Game/Bitmap.java
new file mode 100755
index 0000000..087a865
--- /dev/null
+++ b/src/org/happysanta/gd/Game/Bitmap.java
@@ -0,0 +1,184 @@
+package org.happysanta.gd.Game;
+
+import org.happysanta.gd.Global;
+import org.happysanta.gd.R;
+
+import java.io.IOException;
+
+import static org.happysanta.gd.Helpers.*;
+
+public class Bitmap {
+
+ public final static int HELMET = 0;
+ public final static int CODEBREW_LOGO = 1;
+ public final static int GD_LOGO = 2;
+ public final static int STEERING = 3;
+ public final static int WHEELS = 4;
+ public final static int ARROWS = 5;
+ public final static int FLAGS = 6;
+ public final static int LOCKS = 7;
+ public final static int MEDALS = 8;
+ public final static int LEVELS_WHEELS = 9;
+ public final static int FENDER = 10;
+ public final static int ENGINE = 11;
+ public final static int BIKER = 12;
+
+ public final static int BLUEARM = 100;
+ public final static int BLUELEG = 101;
+ public final static int BLUEBODY = 102;
+
+ public android.graphics.Bitmap bitmap;
+ protected static GDBitmapHolder holders[];
+ protected static Bitmap empty = null;
+
+ Bitmap(android.graphics.Bitmap b) {
+ bitmap = b;
+ }
+
+ static {
+ holders = new GDBitmapHolder[]{
+ // 0
+ new GDBitmapHolder(Bitmap.fromDrawable(R.drawable.s_helmet)),
+
+ // 1
+ new GDBitmapHolder(Bitmap.fromDrawable(R.drawable.codebrew)),
+
+ // 2
+ new GDBitmapHolder(Bitmap.fromDrawable(R.drawable.gd)),
+
+ // 3
+ new GDBitmapHolder(Bitmap.fromDrawable(R.drawable.s_steering)),
+
+ // 4
+ new GDBitmapHolder(new Bitmap[]{
+ Bitmap.fromDrawable(R.drawable.s_wheel1),
+ Bitmap.fromDrawable(R.drawable.s_wheel2)
+ }),
+
+ // 5
+ new GDBitmapHolder(new Bitmap[]{
+ Bitmap.fromDrawable(R.drawable.s_arrow_up),
+ Bitmap.fromDrawable(R.drawable.s_arrow_down)
+ }),
+
+ // 6
+ new GDBitmapHolder(new Bitmap[]{
+ Bitmap.fromDrawable(R.drawable.s_flag_start0),
+ Bitmap.fromDrawable(R.drawable.s_flag_start1),
+ Bitmap.fromDrawable(R.drawable.s_flag_start2),
+ Bitmap.fromDrawable(R.drawable.s_flag_finish0),
+ Bitmap.fromDrawable(R.drawable.s_flag_finish1),
+ Bitmap.fromDrawable(R.drawable.s_flag_finish2)
+ }),
+
+ // 7
+ new GDBitmapHolder(new Bitmap[]{
+ Bitmap.fromDrawable(R.drawable.s_lock0),
+ Bitmap.fromDrawable(R.drawable.s_lock1),
+ Bitmap.fromDrawable(R.drawable.s_lock2)
+ }),
+
+ // 8
+ new GDBitmapHolder(new Bitmap[]{
+ Bitmap.fromDrawable(R.drawable.s_medal_gold),
+ Bitmap.fromDrawable(R.drawable.s_medal_silver),
+ Bitmap.fromDrawable(R.drawable.s_medal_bronze)
+ }),
+
+ // 9
+ new GDBitmapHolder(new Bitmap[]{
+ Bitmap.fromDrawable(R.drawable.levels_wheel0),
+ Bitmap.fromDrawable(R.drawable.levels_wheel1),
+ Bitmap.fromDrawable(R.drawable.levels_wheel2)
+ }),
+
+ // 10
+ new GDBitmapHolder(Bitmap.fromDrawable(R.drawable.s_fender)),
+
+ // 11
+ new GDBitmapHolder(Bitmap.fromDrawable(R.drawable.s_engine)),
+
+ // 12
+ new GDBitmapHolder(new Bitmap[]{
+ Bitmap.fromDrawable(R.drawable.s_bluearm),
+ Bitmap.fromDrawable(R.drawable.s_blueleg),
+ Bitmap.fromDrawable(R.drawable.s_bluebody)
+ })
+ };
+ empty = new Bitmap(android.graphics.Bitmap.createBitmap(1, 1, android.graphics.Bitmap.Config.ARGB_8888));
+ }
+
+ public static Bitmap get(int index) {
+ if (index >= BLUEARM && index <= BLUEBODY) {
+ return get(BIKER, index - 100);
+ }
+
+ if (holders.length >= index - 1) {
+ GDBitmapHolder holder = holders[index];
+
+ if (holder != null && !holder.isArray && holder.bitmap != null) {
+ return holder.bitmap;
+ }
+ }
+
+ return empty;
+ }
+
+ public static Bitmap get(int index, int arrayIndex) {
+ if (holders.length >= index - 1) {
+ GDBitmapHolder holder = holders[index];
+ if (holder != null && holder.isArray && holder.bitmaps != null && holder.bitmaps.length >= arrayIndex - 1) {
+ return holder.bitmaps[arrayIndex];
+ }
+ }
+
+ return empty;
+ }
+
+ public static Bitmap getEmpty() {
+ return empty;
+ }
+
+ public static Bitmap fromDrawable(int id) {
+ return new Bitmap(loadBitmapFromDrawable(id));
+ }
+
+ public static Bitmap fromAsset(String s) throws IOException {
+ return new Bitmap(loadBitmapFromAsset(s));
+ }
+
+ public int getWidth() {
+ return bitmap.getWidth();
+ }
+
+ public int getHeight() {
+ return bitmap.getHeight();
+ }
+
+ public int getWidthDp() {
+ return Math.round(getWidth() / Global.density);
+ }
+
+ public int getHeightDp() {
+ return Math.round(getHeight() / Global.density);
+ }
+
+ private static class GDBitmapHolder {
+
+ public Bitmap bitmap = null;
+ public Bitmap bitmaps[] = null;
+ public boolean isArray = false;
+
+ GDBitmapHolder(Bitmap bitmap) {
+ this.bitmap = bitmap;
+ }
+
+ GDBitmapHolder(Bitmap bitmaps[]) {
+ this.bitmaps = new Bitmap[bitmaps.length];
+ System.arraycopy(bitmaps, 0, this.bitmaps, 0, bitmaps.length);
+ isArray = true;
+ }
+
+ }
+
+}
diff --git a/src/org/happysanta/gd/Game/FPMath.java b/src/org/happysanta/gd/Game/FPMath.java
new file mode 100755
index 0000000..9ddc4ab
--- /dev/null
+++ b/src/org/happysanta/gd/Game/FPMath.java
@@ -0,0 +1,80 @@
+package org.happysanta.gd.Game;
+
+// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.kpdus.com/jad.html
+// Decompiler options: packimports(3) fieldsfirst ansi
+
+
+public class FPMath {
+
+ // public static final int UNSIGNED_MASK = 0x7fffffff;
+// public static final int SIGN_MASK = 0x80000000;
+ //public static final int m_ifI;
+// public static final int m_aI = 1;
+ public static int HALF_PI = 0x19220; // 1,57080949111162
+ // public static int DOUBLE_PI = 0x6487f; // 6,283192187380789
+ public static int PI = 0x3243f; // 3,141588464179446
+ // public static int ONE = 0x10000;
+ private static int m_jI;
+ private static int m_kI;
+// private static int SIN_TABLE[] = {
+// 0, 1608, 3215, 4821, 6423, 8022, 9616, 11204, 12785, 14359,
+// 15923, 17479, 19024, 20557, 22078, 23586, 25079, 26557, 28020, 29465,
+// 30893, 32302, 33692, 35061, 36409, 37736, 39039, 40319, 41575, 42806,
+// 44011, 45189, 46340, 47464, 48558, 49624, 50660, 51665, 52639, 53581,
+// 54491, 55368, 56212, 57022, 57797, 58538, 59243, 59913, 60547, 61144,
+// 61705, 62228, 62714, 63162, 63571, 63943, 64276, 64571, 64826, 65043,
+// 65220, 65358, 65457, 65516
+// };
+// private static int ARCTG_TABLE[] = {
+// 0, 1023, 2047, 3069, 4090, 5109, 6126, 7139, 8149, 9155,
+// 10157, 11155, 12146, 13133, 14113, 15087, 16054, 17015, 17967, 18912,
+// 19849, 20778, 21698, 22610, 23512, 24405, 25289, 26163, 27027, 27882,
+// 28726, 29561, 30385, 31199, 32003, 32796, 33579, 34352, 35114, 35866,
+// 36608, 37339, 38060, 38771, 39471, 40161, 40841, 41512, 42172, 42822,
+// 43463, 44094, 44716, 45328, 45931, 46524, 47109, 47684, 48251, 48809,
+// 49358, 49899, 50431, 50955
+// };
+
+ public FPMath() {
+ }
+
+ public static int divide(int i, int j) {
+ int res = (int) (((long) i << 32) / (long) j >> 16);
+ return res;
+ }
+
+ public static int sin(int i) {
+ float fi = i / (float) 0xFFFF;
+ return (int) Math.round(Math.sin(fi) * 65536);
+ }
+
+ public static int _doII(int i) {
+ return sin(HALF_PI - i);
+ }
+
+ public static int arctg(int i) {
+ float fi = i / (float) 0xFFFF;
+ return (int) Math.round(Math.atan(fi) * 65536);
+ }
+
+ public static int _ifIII(int i, int j) {
+ if ((j >= 0 ? j : -j) < 3)
+ return (i <= 0 ? -1 : 1) * HALF_PI;
+ int k = arctg(divide(i, j));
+ if (i > 0)
+ if (j > 0)
+ return k;
+ else
+ return PI + k;
+ if (j > 0)
+ return k;
+ else
+ return k - PI;
+ }
+
+ static {
+ m_jI = 64;
+ m_kI = m_jI << 16;
+ }
+}
diff --git a/src/org/happysanta/gd/Game/GameView.java b/src/org/happysanta/gd/Game/GameView.java
new file mode 100755
index 0000000..ad181e0
--- /dev/null
+++ b/src/org/happysanta/gd/Game/GameView.java
@@ -0,0 +1,968 @@
+package org.happysanta.gd.Game;
+
+import android.graphics.*;
+import android.view.View;
+import org.happysanta.gd.Command;
+import org.happysanta.gd.GDActivity;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Menu.Menu;
+import org.happysanta.gd.Menu.MenuScreen;
+import org.happysanta.gd.Menu.SimpleMenuElement;
+
+import java.io.IOException;
+import java.util.Timer;
+
+import static org.happysanta.gd.Helpers.*;
+
+public class GameView extends View {
+
+ private static int m_VI = 0;
+ private static int m_vcI = 0;
+ private final int[] startFlagIndexes = {
+ 2, 0, 1, 0
+ };
+ private final int[] finishFlagIndexes = {
+ 4, 3, 5, 3
+ };
+ public int m_abI;
+ public int m_dI;
+ public int m_lI;
+ public boolean drawTimer;
+ public android.graphics.Bitmap m_zaBitmap[];
+ public boolean m_KZ;
+ public long m_rJ;
+ Menu menu;
+ int m_uI;
+ int m_aiI;
+ int m_agI;
+ int m_gI;
+ private Canvas canvas;
+ private int m_XI;
+ private int m_BI;
+ private Physics physEngine;
+ private int m_TI;
+ private int m_QI;
+ private GDActivity activity;
+ private Paint infoFont;
+ private Paint timerFont;
+ private boolean m_ahZ;
+ private int m_oI;
+ private boolean m_AZ;
+ private int m_OI;
+ private android.graphics.Bitmap m_MBitmap;
+ private Canvas m_dcGraphics;
+ private boolean m_ecZ;
+ private String infoMessage;
+ private int gc;
+ private Timer timer;
+ private Command menuCommand;
+ private Paint paint = new Paint();
+ private Object m_ocObject;
+ private byte[][] m_DaaB = {
+ {0, 0},
+ {1, 0},
+ {0, -1},
+ {0, 0},
+ {0, 0},
+ {0, 1},
+ {-1, 0}
+ };
+ private byte[][][] m_maaaB = {
+ {
+ {
+ 0, 0
+ },
+ {
+ 1, -1
+ },
+ {
+ 1, 0
+ },
+ {
+ 1, 1
+ },
+ {
+ 0, -1
+ },
+ {
+ -1, 0
+ },
+ {
+ 0, 1
+ },
+ {
+ -1, -1
+ },
+ {
+ -1, 0
+ },
+ {
+ -1, 1
+ }
+ }, {
+ {
+ 0, 0
+ },
+ {
+ 1, 0
+ },
+ {
+ 0, 0
+ },
+ {
+ 0, 0
+ },
+ {
+ -1, 0
+ },
+ {
+ 0, -1
+ },
+ {
+ 0, 1
+ },
+ {
+ 0, 0
+ },
+ {
+ 0, 0
+ },
+ {
+ 0, 0
+ }
+ },
+ {
+ {
+ 0, 0
+ },
+ {
+ 0, 0
+ },
+ {
+ 0, 0
+ },
+ {
+ 1, 0
+ },
+ {
+ 0, -1
+ },
+ {
+ 0, 1
+ },
+ {
+ -1, 0
+ },
+ {
+ 0, 0
+ },
+ {
+ 0, 0
+ },
+ {
+ 0, 0
+ }
+ }
+ };
+ private int inputOption;
+ private boolean[] m_aeaZ;
+ private boolean[] m_LaZ;
+ // private int defaultHeight;
+ // private int defaultWidth;
+
+ public GameView(GDActivity micro) {
+ super(micro);
+ // clear static
+ m_vcI = 0;
+ m_VI = 0;
+
+ canvas = null;
+ physEngine = null;
+ menu = null;
+ m_TI = 0;
+ m_QI = 0;
+ activity = null;
+ infoFont = null;
+ m_ahZ = false;
+ drawTimer = true;
+ m_oI = 1;
+ m_uI = 0;
+ m_zaBitmap = null;
+
+ m_KZ = false;
+ m_AZ = true;
+ m_MBitmap = null;
+ m_dcGraphics = null;
+ m_ecZ = false;
+ infoMessage = null;
+ gc = 0;
+ timer = new Timer();
+ m_rJ = -1L;
+ m_ocObject = new Object();
+ m_aiI = 0;
+ m_agI = 0;
+ m_gI = -1;
+ inputOption = 2;
+ m_aeaZ = new boolean[7];
+ m_LaZ = new boolean[10];
+ // String s;
+ // String s1;
+ paint.setAntiAlias(true);
+ paint.setStrokeWidth(1);
+
+ invalidate();
+ m_KZ = false;
+ activity = micro;
+ _ifvV();
+
+ infoFont = new Paint();
+ infoFont.setTextSize(20);
+ infoFont.setAntiAlias(true);
+ infoFont.setTypeface(Global.robotoCondensedTypeface);
+
+ timerFont = new Paint();
+ timerFont.setTextSize(18);
+ timerFont.setAntiAlias(true);
+ timerFont.setTypeface(Global.robotoCondensedTypeface);
+
+ m_XI = 0;
+ m_BI = m_dI;
+ menuCommand = new Command("Menu", 1, 1);
+ }
+
+ public void drawBitmap(Bitmap b, float x, float y) {
+ drawBitmap(b, x, y, canvas);
+ }
+
+ public void drawBitmap(Bitmap b, float x, float y, Canvas g) {
+ Paint paint = null;
+ if (!isSDK11OrHigher()) {
+ paint = new Paint();
+ paint.setFlags(Paint.DITHER_FLAG);
+ paint.setFilterBitmap(true);
+ }
+ g.drawBitmap(b.bitmap,
+ new Rect(0, 0, b.getWidth(), b.getHeight()),
+ new RectF(x, y, x + b.getWidthDp(), y + b.getHeightDp()),
+ paint);
+ }
+
+ public static void _dovV() {
+ m_vcI += 655;
+ int j = 32768 + ((FPMath.sin(m_vcI) >= 0 ? FPMath.sin(m_vcI) : -FPMath.sin(m_vcI)) >> 1);
+ m_VI += (int) (6553L * (long) j >> 16);
+ }
+
+ /*
+ TODO
+ суть этого метода в том, что после того, как splash-картинки проигрались, они удаляются из памяти, т.к. они больше нафиг не нужны
+ видимо это было критично на старых телефонах
+ можно и тут в принципе сделать
+ */
+ public void _doIV(int j) {
+ m_oI = j;
+ if (j == 0) {
+ // Bitmap.get(Bitmap.CODEBREW_LOGO) = null;
+ // Bitmap.get(Bitmap.GD_LOGO) = null;
+ }
+ }
+
+ public void _aZV(boolean flag) {
+ m_AZ = flag;
+ _ifvV();
+ }
+
+ public void _ifvV() {
+ m_abI = getScaledWidth();
+ m_lI = m_dI = getScaledHeight();
+ if (m_KZ && m_AZ)
+ m_dI -= 80;
+ //postInvalidate();
+ }
+
+ public android.graphics.Bitmap[] spritesFromBitmap(android.graphics.Bitmap bitmap, int j, int k) {
+ int l = bitmap.getWidth() / j;
+ int i1 = bitmap.getHeight() / k;
+ android.graphics.Bitmap aBitmap[] = new android.graphics.Bitmap[j * k];
+ for (int j1 = 0; j1 < j * k; j1++) {
+ aBitmap[j1] = android.graphics.Bitmap.createBitmap(l, i1, android.graphics.Bitmap.Config.ARGB_8888);
+ new Canvas(aBitmap[j1]).drawBitmap(bitmap, -l * (j1 % j), -i1 * (j1 / j), null);
+ }
+
+ return aBitmap;
+ }
+
+ public int _intII(int j) {
+ synchronized (m_ocObject) {
+ try {
+ {
+ if ((j & 1) != 0) {
+ /* try {
+ if (Bitmap.get(Bitmap.FENDER) == null) {
+ //Bitmap.get(Bitmap.FENDER) = Bitmap.fromAsset("/fender.png");
+ //Bitmap.get(Bitmap.FENDER).mulWidth = 1.0f/6.0f;
+ //Bitmap.get(Bitmap.FENDER).mulHeight = 1.0f/6.0;
+ Bitmap.get(Bitmap.FENDER) = Bitmap.fromDrawable(R.drawable.s_fender);
+ }
+ if (Bitmap.get(Bitmap.ENGINE) == null) {
+ //Bitmap.get(Bitmap.ENGINE) = Bitmap.fromAsset("/engine.png");
+ //Bitmap.get(Bitmap.ENGINE).mulHeight = 1.0f/6.0f;
+ //Bitmap.get(Bitmap.ENGINE).mulWidth = 1.0f/6.0f;
+ Bitmap.get(Bitmap.ENGINE) = Bitmap.fromDrawable(R.drawable.s_engine);
+ }
+ } catch (Throwable _ex) {
+ Bitmap.get(Bitmap.FENDER) = Bitmap.get(Bitmap.ENGINE) = null;
+ j &= -2;
+ } */
+ } else {
+ // Bitmap.get(Bitmap.ENGINE) = Bitmap.get(Bitmap.FENDER) = null;
+ // System.gc();
+ }
+ if ((j & 2) != 0) {
+ // blueleg
+ /*try {
+ if (bikerSprites[1] == null)
+ bikerSprites[1] = Bitmap.fromDrawable(R.drawable.s_blueleg);
+ } catch (Throwable _ex) {
+ bikerSprites[1] = null;
+ bikerSprites[0] = null;
+ bikerSprites[2] = null;
+ j &= -3;
+ System.out.println("There may be error");
+ return 0;
+ }*/
+
+ // bluearm
+ /*try {
+ bikerSprites[0] = Bitmap.fromDrawable(R.drawable.s_bluearm);
+ } catch (Throwable _ex) {
+ bikerSprites[0] = bikerSprites[1];
+ }
+
+ // bluebody
+ try {
+ bikerSprites[2] = Bitmap.fromDrawable(R.drawable.s_bluebody);
+ } catch (Throwable _ex) {
+ bikerSprites[2] = bikerSprites[1];
+ }*/
+ } else {
+ // bikerSprites[1] = bikerSprites[2] = bikerSprites[0] = null;
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("There may be error [1]");
+ }
+ }
+ return j;
+ }
+
+ public android.graphics.Bitmap[] loadSprites(String s, int j, int k) {
+ android.graphics.Bitmap bitmap;
+ try {
+ bitmap = loadBitmapFromAsset(s);
+ } catch (IOException _ex) {
+ android.graphics.Bitmap aBitmap[] = new android.graphics.Bitmap[j * k];
+ for (int l = 0; l < j * k; l++)
+ aBitmap[l] = Bitmap.getEmpty().bitmap;
+
+ return aBitmap;
+ }
+ return spritesFromBitmap(bitmap, j, k);
+ }
+
+ public void _casevV() {
+ physEngine._nullvV();
+ _avV();
+ m_aiI = 0;
+ m_agI = 0;
+ }
+
+ public void setPhysicsEngine(Physics b1) {
+ physEngine = b1;
+ physEngine._caseIV(m_abI >= m_dI ? m_dI : m_abI);
+ }
+
+ public void setMenu(Menu menu) {
+ this.menu = menu;
+ }
+
+ /* public Bitmap _aStringBitmap(String s) {
+ Bitmap bitmap = null;
+ try {
+ bitmap = Global.loadBitmapFromAsset(s);
+ } catch (IOException _ex) {
+ }
+ return bitmap;
+ } */
+
+ public void _doIIV(int j, int k) {
+ m_XI = j;
+ m_BI = k;
+ physEngine._ifIIV(-j, -j + m_abI);
+ }
+
+ public int _charvI() {
+ return m_XI;
+ }
+
+ private float offsetX(float j) {
+ return j + m_XI;
+ }
+
+ private float offsetY(float j) {
+ return -j + m_BI - getGDActivity().getButtonsLayoutHeight() / 2;
+ }
+
+ public void _newvV() {
+ paint.setColor(0xFFFFFFFF);
+ paint.setStyle(Paint.Style.FILL);
+ canvas.drawRect(0, m_dI, m_abI, 80, paint);
+ byte byte0 = 35;
+ int j = m_abI / 2;
+ int k = m_dI + 40;
+ // m_CGraphics.setColor(150, 0, 0);
+ paint.setColor(0xFF960000);
+ int i1;
+ paint.setStyle(Paint.Style.STROKE);
+ if (m_aiI != 0 || m_agI != 0) {
+ i1 = (int) (((long) (int) ((long) m_OI * 0xb40000L >> 16) << 32) / 0x3243fL >> 16) >> 16;
+ int l = i1 - i1 % 45;
+ l -= 90;
+ //m_CGraphics.fillArc(j - byte0, k - byte0, 2 * byte0, 2 * byte0, l - 22, 45);
+ canvas.drawArc(new RectF(j - byte0, k - byte0, 2 * byte0 + j - byte0, 2 * byte0 + k - byte0), l - 22, 45, true, paint);
+ }
+ //m_CGraphics.setColor(0, 0, 0);
+ paint.setColor(0xFF000000);
+ canvas.drawArc(new RectF(j - byte0, k - byte0, 2 * byte0 + j - byte0, 2 * byte0 + k - byte0), 0, 360, true, paint);
+ byte0 = 2;
+ canvas.drawArc(new RectF(j - byte0, k - byte0, 2 * byte0 + j - byte0, 2 * byte0 + k - byte0), 0, 360, true, paint);
+ paint.setStyle(Paint.Style.FILL);
+ }
+
+ public void _aIIIV(int j, int k, int l, int i1) {
+ canvas.drawLine(offsetX(j), offsetY(k), offsetX(l), offsetY(i1), paint);
+ }
+
+ public void drawLine(int j, int k, int l, int i1) {
+ canvas.drawLine(offsetX((j << 2) / (float) 0xFFFF), offsetY((k << 2) / (float) 0xFFFF), offsetX((l << 2) / (float) 0xFFFF), offsetY((i1 << 2) / (float) 0xFFFF), paint);
+ }
+
+ public void _aIIIV(int j, int k, int l, int i1, int j1) {
+ drawBikerPart(j, k, l, i1, j1, 32768);
+ }
+
+ public void drawBikerPart(int j, int k, int l, int i1, int j1, int k1) {
+ float l1 = offsetX((int) ((long) l * (long) k1 >> 16) + (int) ((long) j * (long) (0x10000 - k1) >> 16) >> 16);
+ float i2 = offsetY((int) ((long) i1 * (long) k1 >> 16) + (int) ((long) k * (long) (0x10000 - k1) >> 16) >> 16);
+ int j2 = FPMath._ifIII(l - j, i1 - k);
+ int index = 0;
+ switch (j1) {
+ case 0: // '\0'
+ index = _aIIII(j2, 0, 0x3243f, 16, false);
+ break;
+
+ case 1: // '\001'
+ index = _aIIII(j2, 0, 0x3243f, 16, false);
+ break;
+
+ case 2: // '\002'
+ index = _aIIII(j2, 0, 0x3243f, 16, false);
+ break;
+ }
+ float fAngleDeg = (float) (j2 / (float) 0xFFFF / Math.PI * 180) - 180;
+ index = 0;
+
+ Bitmap bikerSprite = Bitmap.get(Bitmap.BIKER, j1);
+ if (bikerSprite != null) {
+ float x = l1 - bikerSprite.getWidthDp() / 2;
+ float y = i2 - bikerSprite.getHeightDp() / 2;
+
+ canvas.save();
+ canvas.rotate(fAngleDeg, x + bikerSprite.getWidthDp() / 2, y + bikerSprite.getHeightDp() / 2);
+ drawBitmap(bikerSprite, x, y);
+ canvas.restore();
+ }
+ }
+
+ // �������� �����
+ public void _ifIIIV(int j, int k, int l, int i1) {
+ l++;
+ float j1 = offsetX(j - l);
+ float k1 = offsetY(k + l);
+ int l1 = l << 1;
+ if ((i1 = -(int) (((long) (int) ((long) i1 * 0xb40000L >> 16) << 32) / 0x3243fL >> 16)) < 0)
+ i1 += 360;
+ paint.setStyle(Paint.Style.STROKE);
+ canvas.drawArc(new RectF(j1, k1, j1 + l1, k1 + l1), -((i1 >> 16) + 170), -90, false, paint);
+ paint.setStyle(Paint.Style.FILL);
+ }
+
+ // Draws red circle
+ public void drawLineWheel(float j, float k, int l) {
+ float i1 = l / 2;
+ float j1 = offsetX(j - i1);
+ float k1 = offsetY(k + i1);
+
+ paint.setStyle(Paint.Style.STROKE);
+ canvas.drawArc(new RectF(j1, k1, j1 + l, k1 + l), 0, 360, true, paint);
+ paint.setStyle(Paint.Style.FILL);
+ }
+
+ public void _forIIIV(int j, int k, int l, int i1) {
+ float j1 = offsetX(j);
+ float k1 = offsetY(k);
+ canvas.drawRect(j1, k1, j1 + l, k1 + i1, paint);
+ }
+
+ public void drawSteering(int j, int k) {
+ float x = offsetX(j - Bitmap.get(Bitmap.STEERING).getWidthDp() / 2);
+ float y = offsetY(k + Bitmap.get(Bitmap.STEERING).getHeightDp() / 2);
+
+ drawBitmap(Bitmap.get(Bitmap.STEERING), x, y);
+ }
+
+ public void drawHelmet(float j, float k, int l) {
+ float fAngleDeg = (float) (l / (float) 0xFFFF / Math.PI * 180) - 90 - 10;
+ if (fAngleDeg >= 360) fAngleDeg -= 360;
+ if (fAngleDeg < 0) fAngleDeg = 360 + fAngleDeg;
+ if (Bitmap.get(Bitmap.HELMET) != null) {
+ float x = offsetX(j) - Bitmap.get(Bitmap.HELMET).getWidthDp() / 2;
+ float y = offsetY(k) - Bitmap.get(Bitmap.HELMET).getHeightDp() / 2;
+ canvas.save();
+ canvas.rotate(fAngleDeg, x + Bitmap.get(Bitmap.HELMET).getWidthDp() / 2, y + Bitmap.get(Bitmap.HELMET).getHeightDp() / 2);
+
+ drawBitmap(Bitmap.get(Bitmap.HELMET), x, y);
+ canvas.restore();
+ }
+ }
+
+ public void _ifIIIIV(int j, int k, int l, int i1, int j1, int k1) {
+ }
+
+ public void drawTimer(long l) {
+ // logDebug("Timer: " + l);
+ String txt = String.format("%d:%02d:%02d", l / 6000, (l / 100) % 60, l % 100);
+ // logDebug("drawTimter: long = " + l + ", string = " + txt);
+ canvas.drawText(txt, 18, -infoFont.ascent() + 17, timerFont);
+ }
+
+ public synchronized void showInfoMessage(String s, int j) {
+ m_ahZ = false;
+ gc++;
+ infoMessage = s;
+ if (timer != null) {
+ timer.schedule(new SimpleMenuElement(gc), j);
+ }
+ }
+
+ public void _tryIV(int j) {
+ if (gc == j)
+ m_ahZ = true;
+ }
+
+ public void drawStartFlag(int j, int k) {
+ if (m_VI > 0x38000)
+ m_VI = 0;
+ setColor(0, 0, 0);
+ _aIIIV(j, k, j, k + 32);
+ drawBitmap(Bitmap.get(Bitmap.FLAGS, startFlagIndexes[m_VI >> 16]), offsetX(j), offsetY(k) - 32);
+ }
+
+ public void drawFinishFlag(int j, int k) {
+ if (m_VI > 0x38000)
+ m_VI = 0;
+ setColor(0, 0, 0);
+ _aIIIV(j, k, j, k + 32);
+ drawBitmap(Bitmap.get(Bitmap.FLAGS, finishFlagIndexes[m_VI >> 16]), offsetX(j), offsetY(k) - 32);
+ }
+
+ public void drawWheel(float j, float k, int l) {
+ int wheel;
+ if (l == 1)
+ wheel = 0; // small
+ else
+ wheel = 1; // big
+
+ float x = offsetX(j - Bitmap.get(Bitmap.WHEELS, wheel).getWidthDp() / 2);
+ float y = offsetY(k + Bitmap.get(Bitmap.WHEELS, wheel).getHeightDp() / 2);
+
+ drawBitmap(Bitmap.get(Bitmap.WHEELS, wheel), x, y);
+ }
+
+ int _aIIII(int j, int k, int l, int i1, boolean flag) {
+ for (j += k; j < 0; j += l) ;
+ for (; j >= l; j -= l) ;
+ if (flag)
+ j = l - j;
+ int j1;
+ if ((j1 = (int) ((long) (int) (((long) j << 32) / (long) l >> 16) * (long) (i1 << 16) >> 16)) >> 16 < i1 - 1)
+ return j1 >> 16;
+ else
+ return i1 - 1;
+ }
+
+ public void drawEngine(float j, float k, int l) {
+ float fAngleDeg = (float) (l / (float) 0xFFFF / Math.PI * 180) - 180;
+ float x = offsetX(j) - Bitmap.get(Bitmap.ENGINE).getWidthDp() / 2;
+ float y = offsetY(k) - Bitmap.get(Bitmap.ENGINE).getHeightDp() / 2;
+ if (Bitmap.get(Bitmap.ENGINE) != null) {
+ canvas.save();
+ canvas.rotate(fAngleDeg, x + Bitmap.get(Bitmap.ENGINE).getWidthDp() / 2, y + Bitmap.get(Bitmap.ENGINE).getHeightDp() / 2);
+ drawBitmap(Bitmap.get(Bitmap.ENGINE), x, y);
+ canvas.restore();
+ }
+ }
+
+ public void drawFender(float j, float k, int l) {
+ float fAngleDeg = (float) (l / (float) 0xFFFF / Math.PI * 180) - 180 + 15;
+ if (fAngleDeg >= 360) fAngleDeg -= 360;
+ if (Bitmap.get(Bitmap.FENDER) != null) {
+ float x = offsetX(j) - Bitmap.get(Bitmap.FENDER).getWidthDp() / 2;
+ float y = offsetY(k) - Bitmap.get(Bitmap.FENDER).getHeightDp() / 2;
+
+ canvas.save();
+ canvas.rotate(fAngleDeg, x + Bitmap.get(Bitmap.FENDER).getWidthDp() / 2, y + Bitmap.get(Bitmap.FENDER).getHeightDp() / 2);
+ drawBitmap(Bitmap.get(Bitmap.FENDER), x, y);
+ canvas.restore();
+ }
+ }
+
+ public void _tryvV() {
+ paint.setColor(0xFFFFFFFF);
+ canvas.drawRect(0, 0, m_abI, m_dI, paint);
+ }
+
+ public void setColor(int r, int g, int b) {
+ GDActivity _tmp = activity;
+ if (getGDActivity().isMenuShown()) {
+ r += 128;
+ g += 128;
+ b += 128;
+ if (r > 240)
+ r = 240;
+ if (g > 240)
+ g = 240;
+ if (b > 240)
+ b = 240;
+ }
+ //m_CGraphics.setColor(j, k, l);
+ paint.setColor(0xFF000000 | (r << 16) | (g << 8) | b);
+ }
+
+ // Draw boot logos and something else
+ public void drawGame(Canvas g) {
+ final GDActivity gd = getGDActivity();
+ label0:
+ {
+ int j;
+ synchronized (m_ocObject) {
+ if (gd.alive && !gd.m_caseZ)
+ break label0;
+ }
+ return;
+ }
+
+ if (m_ecZ)
+ canvas = m_dcGraphics;
+ else
+ canvas = g;
+ if (m_oI != 0) {
+ if (m_oI == 1) {
+ // Draw codebrew
+ paint.setColor(0xFFFFFFFF);
+ canvas.drawRect(0, 0, getScaledWidth(), getScaledHeight(), paint);
+ if (Bitmap.get(Bitmap.CODEBREW_LOGO) != null) {
+ drawBitmap(Bitmap.get(Bitmap.CODEBREW_LOGO),
+ getScaledWidth() / 2 - Bitmap.get(Bitmap.CODEBREW_LOGO).getWidthDp() / 2,
+ (float) (getScaledHeight() / 2 - Bitmap.get(Bitmap.CODEBREW_LOGO).getHeightDp() / 1.6));
+ }
+ } else {
+ // Draw gd
+ paint.setColor(0xFFFFFFFF);
+ canvas.drawRect(0, 0, getScaledWidth(), getScaledHeight(), paint);
+ if (Bitmap.get(Bitmap.GD_LOGO) != null) {
+ drawBitmap(Bitmap.get(Bitmap.GD_LOGO),
+ getScaledWidth() / 2 - Bitmap.get(Bitmap.GD_LOGO).getWidthDp() / 2,
+ (float) (getScaledHeight() / 2 - Bitmap.get(Bitmap.GD_LOGO).getHeightDp() / 1.6));
+ }
+ }
+ int j = (int) (((long) (gd.m_longI << 16) << 32) / 0xa0000L >> 16);
+ drawProgress(j, true);
+ } else {
+ if (m_lI != getHeight())
+ _ifvV();
+ physEngine._voidvV();
+ _doIIV(-physEngine._elsevI() + m_TI + m_abI / 2, physEngine._ifvI() + m_QI + m_dI / 2);
+ physEngine._ifiV(this);
+ if (drawTimer) {
+ long time = 0, finished;
+ if (gd.startedTime > 0) {
+ if (gd.finishedTime > 0)
+ finished = gd.finishedTime;
+ else
+ finished = System.currentTimeMillis();
+ time = (finished - gd.startedTime - gd.pausedTime) / 10;
+ }
+ drawTimer(time);
+ }
+ if (infoMessage != null) {
+ setColor(0, 0, 0);
+ infoFont.setColor(paint.getColor());
+ /*if (m_dI <= 128)
+ canvas.drawText(infoMessage, m_abI / 2 - infoFont.measureText(infoMessage) / 2, 1, infoFont);
+ else*/
+
+ canvas.drawText(infoMessage, m_abI / 2 - infoFont.measureText(infoMessage) / 2, m_dI / 5, infoFont);
+ if (m_ahZ) {
+ m_ahZ = false;
+ infoMessage = null;
+ }
+ }
+ int j = physEngine._tryvI();
+ drawProgress(j, false);
+ if (m_KZ && m_AZ)
+ _newvV();
+ }
+ canvas = null;
+ if (m_ecZ)
+ g.drawBitmap(m_MBitmap, 0, 0, null);
+ }
+
+ public void drawProgress(int j, boolean flag) {
+ double progr = j / (double) 0xFFFF;
+
+ paint.setColor(0xffc4c4c4);
+ canvas.drawRect(0, 0, getScaledWidth(), 3, paint);
+
+ paint.setColor(0xff29aa27);
+ canvas.drawRect(0, 0, Math.round(getScaledWidth() * Math.min(Math.max(progr, 0), 1)), 3, paint);
+ }
+
+ private void _ifIIV(int j, int k) {
+ if (!getGDActivity().isMenuShown()) {
+ byte byte0 = 0;
+ byte byte1 = 0;
+ m_aiI = j;
+ m_agI = k;
+ int l = j << 16;
+ int i1 = k << 16;
+ int j1 = m_abI / 2 << 16;
+ int k1 = m_dI + 40 << 16;
+ if (m_KZ && m_AZ) {
+ int l1 = FPMath._ifIII(l - j1, i1 - k1);
+ for (l1 += 25735; l1 < 0; l1 += 0x6487e) ;
+ for (; l1 > 0x6487e; l1 -= 0x6487e) ;
+ m_OI = l1;
+ int i2;
+ if ((i2 = 51471) >= l1)
+ byte0 = -1;
+ else if (l1 < (int) ((long) i2 * 0x20000L >> 16)) {
+ byte0 = -1;
+ byte1 = 1;
+ } else if (l1 < (int) ((long) i2 * 0x30000L >> 16))
+ byte1 = 1;
+ else if (l1 < (int) ((long) i2 * 0x40000L >> 16)) {
+ byte0 = 1;
+ byte1 = 1;
+ } else if (l1 < (int) ((long) i2 * 0x50000L >> 16))
+ byte0 = 1;
+ else if (l1 < (int) ((long) i2 * 0x60000L >> 16)) {
+ byte0 = 1;
+ byte1 = -1;
+ } else if (l1 < (int) ((long) i2 * 0x70000L >> 16))
+ byte1 = -1;
+ else if (l1 < (int) ((long) i2 * 0x80000L >> 16)) {
+ byte0 = -1;
+ byte1 = -1;
+ }
+ physEngine._aIIV(byte0, byte1);
+ }
+ }
+ }
+
+ public void _pointerPressedIIV(int j, int k) {
+ if (!getGDActivity().isMenuShown())
+ _ifIIV(j, k);
+ }
+
+ public void _pointerReleasedIIV(int j, int k) {
+ if (!getGDActivity().isMenuShown()) {
+ m_aiI = 0;
+ m_agI = 0;
+ physEngine._nullvV();
+ }
+ }
+
+ public void _pointerDraggedIIV(int j, int k) {
+ if (!getGDActivity().isMenuShown())
+ _ifIIV(j, k);
+ }
+
+ public void setInputOption(int option) {
+ inputOption = option;
+ }
+
+ private void _avV() {
+ for (int j = 0; j < 10; j++)
+ m_LaZ[j] = false;
+
+ for (int k = 0; k < 7; k++)
+ m_aeaZ[k] = false;
+
+ }
+
+ private void _xavV() {
+ int j = 0;
+ int k = 0;
+ int l = inputOption;
+ for (int i1 = 0; i1 < 10; i1++)
+ if (m_LaZ[i1]) {
+ j += m_maaaB[l][i1][0];
+ k += m_maaaB[l][i1][1];
+ }
+
+ for (int j1 = 0; j1 < 7; j1++)
+ if (m_aeaZ[j1]) {
+ j += m_DaaB[j1][0];
+ k += m_DaaB[j1][1];
+ }
+
+ physEngine._aIIV(j, k);
+ }
+
+ protected void processKeyPressed(int j) {
+ int k = getGameAction(j);
+ int l;
+ if ((l = j - 48) >= 0 && l < 10)
+ m_LaZ[l] = true;
+ else if (k >= 0 && k < 7)
+ m_aeaZ[k] = true;
+ _xavV();
+ }
+
+ protected void processKeyReleased(int j) {
+ int k = getGameAction(j);
+ int l;
+ if ((l = j - 48) >= 0 && l < 10)
+ m_LaZ[l] = false;
+ else if (k >= 0 && k < 7)
+ m_aeaZ[k] = false;
+ _xavV();
+ }
+
+ public void showMenu() {
+ if (menu != null) {
+ menu.m_blZ = true;
+ getGDActivity().gameToMenu();
+ }
+ }
+
+ /* protected void hideNotify() {
+ if (!getGDActivity().isMenuShown()) {
+ GDActivity.m_cZ = true;
+ activity.gameToMenu();
+ }
+ } */
+
+ /* protected void showNotify() {
+ GDActivity.m_cZ = false;
+ } */
+
+ protected void keyRepeated(int j) {
+ if (getGDActivity().isMenuShown() && menu != null)
+ menu._tryIV(j);
+ }
+
+ public synchronized void keyPressed(int j) {
+ if (getGDActivity().isMenuShown() && menu != null)
+ menu.keyPressed(j);
+ processKeyPressed(j);
+ }
+
+ public synchronized void keyReleased(int j) {
+ processKeyReleased(j);
+ }
+
+ @Override
+ public void onDraw(Canvas g) {
+ g.save();
+ if (!Global.DISABLE_SCALING)
+ g.scale(Global.density, Global.density);
+ if (getGDActivity().isMenuShown() && menu != null) {
+ menu.draw(g);
+ } else {
+ drawGame(g);
+ }
+ g.restore();
+ invalidate();
+ }
+
+ public void commandAction(Command command) {
+ if (getGDActivity().isMenuShown() && menu != null) {
+ menu.onCommand(command);
+ } else {
+ showMenu();
+ }
+ }
+
+ public void removeMenuCommand() {
+ removeCommand(menuCommand);
+ }
+
+ public void addMenuCommand() {
+ addCommand(menuCommand);
+ }
+
+ public static int getGameAction(int key) {
+ // logDebug("getGameAction: key = " + key);
+ switch (key) {
+ case 50: // 2
+ return MenuScreen.KEY_UP; // up
+ case 56: // 8
+ return MenuScreen.KEY_DOWN; // down
+ case 52: // 4
+ return MenuScreen.KEY_LEFT; // left
+ case 54: // 6
+ return MenuScreen.KEY_RIGHT; // right
+ case 53: // 5
+ return MenuScreen.KEY_FIRE; // fire
+ }
+ return 0;
+ }
+
+ public void addCommand(Command cmd) {
+ GDActivity.shared.addCommand(cmd);
+ }
+
+ public void removeCommand(Command cmd) {
+ GDActivity.shared.removeCommand(cmd);
+ }
+
+ public int getScaledWidth() {
+ float density = Global.DISABLE_SCALING ? 1 : Global.density;
+ return Math.round(getWidth() / density);
+ }
+
+ public int getScaledHeight() {
+ float density = Global.DISABLE_SCALING ? 1 : Global.density;
+ return Math.round(getHeight() / density);
+ }
+
+ @Override
+ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ int width = MeasureSpec.getSize(widthMeasureSpec), height = MeasureSpec.getSize(heightMeasureSpec);
+ setMeasuredDimension(width, height);
+ }
+
+ public synchronized void destroy() {
+ if (timer != null) {
+ timer.cancel();
+ timer.purge();
+ timer = null;
+ }
+ }
+
+}
diff --git a/src/org/happysanta/gd/Game/Physics.java b/src/org/happysanta/gd/Game/Physics.java
new file mode 100755
index 0000000..d6e25b3
--- /dev/null
+++ b/src/org/happysanta/gd/Game/Physics.java
@@ -0,0 +1,1336 @@
+package org.happysanta.gd.Game;
+
+// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.kpdus.com/jad.html
+// Decompiler options: packimports(3) fieldsfirst ansi
+
+
+import org.happysanta.gd.Levels.Loader;
+import org.happysanta.gd.Menu.SimpleMenuElement;
+
+import static org.happysanta.gd.Helpers.getGDActivity;
+import static org.happysanta.gd.Helpers.getLevelLoader;
+
+public class Physics {
+
+ /*public static final int m_agI = 1;
+ //public static final int m_byteI;
+ public static final int m_ahI = 1;
+ public static final int m_LI = 2;
+ public static final int m_uI = 3;
+ //public static final int m_aI;
+ public static final int m_VI = 1;
+ public static final int m_BI = 2;
+ public static final int m_acI = 3;
+ public static final int m_newI = 4;
+ public static final int m_ZI = 5 */
+ public static int m_YI;
+ public static int m_voidI;
+ public static int m_gI;
+ public static int m_fI;
+ public static int m_eI;
+ public static int m_aeI;
+ public static int m_adI;
+ public static int m_yI;
+ public static int m_qI;
+ public static int m_xI;
+ public static int m_foraI[] = {
+ 0x1c000, 0x10000, 32768
+ };
+ public static int m_PI;
+ public static int m_jI;
+ public static int m_QI;
+ public static int m_charI;
+ public static int m_abI;
+ public static int m_WI;
+ public static int m_AI;
+ public static int m_longI;
+ public static int m_hI = 0;
+ // private final int m_pI = 3276;
+ private final int m_KaaI[][] = {
+ {
+ 0x2cccc, -52428
+ }, {
+ 0x40000, 0xfffd8000
+ }, {
+ 0x63333, 0xffff0000
+ }, {
+ 0x6cccc, -39321
+ }, {
+ 0x39999, 39321
+ }, {
+ 16384, 0xfffdcccd
+ }, {
+ 13107, 0xfffecccd
+ }, {
+ 0x46666, 0x14000
+ }
+ };
+ private final int m_ucaaI[][] = {
+ {
+ 0x2e666, 0xfffe4ccd
+ }, {
+ 0x4b333, 0xfffc6667
+ }, {
+ 0x51999, 0xfffe4000
+ }, {
+ 0x60000, -58982
+ }, {
+ 0x40000, 0x18000
+ }, {
+ 0x10000, 0xfffe199a
+ }, {
+ 13107, 0xfffecccd
+ }, {
+ 0x46666, 0x14000
+ }
+ };
+ private final int m_SaaI[][] = {
+ {
+ 0x26666, 13107
+ }, {
+ 0x48000, -13107
+ }, {
+ 0x59999, 0x16666
+ }, {
+ 0x63333, 0x2e666
+ }, {
+ 0x54ccc, 0x11999
+ }, {
+ 39321, 0xfffe8000
+ }, {
+ 13107, -52428
+ }, {
+ 0x48000, 0x14000
+ }
+ };
+ private final int m_wcaaI[][] = {
+ {
+ 0x2cccc, -39321
+ }, {
+ 0x40000, 0xfffe0000
+ }, {
+ 0x60000, 0xffff0000
+ }, {
+ 0x70000, -39321
+ }, {
+ 0x48000, 6553
+ }, {
+ 16384, 0xfffdcccd
+ }, {
+ 13107, 0xfffecccd
+ }, {
+ 0x46666, 0x14ccc
+ }
+ };
+ private final int m_DaaI[][] = {
+ {
+ 0x2e666, 0xfffe999a
+ }, {
+ 0x3e666, 0xfffc6667
+ }, {
+ 0x51999, 0xfffe4000
+ }, {
+ 0x60000, -42598
+ }, {
+ 0x49999, 6553
+ }, {
+ 0x10000, 0xfffecccd
+ }, {
+ 13107, 0xfffecccd
+ }, {
+ 0x46666, 0x14ccc
+ }
+ };
+ private final int m_MaaI[][] = {
+ {
+ 0x26666, 13107
+ }, {
+ 0x48000, -13107
+ }, {
+ 0x59999, 0x19999
+ }, {
+ 0x63333, 0x2b333
+ }, {
+ 0x54ccc, 0x11999
+ }, {
+ 39321, 0xfffe8000
+ }, {
+ 13107, -52428
+ }, {
+ 0x46666, 0x14ccc
+ }
+ };
+ public k m_Hak[];
+ public boolean m_bZ;
+ public int m_zI;
+ public boolean m_elseZ;
+ public boolean m_UZ;
+ public boolean m_NZ;
+ SimpleMenuElement m_aaan[];
+ private int m_vaI;
+ private int m_waI;
+ private int m_xaI;
+ private SimpleMenuElement m_ian[];
+ private int m_cI;
+ private Loader m_lf;
+ private int m_EI;
+ private int m_CI;
+ private boolean m_IZ;
+ private boolean m_mZ;
+ private int m_TI;
+ private int m_kI;
+ private boolean m_vZ;
+ private boolean m_afZ;
+ private int m_tI;
+ private boolean m_dZ;
+ private boolean m_FZ;
+ private boolean m_XZ;
+ private boolean m_wZ;
+ private boolean m_ifZ;
+ private boolean m_sZ;
+ private boolean m_OZ;
+ private boolean m_rZ;
+ private boolean m_RZ;
+ private boolean m_doZ;
+ private int m_oI;
+ private int m_nI;
+ private int m_GI;
+ private int m_JaaI[][] = {
+ {
+ 45875
+ }, {
+ 32768
+ }, {
+ 52428
+ }
+ };
+ private final int leftWheelUpdatingFrequency = 20;
+ private long leftWheelLastUpdated = 0;
+ private int leftWheelParams[][];
+
+ public Physics(Loader f1) {
+ m_vaI = 0;
+ m_waI = 1;
+ m_xaI = -1;
+ m_cI = 0;
+ m_EI = 0;
+ m_CI = 0;
+ m_IZ = false;
+ m_mZ = false;
+ m_TI = 32768;
+ m_kI = 0;
+ m_vZ = false;
+ m_bZ = false;
+ m_afZ = false;
+ m_aaan = new SimpleMenuElement[6];
+ for (int j = 0; j < 6; j++)
+ m_aaan[j] = new SimpleMenuElement();
+
+ m_tI = 0;
+ m_zI = 0;
+ m_elseZ = false;
+ m_UZ = false;
+ m_dZ = false;
+ m_FZ = false;
+ m_XZ = false;
+ m_wZ = false;
+ m_ifZ = false;
+ m_sZ = false;
+ m_OZ = false;
+ m_rZ = false;
+ m_RZ = false;
+ m_NZ = false;
+ m_doZ = true;
+ m_oI = 0;
+ m_nI = 0;
+ m_GI = 0xa0000;
+ m_lf = f1;
+ _doZV(true);
+ m_vZ = false;
+ _charvV();
+ m_IZ = false;
+
+ leftWheelParams = new int[5][4];
+ }
+
+ public static int _doIII(int j, int i1) {
+ int j1 = j >= 0 ? j : -j;
+ int k1;
+ int l1;
+ int i2;
+ if ((k1 = i1 >= 0 ? i1 : -i1) >= j1) {
+ l1 = k1;
+ i2 = j1;
+ } else {
+ l1 = j1;
+ i2 = k1;
+ }
+ return (int) (64448L * (long) l1 >> 16) + (int) (28224L * (long) i2 >> 16);
+ }
+
+ public int _bytevI() {
+ if (m_elseZ && m_UZ)
+ return 3;
+ if (m_UZ)
+ return 1;
+ return !m_elseZ ? 0 : 2;
+ }
+
+ public void _doIV(int j) {
+ m_elseZ = false;
+ m_UZ = false;
+ if ((j & 2) != 0)
+ m_elseZ = true;
+ if ((j & 1) != 0)
+ m_UZ = true;
+ }
+
+ public void _byteIV(int j) {
+ m_zI = j;
+ switch (j) {
+ case 1: // '\001'
+ default:
+ m_YI = 1310;
+ break;
+ }
+ m_voidI = 0x190000;
+ setLeague(1);
+ _doZV(true);
+ }
+
+ public void setLeague(int j) {
+ m_hI = j;
+ m_gI = 45875;
+ m_fI = 13107;
+ m_eI = 39321;
+ m_yI = 0x140000;
+ m_xI = 0x40000;
+ m_jI = 6553;
+ switch (j) {
+ case 3: // '\003'
+ m_aeI = 32768;
+ m_adI = 32768;
+ m_PI = 0x160000;
+ m_QI = 0x4b00000;
+ m_charI = 0x360000;
+ m_abI = 6553;
+ m_WI = 26214;
+ m_AI = 0x10000;
+ m_longI = 0x140000;
+ m_qI = 0x14a0000;
+ break;
+
+ case 2: // '\002'
+ m_aeI = 32768;
+ m_adI = 32768;
+ m_PI = 0x140000;
+ m_QI = 0x47e0000;
+ m_charI = 0x350000;
+ m_abI = 6553;
+ m_WI = 26214;
+ m_AI = 39321;
+ m_longI = 0x50000;
+ m_qI = 0x14a0000;
+ break;
+
+ case 1: // '\001'
+ m_aeI = 32768;
+ m_adI = 32768;
+ m_PI = 0x110000;
+ m_QI = 0x3e80000;
+ m_charI = 0x320000;
+ m_abI = 6553;
+ m_WI = 26214;
+ m_AI = 26214;
+ m_longI = 0x50000;
+ m_qI = 0x12c0000;
+ break;
+
+ case 0: // '\0'
+ default:
+ m_aeI = 19660;
+ m_adI = 19660;
+ m_PI = 0x110000;
+ m_QI = 0x3200000;
+ m_charI = 0x320000;
+ m_abI = 327;
+ m_WI = 0;
+ m_AI = 32768;
+ m_longI = 0x50000;
+ m_qI = 0x12c0000;
+ break;
+ }
+ _doZV(true);
+ }
+
+ public void _doZV(boolean flag) {
+ m_tI = 0;
+ _iIIV(m_lf._newvI(), m_lf._avI());
+ m_cI = 0;
+ m_kI = 0;
+ m_IZ = false;
+ m_mZ = false;
+ m_RZ = false;
+ m_NZ = false;
+ m_vZ = false;
+ m_bZ = false;
+ m_afZ = false;
+ m_lf.levels._aIIV((m_Hak[2].m_ifan[5].x + 0x18000) - m_foraI[0], (m_Hak[1].m_ifan[5].x - 0x18000) + m_foraI[0]);
+ }
+
+ public void _aZV(boolean flag) {
+ int j = (flag ? 0x10000 : 0xffff0000) << 1;
+ for (int i1 = 0; i1 < 6; i1++) {
+ for (int j1 = 0; j1 < 6; j1++)
+ m_Hak[i1].m_ifan[j1].y += j;
+ }
+
+ }
+
+ private void _iIIV(int j, int i1) {
+ if (m_Hak == null)
+ m_Hak = new k[6];
+ if (m_ian == null)
+ m_ian = new SimpleMenuElement[10];
+ int l1 = 0;
+ int i2 = 0;
+ int j2 = 0;
+ int k2 = 0;
+ for (int j1 = 0; j1 < 6; j1++) {
+ int l2 = 0;
+ switch (j1) {
+ case 0: // '\0'
+ i2 = 1;
+ l1 = 0x58000;
+ j2 = 0;
+ k2 = 0;
+ break;
+
+ case 4: // '\004'
+ i2 = 1;
+ l1 = 0x38000;
+ j2 = 0xfffe0000;
+ k2 = 0x30000;
+ break;
+
+ case 3: // '\003'
+ i2 = 1;
+ l1 = 0x38000;
+ j2 = 0x20000;
+ k2 = 0x30000;
+ break;
+
+ case 1: // '\001'
+ i2 = 0;
+ l1 = 0x18000;
+ j2 = 0x38000;
+ k2 = 0;
+ break;
+
+ case 2: // '\002'
+ i2 = 0;
+ l1 = 0x58000;
+ j2 = 0xfffc8000;
+ k2 = 0;
+ l2 = 21626;
+ break;
+
+ case 5: // '\005'
+ i2 = 2;
+ l1 = 0x48000;
+ j2 = 0;
+ k2 = 0x50000;
+ break;
+ }
+ if (m_Hak[j1] == null)
+ m_Hak[j1] = new k();
+ m_Hak[j1]._avV();
+ m_Hak[j1].m_aI = m_foraI[i2];
+ m_Hak[j1].m_intI = i2;
+ m_Hak[j1].m_forI = (int) ((long) (int) (0x1000000000000L / (long) l1 >> 16) * (long) m_yI >> 16);
+ m_Hak[j1].m_ifan[m_vaI].x = j + j2;
+ m_Hak[j1].m_ifan[m_vaI].y = i1 + k2;
+ m_Hak[j1].m_ifan[5].x = j + j2;
+ m_Hak[j1].m_ifan[5].y = i1 + k2;
+ m_Hak[j1].m_newI = l2;
+ }
+
+ for (int k1 = 0; k1 < 10; k1++) {
+ if (m_ian[k1] == null)
+ m_ian[k1] = new SimpleMenuElement();
+ m_ian[k1].init();
+ m_ian[k1].x = m_qI;
+ m_ian[k1].m_bI = m_xI;
+ }
+
+ m_ian[0].y = 0x38000;
+ m_ian[1].y = 0x38000;
+ m_ian[2].y = 0x39b05;
+ m_ian[3].y = 0x39b05;
+ m_ian[4].y = 0x40000;
+ m_ian[5].y = 0x35aa6;
+ m_ian[6].y = 0x35aa6;
+ m_ian[7].y = 0x2d413;
+ m_ian[8].y = 0x2d413;
+ m_ian[9].y = 0x50000;
+ m_ian[5].m_bI = (int) ((long) m_xI * 45875L >> 16);
+ m_ian[6].x = (int) (6553L * (long) m_qI >> 16);
+ m_ian[5].x = (int) (6553L * (long) m_qI >> 16);
+ m_ian[9].x = (int) (0x11999L * (long) m_qI >> 16);
+ m_ian[8].x = (int) (0x11999L * (long) m_qI >> 16);
+ m_ian[7].x = (int) (0x11999L * (long) m_qI >> 16);
+ }
+
+ public void _ifIIV(int j, int i1) {
+ m_lf._ifIIV(j, i1);
+ }
+
+ public void _nullvV() {
+ m_ifZ = m_sZ = m_rZ = m_OZ = false;
+ }
+
+ public void _aIIV(int j, int i1) {
+ if (!m_vZ) {
+ m_ifZ = m_sZ = m_rZ = m_OZ = false;
+ if (j > 0)
+ m_ifZ = true;
+ else if (j < 0)
+ m_sZ = true;
+ if (i1 > 0) {
+ m_rZ = true;
+ return;
+ }
+ if (i1 < 0)
+ m_OZ = true;
+ }
+ }
+
+ public synchronized void _casevV() {
+ _doZV(true);
+ m_vZ = true;
+ }
+
+ public synchronized void _avV() {
+ m_vZ = false;
+ }
+
+ public boolean _gotovZ() {
+ return m_vZ;
+ }
+
+ private void _pvV() {
+ int j = m_Hak[1].m_ifan[m_vaI].x - m_Hak[2].m_ifan[m_vaI].x;
+ int i1 = m_Hak[1].m_ifan[m_vaI].y - m_Hak[2].m_ifan[m_vaI].y;
+ int j1 = _doIII(j, i1);
+ int _tmp = (int) (((long) j << 32) / (long) j1 >> 16);
+ i1 = (int) (((long) i1 << 32) / (long) j1 >> 16);
+ m_FZ = false;
+ if (i1 < 0) {
+ m_XZ = true;
+ m_wZ = false;
+ } else if (i1 > 0) {
+ m_wZ = true;
+ m_XZ = false;
+ }
+ boolean flag;
+ if ((flag = (m_Hak[2].m_ifan[m_vaI].y - m_Hak[0].m_ifan[m_vaI].y <= 0 ? -1 : 1) * (m_Hak[2].m_ifan[m_vaI].m_eI - m_Hak[0].m_ifan[m_vaI].m_eI <= 0 ? -1 : 1) > 0) && m_wZ || !flag && m_XZ) {
+ m_dZ = true;
+ return;
+ } else {
+ m_dZ = false;
+ return;
+ }
+ }
+
+ private void _qvV() {
+ if (!m_IZ) {
+ int j = m_Hak[1].m_ifan[m_vaI].x - m_Hak[2].m_ifan[m_vaI].x;
+ int i1 = m_Hak[1].m_ifan[m_vaI].y - m_Hak[2].m_ifan[m_vaI].y;
+ int j1 = _doIII(j, i1);
+ j = (int) (((long) j << 32) / (long) j1 >> 16);
+ i1 = (int) (((long) i1 << 32) / (long) j1 >> 16);
+ if (m_dZ && m_cI >= -m_QI)
+ m_cI -= m_charI;
+ if (m_FZ) {
+ m_cI = 0;
+ m_Hak[1].m_ifan[m_vaI].m_gotoI = (int) ((long) m_Hak[1].m_ifan[m_vaI].m_gotoI * (long) (0x10000 - m_abI) >> 16);
+ m_Hak[2].m_ifan[m_vaI].m_gotoI = (int) ((long) m_Hak[2].m_ifan[m_vaI].m_gotoI * (long) (0x10000 - m_abI) >> 16);
+ if (m_Hak[1].m_ifan[m_vaI].m_gotoI < 6553)
+ m_Hak[1].m_ifan[m_vaI].m_gotoI = 0;
+ if (m_Hak[2].m_ifan[m_vaI].m_gotoI < 6553)
+ m_Hak[2].m_ifan[m_vaI].m_gotoI = 0;
+ }
+ m_Hak[0].m_forI = (int) (11915L * (long) m_yI >> 16);
+ m_Hak[0].m_forI = (int) (11915L * (long) m_yI >> 16);
+ m_Hak[4].m_forI = (int) (18724L * (long) m_yI >> 16);
+ m_Hak[3].m_forI = (int) (18724L * (long) m_yI >> 16);
+ m_Hak[1].m_forI = (int) (43690L * (long) m_yI >> 16);
+ m_Hak[2].m_forI = (int) (11915L * (long) m_yI >> 16);
+ m_Hak[5].m_forI = (int) (14563L * (long) m_yI >> 16);
+ if (m_XZ) {
+ m_Hak[0].m_forI = (int) (18724L * (long) m_yI >> 16);
+ m_Hak[4].m_forI = (int) (14563L * (long) m_yI >> 16);
+ m_Hak[3].m_forI = (int) (18724L * (long) m_yI >> 16);
+ m_Hak[1].m_forI = (int) (43690L * (long) m_yI >> 16);
+ m_Hak[2].m_forI = (int) (10082L * (long) m_yI >> 16);
+ } else if (m_wZ) {
+ m_Hak[0].m_forI = (int) (18724L * (long) m_yI >> 16);
+ m_Hak[4].m_forI = (int) (18724L * (long) m_yI >> 16);
+ m_Hak[3].m_forI = (int) (14563L * (long) m_yI >> 16);
+ m_Hak[1].m_forI = (int) (26214L * (long) m_yI >> 16);
+ m_Hak[2].m_forI = (int) (11915L * (long) m_yI >> 16);
+ }
+ if (m_XZ || m_wZ) {
+ int k1 = -i1;
+ int l1 = j;
+ if (m_XZ && m_kI > -m_longI) {
+ int i2 = 0x10000;
+ if (m_kI < 0)
+ i2 = (int) (((long) (m_longI - (m_kI >= 0 ? m_kI : -m_kI)) << 32) / (long) m_longI >> 16);
+ int k2 = (int) ((long) m_AI * (long) i2 >> 16);
+ int i3 = (int) ((long) k1 * (long) k2 >> 16);
+ int k3 = (int) ((long) l1 * (long) k2 >> 16);
+ int i4 = (int) ((long) j * (long) k2 >> 16);
+ int k4 = (int) ((long) i1 * (long) k2 >> 16);
+ if (m_TI > 32768)
+ m_TI = m_TI - 1638 >= 0 ? m_TI - 1638 : 0;
+ else
+ m_TI = m_TI - 3276 >= 0 ? m_TI - 3276 : 0;
+ m_Hak[4].m_ifan[m_vaI].m_eI -= i3;
+ m_Hak[4].m_ifan[m_vaI].m_dI -= k3;
+ m_Hak[3].m_ifan[m_vaI].m_eI += i3;
+ m_Hak[3].m_ifan[m_vaI].m_dI += k3;
+ m_Hak[5].m_ifan[m_vaI].m_eI -= i4;
+ m_Hak[5].m_ifan[m_vaI].m_dI -= k4;
+ }
+ if (m_wZ && m_kI < m_longI) {
+ int j2 = 0x10000;
+ if (m_kI > 0)
+ j2 = (int) (((long) (m_longI - m_kI) << 32) / (long) m_longI >> 16);
+ int l2 = (int) ((long) m_AI * (long) j2 >> 16);
+ int j3 = (int) ((long) k1 * (long) l2 >> 16);
+ int l3 = (int) ((long) l1 * (long) l2 >> 16);
+ int j4 = (int) ((long) j * (long) l2 >> 16);
+ int l4 = (int) ((long) i1 * (long) l2 >> 16);
+ if (m_TI > 32768)
+ m_TI = m_TI + 1638 >= 0x10000 ? 0x10000 : m_TI + 1638;
+ else
+ m_TI = m_TI + 3276 >= 0x10000 ? 0x10000 : m_TI + 3276;
+ m_Hak[4].m_ifan[m_vaI].m_eI += j3;
+ m_Hak[4].m_ifan[m_vaI].m_dI += l3;
+ m_Hak[3].m_ifan[m_vaI].m_eI -= j3;
+ m_Hak[3].m_ifan[m_vaI].m_dI -= l3;
+ m_Hak[5].m_ifan[m_vaI].m_eI += j4;
+ m_Hak[5].m_ifan[m_vaI].m_dI += l4;
+ }
+ return;
+ }
+ if (m_TI < 26214) {
+ m_TI += 3276;
+ return;
+ }
+ if (m_TI > 39321) {
+ m_TI -= 3276;
+ return;
+ }
+ m_TI = 32768;
+ }
+ }
+
+ public synchronized int _dovI() {
+ m_dZ = m_ifZ;
+ m_FZ = m_sZ;
+ m_XZ = m_OZ;
+ m_wZ = m_rZ;
+ if (m_vZ)
+ _pvV();
+ GameView._dovV();
+ _qvV();
+ int j;
+ if ((j = _uII(m_YI)) == 5 || m_mZ)
+ return 5;
+ if (m_IZ)
+ return 3;
+ if (_newvZ()) {
+ m_NZ = false;
+ return 4;
+ } else {
+ return j;
+ }
+ }
+
+ public boolean _newvZ() {
+ return m_Hak[1].m_ifan[m_vaI].x < m_lf._intvI();
+ }
+
+ public boolean _longvZ() {
+ return m_Hak[1].m_ifan[m_waI].x > m_lf._dovI() || m_Hak[2].m_ifan[m_waI].x > m_lf._dovI();
+ }
+
+ private int _uII(int j) {
+ boolean flag = m_RZ;
+ int i1 = 0;
+ int j1 = j;
+ int j2;
+ do {
+ if (i1 >= j)
+ break;
+ _aaIV(j1 - i1);
+ int k1;
+ if (!flag && _longvZ())
+ k1 = 3;
+ else
+ k1 = _baII(m_waI);
+ if (!flag && m_RZ)
+ return k1 == 3 ? 1 : 2;
+ if (k1 == 0) {
+ if (((j1 = i1 + j1 >> 1) - i1 >= 0 ? j1 - i1 : -(j1 - i1)) < 65)
+ return 5;
+ } else if (k1 == 3) {
+ m_RZ = true;
+ j1 = i1 + j1 >> 1;
+ } else {
+ int i2;
+ if (k1 == 1)
+ do {
+ _caIV(m_waI);
+ j2 = _baII(m_waI);
+ i2 = j2;
+ if (j2 == 0)
+ return 5;
+ } while (i2 != 2);
+ i1 = j1;
+ j1 = j;
+ m_vaI = m_vaI != 1 ? 1 : 0;
+ m_waI = m_waI != 1 ? 1 : 0;
+ }
+ } while (true);
+ int l1;
+ if ((l1 = (int) ((long) (m_Hak[1].m_ifan[m_vaI].x - m_Hak[2].m_ifan[m_vaI].x) * (long) (m_Hak[1].m_ifan[m_vaI].x - m_Hak[2].m_ifan[m_vaI].x) >> 16) + (int) ((long) (m_Hak[1].m_ifan[m_vaI].y - m_Hak[2].m_ifan[m_vaI].y) * (long) (m_Hak[1].m_ifan[m_vaI].y - m_Hak[2].m_ifan[m_vaI].y) >> 16)) < 0xf0000)
+ m_IZ = true;
+ if (l1 > 0x460000)
+ m_IZ = true;
+ return 0;
+ }
+
+ private void _aIV(int j) {
+ for (int i1 = 0; i1 < 6; i1++) {
+ k k1;
+ SimpleMenuElement n1;
+ (n1 = (k1 = m_Hak[i1]).m_ifan[j]).m_nullI = 0;
+ n1.m_longI = 0;
+ n1.m_fI = 0;
+ n1.m_longI -= (int) (((long) m_voidI << 32) / (long) k1.m_forI >> 16);
+ }
+
+ if (!m_IZ) {
+ _akkV(m_Hak[0], m_ian[1], m_Hak[2], j, 0x10000);
+ _akkV(m_Hak[0], m_ian[0], m_Hak[1], j, 0x10000);
+ _akkV(m_Hak[2], m_ian[6], m_Hak[4], j, 0x20000);
+ _akkV(m_Hak[1], m_ian[5], m_Hak[3], j, 0x20000);
+ }
+ _akkV(m_Hak[0], m_ian[2], m_Hak[3], j, 0x10000);
+ _akkV(m_Hak[0], m_ian[3], m_Hak[4], j, 0x10000);
+ _akkV(m_Hak[3], m_ian[4], m_Hak[4], j, 0x10000);
+ _akkV(m_Hak[5], m_ian[8], m_Hak[3], j, 0x10000);
+ _akkV(m_Hak[5], m_ian[7], m_Hak[4], j, 0x10000);
+ _akkV(m_Hak[5], m_ian[9], m_Hak[0], j, 0x10000);
+ SimpleMenuElement n2 = m_Hak[2].m_ifan[j];
+ m_cI = (int) ((long) m_cI * (long) (0x10000 - m_jI) >> 16);
+ n2.m_fI = m_cI;
+ if (n2.m_gotoI > m_PI)
+ n2.m_gotoI = m_PI;
+ if (n2.m_gotoI < -m_PI)
+ n2.m_gotoI = -m_PI;
+ int j1 = 0;
+ int l1 = 0;
+ for (int i2 = 0; i2 < 6; i2++) {
+ j1 += m_Hak[i2].m_ifan[j].m_eI;
+ l1 += m_Hak[i2].m_ifan[j].m_dI;
+ }
+
+ j1 = (int) (((long) j1 << 32) / 0x60000L >> 16);
+ l1 = (int) (((long) l1 << 32) / 0x60000L >> 16);
+ int j3 = 0;
+ for (int k3 = 0; k3 < 6; k3++) {
+ int j2 = m_Hak[k3].m_ifan[j].m_eI - j1;
+ int k2 = m_Hak[k3].m_ifan[j].m_dI - l1;
+ if ((j3 = _doIII(j2, k2)) > 0x1e0000) {
+ int l2 = (int) (((long) j2 << 32) / (long) j3 >> 16);
+ int i3 = (int) (((long) k2 << 32) / (long) j3 >> 16);
+ m_Hak[k3].m_ifan[j].m_eI -= l2;
+ m_Hak[k3].m_ifan[j].m_dI -= i3;
+ }
+ }
+
+ byte byte0 = ((byte) (m_Hak[2].m_ifan[j].y - m_Hak[0].m_ifan[j].y < 0 ? -1 : 1));
+ byte byte1 = ((byte) (m_Hak[2].m_ifan[j].m_eI - m_Hak[0].m_ifan[j].m_eI < 0 ? -1 : 1));
+ if (byte0 * byte1 > 0) {
+ m_kI = j3;
+ return;
+ } else {
+ m_kI = -j3;
+ return;
+ }
+ }
+
+ private void _akkV(k k1, SimpleMenuElement n1, k k2, int j, int i1) {
+ SimpleMenuElement n2 = k1.m_ifan[j];
+ SimpleMenuElement n3 = k2.m_ifan[j];
+ int j1 = n2.x - n3.x;
+ int l1 = n2.y - n3.y;
+ int i2;
+ if (((i2 = _doIII(j1, l1)) >= 0 ? i2 : -i2) >= 3) {
+ j1 = (int) (((long) j1 << 32) / (long) i2 >> 16);
+ l1 = (int) (((long) l1 << 32) / (long) i2 >> 16);
+ int j2 = i2 - n1.y;
+ int l2 = (int) ((long) j1 * (long) (int) ((long) j2 * (long) n1.x >> 16) >> 16);
+ int i3 = (int) ((long) l1 * (long) (int) ((long) j2 * (long) n1.x >> 16) >> 16);
+ int j3 = n2.m_eI - n3.m_eI;
+ int k3 = n2.m_dI - n3.m_dI;
+ int l3 = (int) ((long) ((int) ((long) j1 * (long) j3 >> 16) + (int) ((long) l1 * (long) k3 >> 16)) * (long) n1.m_bI >> 16);
+ l2 += (int) ((long) j1 * (long) l3 >> 16);
+ i3 += (int) ((long) l1 * (long) l3 >> 16);
+ l2 = (int) ((long) l2 * (long) i1 >> 16);
+ i3 = (int) ((long) i3 * (long) i1 >> 16);
+ n2.m_nullI -= l2;
+ n2.m_longI -= i3;
+ n3.m_nullI += l2;
+ n3.m_longI += i3;
+ }
+ }
+
+ private void _aIIV(int j, int i1, int j1) {
+ for (int l1 = 0; l1 < 6; l1++) {
+ SimpleMenuElement n1 = m_Hak[l1].m_ifan[j];
+ SimpleMenuElement n2;
+ (n2 = m_Hak[l1].m_ifan[i1]).x = (int) ((long) n1.m_eI * (long) j1 >> 16);
+ n2.y = (int) ((long) n1.m_dI * (long) j1 >> 16);
+ int k1 = (int) ((long) j1 * (long) m_Hak[l1].m_forI >> 16);
+ n2.m_eI = (int) ((long) n1.m_nullI * (long) k1 >> 16);
+ n2.m_dI = (int) ((long) n1.m_longI * (long) k1 >> 16);
+ }
+
+ }
+
+ private void _zIIV(int j, int i1, int j1) {
+ for (int k1 = 0; k1 < 6; k1++) {
+ SimpleMenuElement n1 = m_Hak[k1].m_ifan[j];
+ SimpleMenuElement n2 = m_Hak[k1].m_ifan[i1];
+ SimpleMenuElement n3 = m_Hak[k1].m_ifan[j1];
+ n1.x = n2.x + (n3.x >> 1);
+ n1.y = n2.y + (n3.y >> 1);
+ n1.m_eI = n2.m_eI + (n3.m_eI >> 1);
+ n1.m_dI = n2.m_dI + (n3.m_dI >> 1);
+ }
+
+ }
+
+ private void _aaIV(int j) {
+ _aIV(m_vaI);
+ _aIIV(m_vaI, 2, j);
+ _zIIV(4, m_vaI, 2);
+ _aIV(4);
+ _aIIV(4, 3, j >> 1);
+ _zIIV(4, m_vaI, 3);
+ _zIIV(m_waI, m_vaI, 2);
+ _zIIV(m_waI, m_waI, 3);
+
+ // wheels?!?!?!?! oh my god i found it!!!!!
+ for (int i1 = 1; i1 <= 2; i1++) {
+ SimpleMenuElement n1 = m_Hak[i1].m_ifan[m_vaI];
+ SimpleMenuElement n2;
+ (n2 = m_Hak[i1].m_ifan[m_waI]).m_bI = n1.m_bI + (int) ((long) j * (long) n1.m_gotoI >> 16);
+ n2.m_gotoI = n1.m_gotoI + (int) ((long) j * (long) (int) ((long) m_Hak[i1].m_newI * (long) n1.m_fI >> 16) >> 16);
+ }
+
+ }
+
+ private int _baII(int j) {
+ byte byte0 = 2;
+ int i1;
+ i1 = (i1 = m_Hak[1].m_ifan[j].x >= m_Hak[2].m_ifan[j].x ? m_Hak[1].m_ifan[j].x : m_Hak[2].m_ifan[j].x) >= m_Hak[5].m_ifan[j].x ? i1 : m_Hak[5].m_ifan[j].x;
+ int j1;
+ j1 = (j1 = m_Hak[1].m_ifan[j].x >= m_Hak[2].m_ifan[j].x ? m_Hak[2].m_ifan[j].x : m_Hak[1].m_ifan[j].x) >= m_Hak[5].m_ifan[j].x ? m_Hak[5].m_ifan[j].x : j1;
+ m_lf._aIIV(j1 - m_foraI[0], i1 + m_foraI[0], m_Hak[5].m_ifan[j].y);
+ int k1 = m_Hak[1].m_ifan[j].x - m_Hak[2].m_ifan[j].x;
+ int l1 = m_Hak[1].m_ifan[j].y - m_Hak[2].m_ifan[j].y;
+ int i2 = _doIII(k1, l1);
+ k1 = (int) (((long) k1 << 32) / (long) i2 >> 16);
+ int j2 = -(int) (((long) l1 << 32) / (long) i2 >> 16);
+ int k2 = k1;
+ for (int l2 = 0; l2 < 6; l2++) {
+ if (l2 == 4 || l2 == 3)
+ continue;
+ SimpleMenuElement n1 = m_Hak[l2].m_ifan[j];
+ if (l2 == 0) {
+ n1.x += (int) ((long) j2 * 0x10000L >> 16);
+ n1.y += (int) ((long) k2 * 0x10000L >> 16);
+ }
+ int i3 = m_lf._anvI(n1, m_Hak[l2].m_intI);
+ if (l2 == 0) {
+ n1.x -= (int) ((long) j2 * 0x10000L >> 16);
+ n1.y -= (int) ((long) k2 * 0x10000L >> 16);
+ }
+ m_EI = m_lf.m_eI;
+ m_CI = m_lf.m_dI;
+ if (l2 == 5 && i3 != 2)
+ m_mZ = true;
+ if (l2 == 1 && i3 != 2)
+ m_NZ = true;
+ if (i3 == 1) {
+ m_xaI = l2;
+ byte0 = 1;
+ continue;
+ }
+ if (i3 != 0)
+ continue;
+ m_xaI = l2;
+ byte0 = 0;
+ break;
+ }
+
+ return byte0;
+ }
+
+ private void _caIV(int j) {
+ k k1;
+ SimpleMenuElement n1;
+ (n1 = (k1 = m_Hak[m_xaI]).m_ifan[j]).x += (int) ((long) m_EI * 3276L >> 16);
+ n1.y += (int) ((long) m_CI * 3276L >> 16);
+ int i1;
+ int j1;
+ int l1;
+ int i2;
+ int j2;
+ if (m_FZ && (m_xaI == 2 || m_xaI == 1) && n1.m_gotoI < 6553) {
+ i1 = m_gI - m_WI;
+ j1 = 13107;
+ l1 = 39321;
+ i2 = 26214 - m_WI;
+ j2 = 26214 - m_WI;
+ } else {
+ i1 = m_gI;
+ j1 = m_fI;
+ l1 = m_eI;
+ i2 = m_aeI;
+ j2 = m_adI;
+ }
+ int k2 = _doIII(m_EI, m_CI);
+ m_EI = (int) (((long) m_EI << 32) / (long) k2 >> 16);
+ m_CI = (int) (((long) m_CI << 32) / (long) k2 >> 16);
+ int l2 = n1.m_eI;
+ int i3 = n1.m_dI;
+ int j3 = -((int) ((long) l2 * (long) m_EI >> 16) + (int) ((long) i3 * (long) m_CI >> 16));
+ int k3 = -((int) ((long) l2 * (long) (-m_CI) >> 16) + (int) ((long) i3 * (long) m_EI >> 16));
+ int l3 = (int) ((long) i1 * (long) n1.m_gotoI >> 16) - (int) ((long) j1 * (long) (int) (((long) k3 << 32) / (long) k1.m_aI >> 16) >> 16);
+ int i4 = (int) ((long) i2 * (long) k3 >> 16) - (int) ((long) l1 * (long) (int) ((long) n1.m_gotoI * (long) k1.m_aI >> 16) >> 16);
+ int j4 = -(int) ((long) j2 * (long) j3 >> 16);
+ int k4 = (int) ((long) (-i4) * (long) (-m_CI) >> 16);
+ int l4 = (int) ((long) (-i4) * (long) m_EI >> 16);
+ int i5 = (int) ((long) (-j4) * (long) m_EI >> 16);
+ int j5 = (int) ((long) (-j4) * (long) m_CI >> 16);
+ n1.m_gotoI = l3;
+ n1.m_eI = k4 + i5;
+ n1.m_dI = l4 + j5;
+ }
+
+ public void _ifZV(boolean flag) {
+ m_doZ = flag;
+ }
+
+ public void _caseIV(int j) {
+ m_GI = (int) (((long) (int) (0xa0000L * (long) (j << 16) >> 16) << 32) / 0x800000L >> 16);
+ }
+
+ public int _elsevI() {
+ if (m_doZ)
+ m_oI = (int) (((long) m_aaan[0].m_eI << 32) / 0x180000L >> 16) + (int) ((long) m_oI * 57344L >> 16);
+ else
+ m_oI = 0;
+ m_oI = m_oI >= m_GI ? m_GI : m_oI;
+ m_oI = m_oI >= -m_GI ? m_oI : -m_GI;
+ return (m_aaan[0].x + m_oI << 2) >> 16;
+ }
+
+ public int _ifvI() {
+ if (m_doZ)
+ m_nI = (int) (((long) m_aaan[0].m_dI << 32) / 0x180000L >> 16) + (int) ((long) m_nI * 57344L >> 16);
+ else
+ m_nI = 0;
+ m_nI = m_nI >= m_GI ? m_GI : m_nI;
+ m_nI = m_nI >= -m_GI ? m_nI : -m_GI;
+ return (m_aaan[0].y + m_nI << 2) >> 16;
+ }
+
+ public int _tryvI() {
+ int j = m_aaan[1].x >= m_aaan[2].x ? m_aaan[1].x : m_aaan[2].x;
+ if (m_IZ)
+ return m_lf._aII(m_aaan[0].x);
+ else
+ return m_lf._aII(j);
+ }
+
+ public void _charvV() {
+ synchronized (m_Hak) {
+ for (int j = 0; j < 6; j++) {
+ m_Hak[j].m_ifan[5].x = m_Hak[j].m_ifan[m_vaI].x;
+ m_Hak[j].m_ifan[5].y = m_Hak[j].m_ifan[m_vaI].y;
+ m_Hak[j].m_ifan[5].m_bI = m_Hak[j].m_ifan[m_vaI].m_bI;
+ }
+
+ m_Hak[0].m_ifan[5].m_eI = m_Hak[0].m_ifan[m_vaI].m_eI;
+ m_Hak[0].m_ifan[5].m_dI = m_Hak[0].m_ifan[m_vaI].m_dI;
+ m_Hak[2].m_ifan[5].m_gotoI = m_Hak[2].m_ifan[m_vaI].m_gotoI;
+ }
+ }
+
+ public void _voidvV() {
+ synchronized (m_Hak) {
+ for (int j = 0; j < 6; j++) {
+ m_aaan[j].x = m_Hak[j].m_ifan[5].x;
+ m_aaan[j].y = m_Hak[j].m_ifan[5].y;
+ m_aaan[j].m_bI = m_Hak[j].m_ifan[5].m_bI;
+ }
+
+ m_aaan[0].m_eI = m_Hak[0].m_ifan[5].m_eI;
+ m_aaan[0].m_dI = m_Hak[0].m_ifan[5].m_dI;
+ m_aaan[2].m_gotoI = m_Hak[2].m_ifan[5].m_gotoI;
+ }
+ }
+
+ private void _aiIV(GameView view, int i1, int j1) {
+ int k1 = FPMath._ifIII(m_aaan[0].x - m_aaan[3].x, m_aaan[0].y - m_aaan[3].y);
+ int l1 = FPMath._ifIII(m_aaan[0].x - m_aaan[4].x, m_aaan[0].y - m_aaan[4].y);
+ int engineX = (m_aaan[0].x >> 1) + (m_aaan[3].x >> 1);
+ int engineY = (m_aaan[0].y >> 1) + (m_aaan[3].y >> 1);
+ int fenderX = (m_aaan[0].x >> 1) + (m_aaan[4].x >> 1);
+ int fenderY = (m_aaan[0].y >> 1) + (m_aaan[4].y >> 1);
+ int i3 = -j1;
+ int j3 = i1;
+ engineX += (int) ((long) i3 * 0x10000L >> 16) - (int) ((long) i1 * 32768L >> 16);
+ engineY += (int) ((long) j3 * 0x10000L >> 16) - (int) ((long) j1 * 32768L >> 16);
+ fenderX += (int) ((long) i3 * 0x10000L >> 16) - (int) ((long) i1 * 0x1ccccL >> 16);
+ fenderY += (int) ((long) j3 * 0x10000L >> 16) - (int) ((long) j1 * 0x20000L >> 16);
+ view.drawFender((fenderX << 2) / (float) 0xFFFF /*>> 16*/, (fenderY << 2) / (float) 0xFFFF /*>> 16*/, l1);
+ view.drawEngine((engineX << 2) / (float) 0xFFFF /*>> 16*/, (engineY << 2) / (float) 0xFFFF /*>> 16*/, k1);
+ }
+
+ private void _laiV(GameView view) {
+ view.setColor(128, 128, 128);
+ view.drawLine(m_aaan[3].x, m_aaan[3].y, m_aaan[1].x, m_aaan[1].y);
+ }
+
+ private void _aiV(GameView gameView) {
+ int i1 = 1;
+ int j1 = 1;
+ switch (m_hI) {
+ case 2: // '\002'
+ case 3: // '\003'
+ i1 = j1 = 0;
+ break;
+
+ case 1: // '\001'
+ i1 = 0;
+ break;
+ }
+ gameView.drawWheel((m_aaan[2].x << 2) / (float) 0xFFFF /*>> 16*/, (m_aaan[2].y << 2) / (float) 0xFFFF /*>> 16*/, i1);
+ gameView.drawWheel((m_aaan[1].x << 2) / (float) 0xFFFF /*>> 16*/, (m_aaan[1].y << 2) / (float) 0xFFFF /*>> 16*/, j1);
+ }
+
+ private void _doiV(GameView gameView) {
+ int i1;
+ int j1 = (int) ((long) (i1 = m_Hak[1].m_aI) * 58982L >> 16);
+ int k1 = (int) ((long) i1 * 45875L >> 16);
+ gameView.setColor(0, 0, 0);
+ if (getGDActivity().isMenuShown()) {
+ gameView.drawLineWheel((m_aaan[1].x << 2) >> 16, (m_aaan[1].y << 2) >> 16, (i1 + i1 << 2) >> 16);
+ gameView.drawLineWheel((m_aaan[1].x << 2) >> 16, (m_aaan[1].y << 2) >> 16, (j1 + j1 << 2) >> 16);
+ gameView.drawLineWheel((m_aaan[2].x << 2) >> 16, (m_aaan[2].y << 2) >> 16, (i1 + i1 << 2) >> 16);
+ gameView.drawLineWheel((m_aaan[2].x << 2) >> 16, (m_aaan[2].y << 2) >> 16, (k1 + k1 << 2) >> 16);
+ }
+
+ // right wheel
+ int l1 = j1;
+ int i2 = 0;
+ int j2;
+ int k2 = FPMath._doII(j2 = m_aaan[1].m_bI);
+ int l2 = FPMath.sin(j2);
+ int i3 = l1;
+ l1 = (int) ((long) k2 * (long) l1 >> 16) + (int) ((long) (-l2) * (long) i2 >> 16);
+ i2 = (int) ((long) l2 * (long) i3 >> 16) + (int) ((long) k2 * (long) i2 >> 16);
+ k2 = FPMath._doII(j2 = 0x141b2);
+ l2 = FPMath.sin(j2);
+ for (int k3 = 0; k3 < 5; k3++) {
+ gameView.drawLine(m_aaan[1].x, m_aaan[1].y, m_aaan[1].x + l1, m_aaan[1].y + i2);
+ i3 = l1;
+ l1 = (int) ((long) k2 * (long) l1 >> 16) + (int) ((long) (-l2) * (long) i2 >> 16);
+ i2 = (int) ((long) l2 * (long) i3 >> 16) + (int) ((long) k2 * (long) i2 >> 16);
+ }
+
+ // left wheel
+ l1 = j1;
+ i2 = 0;
+ // k2 = FPMath._doII(j2 = m_aaan[2].m_bI);
+ k2 = FPMath._doII(j2 = Math.round(m_aaan[2].m_bI / 1.75f));
+ l2 = FPMath.sin(j2);
+ i3 = l1;
+ l1 = (int) ((long) k2 * (long) l1 >> 16) + (int) ((long) (-l2) * (long) i2 >> 16);
+ i2 = (int) ((long) l2 * (long) i3 >> 16) + (int) ((long) k2 * (long) i2 >> 16);
+ k2 = FPMath._doII(j2 = 0x141b2);
+ l2 = FPMath.sin(j2);
+
+ boolean toUpdate = true;
+ for (int l3 = 0; l3 < 5; l3++) {
+ if (toUpdate) {
+ // Log.d("AGDTR", "toUpdate is true");
+ leftWheelParams[l3][0] = m_aaan[2].x;
+ leftWheelParams[l3][1] = m_aaan[2].y;
+ leftWheelParams[l3][2] = m_aaan[2].x + l1;
+ leftWheelParams[l3][3] = m_aaan[2].y + i2;
+ }
+ // gameView.drawLine(m_aaan[2].x, m_aaan[2].y, m_aaan[2].x + l1, m_aaan[2].y + i2);
+ gameView.drawLine(leftWheelParams[l3][0], leftWheelParams[l3][1], leftWheelParams[l3][2], leftWheelParams[l3][3]);
+ int j3 = l1;
+ l1 = (int) ((long) k2 * (long) l1 >> 16) + (int) ((long) (-l2) * (long) i2 >> 16);
+ i2 = (int) ((long) l2 * (long) j3 >> 16) + (int) ((long) k2 * (long) i2 >> 16);
+ }
+ // if (toUpdate) leftWheelLastUpdated = System.currentTimeMillis();
+ // Log.d("AGDTR", "diff: " + (System.currentTimeMillis() - leftWheelLastUpdated));
+
+ if (m_hI > 0) {
+ gameView.setColor(255, 0, 0);
+ if (m_hI > 2)
+ gameView.setColor(100, 100, 255);
+ gameView.drawLineWheel((m_aaan[2].x << 2) / (float) 0xFFFF /*>> 16*/, (m_aaan[2].y << 2) / (float) 0xFFFF /*>> 16*/, 4);
+ gameView.drawLineWheel((m_aaan[1].x << 2) / (float) 0xFFFF /*>> 16*/, (m_aaan[1].y << 2) / (float) 0xFFFF /*>> 16*/, 4);
+ }
+ }
+
+ private void _ifiIIV(GameView j, int i1, int j1, int k1, int l1) {
+ int i2 = 0;
+ int j2 = 0x10000;
+ int k2 = m_aaan[0].x;
+ int l2 = m_aaan[0].y;
+ int i3 = 0;
+ int j3 = 0;
+ int k3 = 0;
+ int l3 = 0;
+ int i4 = 0;
+ int j4 = 0;
+ int k4 = 0;
+ int l4 = 0;
+ int i5 = 0;
+ int j5 = 0;
+ int k5 = 0;
+ int l5 = 0;
+ int i6 = 0;
+ int j6 = 0;
+ int k6 = 0;
+ int l6 = 0;
+ int ai[][] = (int[][]) null;
+ int ai1[][] = (int[][]) null;
+ int ai2[][] = (int[][]) null;
+ if (m_elseZ) {
+ if (m_TI < 32768) {
+ ai1 = m_ucaaI;
+ ai2 = m_KaaI;
+ j2 = (int) ((long) m_TI * 0x20000L >> 16);
+ } else if (m_TI > 32768) {
+ i2 = 1;
+ ai1 = m_KaaI;
+ ai2 = m_SaaI;
+ j2 = (int) ((long) (m_TI - 32768) * 0x20000L >> 16);
+ } else {
+ ai = m_KaaI;
+ }
+ } else if (m_TI < 32768) {
+ ai1 = m_DaaI;
+ ai2 = m_wcaaI;
+ j2 = (int) ((long) m_TI * 0x20000L >> 16);
+ } else if (m_TI > 32768) {
+ i2 = 1;
+ ai1 = m_wcaaI;
+ ai2 = m_MaaI;
+ j2 = (int) ((long) (m_TI - 32768) * 0x20000L >> 16);
+ } else {
+ ai = m_wcaaI;
+ }
+ for (int j7 = 0; j7 < m_KaaI.length; j7++) {
+ int i8;
+ int j8;
+ if (ai1 != null) {
+ j8 = (int) ((long) ai1[j7][0] * (long) (0x10000 - j2) >> 16) + (int) ((long) ai2[j7][0] * (long) j2 >> 16);
+ i8 = (int) ((long) ai1[j7][1] * (long) (0x10000 - j2) >> 16) + (int) ((long) ai2[j7][1] * (long) j2 >> 16);
+ } else {
+ j8 = ai[j7][0];
+ i8 = ai[j7][1];
+ }
+ int k8 = k2 + (int) ((long) k1 * (long) j8 >> 16) + (int) ((long) i1 * (long) i8 >> 16);
+ int l8 = l2 + (int) ((long) l1 * (long) j8 >> 16) + (int) ((long) j1 * (long) i8 >> 16);
+ switch (j7) {
+ case 0: // '\0'
+ k4 = k8;
+ l4 = l8;
+ break;
+
+ case 1: // '\001'
+ i5 = k8;
+ j5 = l8;
+ break;
+
+ case 2: // '\002'
+ k5 = k8;
+ l5 = l8;
+ break;
+
+ case 3: // '\003'
+ i6 = k8;
+ j6 = l8;
+ break;
+
+ case 4: // '\004'
+ k6 = k8;
+ l6 = l8;
+ break;
+
+ case 5: // '\005'
+ k3 = k8;
+ l3 = l8;
+ break;
+
+ case 6: // '\006'
+ i4 = k8;
+ j4 = l8;
+ break;
+
+ case 7: // '\007'
+ i3 = k8;
+ j3 = l8;
+ break;
+ }
+ }
+
+ int i7 = (int) ((long) m_JaaI[i2][0] * (long) (0x10000 - j2) >> 16) + (int) ((long) m_JaaI[i2 + 1][0] * (long) j2 >> 16);
+ if (m_elseZ) {
+ j._aIIIV(k3 << 2, l3 << 2, k4 << 2, l4 << 2, 1);
+ j._aIIIV(k4 << 2, l4 << 2, i5 << 2, j5 << 2, 1);
+ j.drawBikerPart(i5 << 2, j5 << 2, k5 << 2, l5 << 2, 2, i7);
+ j._aIIIV(k5 << 2, l5 << 2, k6 << 2, l6 << 2, 0);
+ int k7 = FPMath._ifIII(i1, j1);
+ if (m_TI > 32768)
+ k7 += 20588;
+ j.drawHelmet((i6 << 2) / (float) 0xFFFF /*>> 16*/, (j6 << 2) / (float) 0xFFFF /*>> 16*/, k7);
+ } else {
+ j.setColor(0, 0, 0);
+ j.drawLine(k3, l3, k4, l4);
+ j.drawLine(k4, l4, i5, j5);
+ j.setColor(0, 0, 128);
+ j.drawLine(i5, j5, k5, l5);
+ j.drawLine(k5, l5, k6, l6);
+ j.drawLine(k6, l6, i3, j3);
+ int l7 = 0x10000;
+ j.setColor(156, 0, 0);
+ j.drawLineWheel((i6 << 2) >> 16, (j6 << 2) >> 16, (l7 + l7 << 2) >> 16);
+ }
+ j.setColor(0, 0, 0);
+ j.drawSteering((i3 << 2) >> 16, (j3 << 2) >> 16);
+ j.drawSteering((i4 << 2) >> 16, (j4 << 2) >> 16);
+ }
+
+ private void _aiIIV(GameView j, int i1, int j1, int k1, int l1) {
+ int i2 = m_aaan[2].x;
+ int j2 = m_aaan[2].y;
+ int k2 = i2 + (int) ((long) k1 * (long) 32768 >> 16);
+ int l2 = j2 + (int) ((long) l1 * (long) 32768 >> 16);
+ int i3 = i2 - (int) ((long) k1 * (long) 32768 >> 16);
+ int j3 = j2 - (int) ((long) l1 * (long) 32768 >> 16);
+ int k3 = m_aaan[0].x + (int) ((long) i1 * 32768L >> 16);
+ int l3 = m_aaan[0].y + (int) ((long) j1 * 32768L >> 16);
+ int i4 = k3 - (int) ((long) i1 * 0x20000L >> 16);
+ int j4 = l3 - (int) ((long) j1 * 0x20000L >> 16);
+ int k4 = i4 + (int) ((long) k1 * 0x10000L >> 16);
+ int l4 = j4 + (int) ((long) l1 * 0x10000L >> 16);
+ int i5 = i4 + (int) ((long) i1 * 49152L >> 16) + (int) ((long) k1 * 49152L >> 16);
+ int j5 = j4 + (int) ((long) j1 * 49152L >> 16) + (int) ((long) l1 * 49152L >> 16);
+ int k5 = i4 + (int) ((long) k1 * 32768L >> 16);
+ int l5 = j4 + (int) ((long) l1 * 32768L >> 16);
+ int i6 = m_aaan[1].x;
+ int j6 = m_aaan[1].y;
+ int k6 = m_aaan[4].x - (int) ((long) i1 * 49152L >> 16);
+ int l6 = m_aaan[4].y - (int) ((long) j1 * 49152L >> 16);
+ int i7 = k6 - (int) ((long) k1 * 32768L >> 16);
+ int j7 = l6 - (int) ((long) l1 * 32768L >> 16);
+ int k7 = (k6 - (int) ((long) i1 * 0x20000L >> 16)) + (int) ((long) k1 * 16384L >> 16);
+ int l7 = (l6 - (int) ((long) j1 * 0x20000L >> 16)) + (int) ((long) l1 * 16384L >> 16);
+ int i8 = m_aaan[3].x;
+ int j8 = m_aaan[3].y;
+ int k8 = i8 + (int) ((long) k1 * 32768L >> 16);
+ int l8 = j8 + (int) ((long) l1 * 32768L >> 16);
+ int i9 = (i8 + (int) ((long) k1 * 0x1c000L >> 16)) - (int) ((long) i1 * 32768L >> 16);
+ int j9 = (j8 + (int) ((long) l1 * 0x1c000L >> 16)) - (int) ((long) j1 * 32768L >> 16);
+ j.setColor(50, 50, 50);
+ j.drawLineWheel((k5 << 2) >> 16, (l5 << 2) >> 16, (32768 + 32768 << 2) >> 16);
+ if (!m_IZ) {
+ j.drawLine(k2, l2, k4, l4);
+ j.drawLine(i3, j3, i4, j4);
+ }
+ j.drawLine(k3, l3, i4, j4);
+ j.drawLine(k3, l3, i8, j8);
+ j.drawLine(i5, j5, k8, l8);
+ j.drawLine(k8, l8, i9, j9);
+ if (!m_IZ) {
+ j.drawLine(i8, j8, i6, j6);
+ j.drawLine(i9, j9, i6, j6);
+ }
+ j.drawLine(k4, l4, i7, j7);
+ j.drawLine(i5, j5, k6, l6);
+ j.drawLine(k6, l6, k7, l7);
+ j.drawLine(i7, j7, k7, l7);
+ }
+
+ public void _ifiV(GameView j) {
+ j._tryvV();
+ int i1 = m_aaan[3].x - m_aaan[4].x;
+ int j1 = m_aaan[3].y - m_aaan[4].y;
+ int k1;
+ if ((k1 = _doIII(i1, j1)) != 0) {
+ i1 = (int) (((long) i1 << 32) / (long) k1 >> 16);
+ j1 = (int) (((long) j1 << 32) / (long) k1 >> 16);
+ }
+ int l1 = -j1;
+ int i2 = i1;
+ if (m_IZ) {
+ int k2 = m_aaan[4].x;
+ int j2;
+ if ((j2 = m_aaan[3].x) >= k2) {
+ int l2 = j2;
+ j2 = k2;
+ k2 = l2;
+ }
+ m_lf.levels._aIIV(j2, k2);
+ }
+
+ Loader loader = getLevelLoader();
+ if (loader != null && loader.isPerspectiveEnabled())
+ m_lf._aiIV(j, m_aaan[0].x, m_aaan[0].y);
+ if (m_UZ)
+ _aiIV(j, i1, j1);
+ if (!getGDActivity().isMenuShown())
+ _aiV(j);
+ _doiV(j);
+ if (m_UZ)
+ j.setColor(170, 0, 0);
+ else
+ j.setColor(50, 50, 50);
+ j._ifIIIV((m_aaan[1].x << 2) >> 16, (m_aaan[1].y << 2) >> 16, (m_foraI[0] << 2) >> 16, FPMath._ifIII(i1, j1));
+ if (!m_IZ)
+ _laiV(j);
+ _ifiIIV(j, i1, j1, l1, i2);
+ if (!m_UZ)
+ _aiIIV(j, i1, j1, l1, i2);
+ m_lf._aiV(j);
+ }
+
+}
diff --git a/src/org/happysanta/gd/Game/k.java b/src/org/happysanta/gd/Game/k.java
new file mode 100755
index 0000000..7a45482
--- /dev/null
+++ b/src/org/happysanta/gd/Game/k.java
@@ -0,0 +1,34 @@
+package org.happysanta.gd.Game;
+
+// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.kpdus.com/jad.html
+// Decompiler options: packimports(3) fieldsfirst ansi
+
+
+import org.happysanta.gd.Menu.SimpleMenuElement;
+
+public class k {
+
+ public boolean m_doZ;
+ public int m_aI;
+ public int m_intI;
+ public int m_forI;
+ public int m_newI;
+ public SimpleMenuElement m_ifan[];
+
+ public k() {
+ m_ifan = new SimpleMenuElement[6];
+ for (int i = 0; i < 6; i++)
+ m_ifan[i] = new SimpleMenuElement();
+
+ _avV();
+ }
+
+ public void _avV() {
+ m_aI = m_forI = m_newI = 0;
+ m_doZ = true;
+ for (int i = 0; i < 6; i++)
+ m_ifan[i].init();
+
+ }
+}
diff --git a/src/org/happysanta/gd/Global.java b/src/org/happysanta/gd/Global.java
new file mode 100755
index 0000000..3fb600b
--- /dev/null
+++ b/src/org/happysanta/gd/Global.java
@@ -0,0 +1,21 @@
+package org.happysanta.gd;
+
+import android.graphics.Typeface;
+
+public class Global {
+
+ public static final boolean DEBUG = false;
+ public static final boolean DISABLE_SCALING = false;
+ public static final boolean INSTALLED_FROM_APK = true;
+ public static final boolean ACRA_ENABLED = true;
+ // public static final boolean ENABLE_TOUCH_HACK_FOR_ALL = false;
+
+ public static float density = 0;
+ public static Typeface robotoCondensedTypeface;
+
+ static {
+ density = Helpers.getGDActivity().getResources().getDisplayMetrics().density;
+ robotoCondensedTypeface = Typeface.createFromAsset(Helpers.getGDActivity().getAssets(), "RobotoCondensed-Regular.ttf");
+ }
+
+}
diff --git a/src/org/happysanta/gd/Helpers.java b/src/org/happysanta/gd/Helpers.java
new file mode 100755
index 0000000..667a880
--- /dev/null
+++ b/src/org/happysanta/gd/Helpers.java
@@ -0,0 +1,309 @@
+package org.happysanta.gd;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Build;
+import android.util.Log;
+import org.happysanta.gd.Game.GameView;
+import org.happysanta.gd.Levels.Loader;
+import org.happysanta.gd.Menu.Menu;
+import org.happysanta.gd.Storage.LevelsManager;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class Helpers {
+
+ private static char[] cp1251Map = new char[]{
+ '\u0000', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\u0007',
+ '\u0008', '\u0009', '\n', '\u000B', '\u000C', '\r', '\u000E', '\u000F',
+ '\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017',
+ '\u0018', '\u0019', '\u001A', '\u001B', '\u001C', '\u001D', '\u001E', '\u001F',
+ '\u0020', '\u0021', '\u0022', '\u0023', '\u0024', '\u0025', '\u0026', '\'',
+ '\u0028', '\u0029', '\u002A', '\u002B', '\u002C', '\u002D', '\u002E', '\u002F',
+ '\u0030', '\u0031', '\u0032', '\u0033', '\u0034', '\u0035', '\u0036', '\u0037',
+ '\u0038', '\u0039', '\u003A', '\u003B', '\u003C', '\u003D', '\u003E', '\u003F',
+ '\u0040', '\u0041', '\u0042', '\u0043', '\u0044', '\u0045', '\u0046', '\u0047',
+ '\u0048', '\u0049', '\u004A', '\u004B', '\u004C', '\u004D', '\u004E', '\u004F',
+ '\u0050', '\u0051', '\u0052', '\u0053', '\u0054', '\u0055', '\u0056', '\u0057',
+ '\u0058', '\u0059', '\u005A', '\u005B', '\\', '\u005D', '\u005E', '\u005F',
+ '\u0060', '\u0061', '\u0062', '\u0063', '\u0064', '\u0065', '\u0066', '\u0067',
+ '\u0068', '\u0069', '\u006A', '\u006B', '\u006C', '\u006D', '\u006E', '\u006F',
+ '\u0070', '\u0071', '\u0072', '\u0073', '\u0074', '\u0075', '\u0076', '\u0077',
+ '\u0078', '\u0079', '\u007A', '\u007B', '\u007C', '\u007D', '\u007E', '\u007F',
+ '\u0402', '\u0403', '\u201A', '\u0453', '\u201E', '\u2026', '\u2020', '\u2021',
+ '\u20AC', '\u2030', '\u0409', '\u2039', '\u040A', '\u040C', '\u040B', '\u040F',
+ '\u0452', '\u2018', '\u2019', '\u201C', '\u201D', '\u2022', '\u2013', '\u2014',
+ '\uFFFD', '\u2122', '\u0459', '\u203A', '\u045A', '\u045C', '\u045B', '\u045F',
+ '\u00A0', '\u040E', '\u045E', '\u0408', '\u00A4', '\u0490', '\u00A6', '\u00A7',
+ '\u0401', '\u00A9', '\u0404', '\u00AB', '\u00AC', '\u00AD', '\u00AE', '\u0407',
+ '\u00B0', '\u00B1', '\u0406', '\u0456', '\u0491', '\u00B5', '\u00B6', '\u00B7',
+ '\u0451', '\u2116', '\u0454', '\u00BB', '\u0458', '\u0405', '\u0455', '\u0457',
+ '\u0410', '\u0411', '\u0412', '\u0413', '\u0414', '\u0415', '\u0416', '\u0417',
+ '\u0418', '\u0419', '\u041A', '\u041B', '\u041C', '\u041D', '\u041E', '\u041F',
+ '\u0420', '\u0421', '\u0422', '\u0423', '\u0424', '\u0425', '\u0426', '\u0427',
+ '\u0428', '\u0429', '\u042A', '\u042B', '\u042C', '\u042D', '\u042E', '\u042F',
+ '\u0430', '\u0431', '\u0432', '\u0433', '\u0434', '\u0435', '\u0436', '\u0437',
+ '\u0438', '\u0439', '\u043A', '\u043B', '\u043C', '\u043D', '\u043E', '\u043F',
+ '\u0440', '\u0441', '\u0442', '\u0443', '\u0444', '\u0445', '\u0446', '\u0447',
+ '\u0448', '\u0449', '\u044A', '\u044B', '\u044C', '\u044D', '\u044E', '\u044F'
+ };
+
+ public static GDActivity getGDActivity() {
+ return GDActivity.shared;
+ }
+
+ public static GameView getGDView() {
+ return GDActivity.shared.gameView;
+ }
+
+ public static Menu getGameMenu() {
+ return GDActivity.shared.menu;
+ }
+
+ public static Loader getLevelLoader() {
+ return GDActivity.shared.levelLoader;
+ }
+
+ public static LevelsManager getLevelsManager() {
+ return GDActivity.shared.levelsManager;
+ }
+
+ public static int getDp(int px) {
+ return Math.round(px * Global.density);
+ }
+
+ public static int getDp(float px) {
+ return Math.round(px * Global.density);
+ }
+
+ public static String getCurrentStackTrace() {
+ String del = "\n";
+ StringBuilder sb = new StringBuilder();
+ StackTraceElement[] list = Thread.currentThread().getStackTrace();
+ // for (StackTraceElement e: list) {
+ for (int i = 0; i < list.length; i++) {
+ sb.append(list[i].toString() + (i < list.length - 1 ? del : ""));
+ }
+ return sb.toString();
+ }
+
+ public static Bitmap loadBitmapFromDrawable(int id) {
+ BitmapFactory.Options options = null;
+ if (!isSDK11OrHigher()) {
+ options = new BitmapFactory.Options();
+ options.inPreferredConfig = Bitmap.Config.ARGB_8888;
+ }
+ return BitmapFactory.decodeResource(getGDActivity().getResources(), id);
+ }
+
+ public static Bitmap loadBitmapFromAsset(String name) throws IOException {
+ if (name.startsWith("/")) name = name.substring(1);
+ Bitmap bmp = null;
+ InputStream s = getGDActivity().getAssets().open(name);
+ bmp = BitmapFactory.decodeStream(s);
+ s.close();
+ return bmp;
+ }
+
+ public static void logDebug(String s) {
+ Log.d("AGDTR<" + Thread.currentThread().getName() + ">", s);
+ }
+
+ public static void logDebug(Object s) {
+ Log.d("AGDTR<" + Thread.currentThread().getName() + ">", s.toString());
+ }
+
+ public static boolean isOnline() {
+ ConnectivityManager cm = (ConnectivityManager) getGDActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo netInfo = cm.getActiveNetworkInfo();
+ return netInfo != null && netInfo.isConnectedOrConnecting();
+ }
+
+ /*public static String trimLine(String s, Paint f, int w) {
+ // logDebug("trimLine; s = " + s + ", w = " + w + "; measure = " + f.measureText(s));
+ String points = "...", result = s;
+ float avgWidth = f.measureText("o"), pointsWidth = f.measureText(points);
+ float diff;
+ int i = 0,
+ len = s.length(),
+ half = 0,
+ c = 0,
+ st1 = 0,
+ st2 = len - 1;
+
+ if (s.equals("") || f.measureText(s) <= w) return s;
+
+ w -= pointsWidth;
+
+ int tmpMax = (int)Math.round(Math.floor(w / Math.round(avgWidth / 1.5)) * 2);
+ if (len > tmpMax) {
+ s = s.substring(0, tmpMax);
+ len = s.length();
+ }
+
+ while (true) {
+ i++;
+ // if (i >= 100) return s;
+ if (half == 0) {
+ c = Math.round(len / 2);
+ } else {
+ switch (half) {
+ case 1:
+ st2 = c;
+ c -= (st2 - st1) / 2;
+ break;
+
+ case 2:
+ st1 = c;
+ c += (st2 - st1) / 2;
+ break;
+ }
+ }
+
+ String sub = s.substring(0, c > len - 1 ? len - 1 : c);
+ float subWidth = f.measureText(sub);
+
+ if (subWidth > w + avgWidth) half = 1;
+ else if (subWidth < w - avgWidth) half = 2;
+ else {
+ diff = subWidth - w;
+
+ if (diff > 0) {
+ result = s.substring(0, c - 1);
+ if (!result.equals(s)) result += points;
+ } else {
+ result = s.substring(0, c + 1);
+ if (!result.equals(s)) result += points;
+ }
+
+ return result;
+ }
+ }
+
+ // return s;
+ }*/
+
+ public static String getString(int r) {
+ return GDActivity.shared.getString(r);
+ }
+
+ public static String[] getStringArray(int r) {
+ return GDActivity.shared.getResources().getStringArray(r);
+ }
+
+ public static void runOnUiThread(Runnable runnable) {
+ GDActivity.shared.runOnUiThread(runnable);
+ }
+
+ public static long getTimestamp() {
+ return System.currentTimeMillis() / 1000L;
+ }
+
+ public static void showAlert(String title, String message, final Runnable listener) {
+ Context context = getGDActivity();
+ AlertDialog alertDialog = new AlertDialog.Builder(context)
+ .setTitle(title)
+ .setMessage(message)
+ .setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (listener != null) listener.run();
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ if (listener != null) listener.run();
+ }
+ })
+ .create();
+ alertDialog.show();
+ }
+
+ public static void showConfirm(String title, String message, final Runnable onOk, final Runnable onCancel) {
+ Context context = getGDActivity();
+ AlertDialog.Builder alert = new AlertDialog.Builder(context)
+ .setTitle(title)
+ .setMessage(message)
+ .setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (onOk != null) onOk.run();
+ }
+ })
+ .setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ if (onCancel != null) onCancel.run();
+ }
+ })
+ .setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ if (onCancel != null) onCancel.run();
+ }
+ });
+ alert.show();
+ }
+
+ public static boolean isSDK11OrHigher() {
+ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
+ }
+
+ public static boolean isSDK10OrLower() {
+ return Build.VERSION.SDK_INT <= 10;
+ }
+
+ public static String getAppVersion() {
+ String v = "0.0";
+ try {
+ PackageInfo pInfo = GDActivity.shared.getPackageManager().getPackageInfo(GDActivity.shared.getPackageName(), 0);
+ v = pInfo.versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ }
+ return v;
+ }
+
+ public static String decodeCp1251(byte[] data) {
+ if (data == null) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer(data.length);
+ for (int i = 0; i < data.length; i++) {
+ if (data[i] == 0) break;
+ sb.append(cp1251Map[data[i] & 0xFF]);
+ }
+ return sb.toString();
+ }
+
+ public static String getDeviceName() {
+ String manufacturer = Build.MANUFACTURER;
+ String model = Build.MODEL;
+ if (model.startsWith(manufacturer)) {
+ return capitalize(model);
+ } else {
+ return capitalize(manufacturer) + " " + model;
+ }
+ }
+
+ private static String capitalize(String s) {
+ if (s == null || s.length() == 0) {
+ return "";
+ }
+ char first = s.charAt(0);
+ if (Character.isUpperCase(first)) {
+ return s;
+ } else {
+ return Character.toUpperCase(first) + s.substring(1);
+ }
+ }
+
+}
diff --git a/src/org/happysanta/gd/KeyboardController.java b/src/org/happysanta/gd/KeyboardController.java
new file mode 100644
index 0000000..4438677
--- /dev/null
+++ b/src/org/happysanta/gd/KeyboardController.java
@@ -0,0 +1,303 @@
+package org.happysanta.gd;
+
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.LinearLayout;
+import org.happysanta.gd.Game.GameView;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+import static org.happysanta.gd.Helpers.getDp;
+
+public class KeyboardController implements View.OnTouchListener {
+
+ private static final int MAX_POINTERS = 10;
+ public static final int PADDING = 15;
+ private static final boolean DISABLE_MOVE = false;
+
+ private static int PADDING_DP = 0;
+
+ private GDActivity gd;
+ private int[] buf;
+ private LinearLayout[] btns;
+ private PointerInfo[] pointers;
+ private StringBuffer logBuffer;
+
+ static {
+ PADDING_DP = getDp(PADDING);
+ }
+
+ KeyboardController(GDActivity gd) {
+ this.gd = gd;
+ buf = new int[2];
+ btns = new LinearLayout[9];
+ pointers = new PointerInfo[MAX_POINTERS];
+ for (int i = 0; i < MAX_POINTERS; i++) {
+ pointers[i] = new PointerInfo(i);
+ }
+
+ logBuffer = new StringBuffer();
+ }
+
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ GameView gameView = gd.gameView;
+
+ v.getLocationOnScreen(buf);
+ Rect rect = new Rect(buf[0], buf[1], buf[0] + v.getWidth(), buf[1] + v.getHeight());
+
+ rect.left += PADDING_DP;
+ rect.right -= PADDING_DP;
+ rect.top += PADDING_DP;
+ rect.bottom -= PADDING_DP;
+
+ /*int actionRaw = MotionEventCompat.getAction/event.getAction();
+ if (actionRaw != MotionEvent.ACTION_MOVE) {
+ log("EVT_RAW " + actionRaw + " " + actionToString(actionRaw));
+ }*/
+
+ // int action = actionRaw & MotionEvent.ACTION_MASK;
+ int action = event.getActionMasked();
+ if (action == MotionEvent.ACTION_DOWN
+ || action == MotionEvent.ACTION_POINTER_DOWN
+ || action == MotionEvent.ACTION_UP
+ || action == MotionEvent.ACTION_POINTER_UP
+// || action == MotionEvent.ACTION_CANCEL
+ /*|| action == MotionEvent.ACTION_POINTER_2_DOWN
+ || action == MotionEvent.ACTION_POINTER_3_DOWN
+ || action == MotionEvent.ACTION_POINTER_2_UP
+ || action == MotionEvent.ACTION_POINTER_3_UP*/) {
+ /*int index = event.getActionIndex();
+ int pointerId = event.getPointerId(index);*/
+
+ int index = event.getActionIndex();
+ int pointerId = event.getPointerId(index);
+// int pointerId = event.getPointerId(index);
+
+ if (pointerId >= MAX_POINTERS) {
+ return true;
+ }
+
+ int x = Math.round(event.getX(index));
+ int y = Math.round(event.getY(index));
+
+ //if (Global.DEBUG || true) {
+// log("EVT [ind=" + index + ", pntId=" + pointerId + "] " + actionToString(action) + " "
+// + "(x=" + x + ", y=" + y + "), "
+// + "(rx=" + event.getRawX() + ", ry=" + event.getRawY() + ")"
+// );
+// log("EVT DUMP " + event.toString());
+// log("RECT l="+rect.left+", r="+rect.right+", t="+rect.top+", b="+rect.bottom);
+ // }
+
+ LinearLayout btn;
+ PointerInfo pointer = pointers[pointerId];
+
+ int btnIndex = whichButton(rect, x, y);
+
+// log("BTN index="+btnIndex, true);
+
+ // logBuffer("x="+x+", y="+y+", btn="+btnIndex);
+
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ case MotionEvent.ACTION_POINTER_DOWN:
+ press(v);
+
+ pointer.setButtonIndex(btnIndex);
+ btn = pointer.getButton();
+
+ btn.setPressed(true);
+ gameView.keyPressed(gameKeyCode(btnIndex));
+ break;
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_POINTER_UP:
+ // case MotionEvent.ACTION_CANCEL:
+ btn = pointer.getButton();
+ if (btn != null) {
+ btn.setPressed(false);
+ if (DISABLE_MOVE) {
+ btnIndex = pointer.btnIndex;
+ }
+ gameView.keyReleased(gameKeyCode(btnIndex));
+ pointer.finish();
+ }
+ break;
+ }
+ } else if (action == MotionEvent.ACTION_MOVE && !gd.isMenuShown() && !DISABLE_MOVE) {
+ int pointerCount = event.getPointerCount();
+// int pointerCount = event.getPointerCount();
+ LinearLayout btn, oldBtn;
+ PointerInfo pointer;
+
+ for (int pointerIndex = 0; pointerIndex < pointerCount; pointerIndex++) {
+ int pointerId = event.getPointerId(pointerIndex);
+ if (pointerId >= MAX_POINTERS) continue;
+
+ int x = Math.round(event.getX(pointerIndex));
+ int y = Math.round(event.getY(pointerIndex));
+
+// int x = Math.round(event.getX(pointerIndex));
+// int y = Math.round(event.getY(pointerIndex));
+ int btnIndex = whichButton(rect, x, y);
+
+ pointer = pointers[pointerId];
+ if (btnIndex != pointer.btnIndex) {
+ oldBtn = btns[pointer.btnIndex];
+ oldBtn.setPressed(false);
+ gameView.keyReleased(gameKeyCode(pointer.btnIndex));
+
+ press(v);
+
+ pointer.setButtonIndex(btnIndex);
+ btn = pointer.getButton();
+ btn.setPressed(true);
+ gameView.keyPressed(gameKeyCode(pointer.btnIndex));
+ }
+ }
+ }
+
+ return true;
+ }
+
+ private synchronized void log(Object o, boolean last) {
+ String logStr = o.toString();
+ Log.d("GD Keyboard", o.toString());
+
+ if (last)
+ Log.d("", "");
+
+ /*if (!gd.isMenuShown()) {
+ logBuffer.append("<");
+ logBuffer.append(getCurrentTime());
+ logBuffer.append("> ");
+
+ logBuffer.append(logStr);
+ logBuffer.append("\n");
+
+ if (last)
+ logBuffer.append("\n");
+ }*/
+ }
+
+ private void log(Object o) {
+ log(o, false);
+ }
+
+ public synchronized void clearLogBuffer() {
+ logBuffer = null;
+ logBuffer = new StringBuffer();
+ }
+
+ public String getLog() {
+ return logBuffer.toString();
+ }
+
+ private static String getCurrentTime() {
+ Calendar cal = Calendar.getInstance();
+ cal.getTime();
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
+ return sdf.format(cal.getTime());
+ }
+
+ private static String actionToString(int action) {
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ return "ACTION_DOWN";
+ case MotionEvent.ACTION_POINTER_DOWN:
+ return "ACTION_POINTER_DOWN";
+ case MotionEvent.ACTION_POINTER_2_DOWN:
+ return "ACTION_POINTER_2_DOWN";
+ case MotionEvent.ACTION_POINTER_2_UP:
+ return "ACTION_POINTER_2_UP";
+ case MotionEvent.ACTION_POINTER_3_DOWN:
+ return "ACTION_POINTER_3_DOWN";
+ case MotionEvent.ACTION_POINTER_3_UP:
+ return "ACTION_POINTER_3_UP";
+ case MotionEvent.ACTION_UP:
+ return "ACTION_UP";
+ case MotionEvent.ACTION_POINTER_UP:
+ return "ACTION_POINTER_UP";
+ case MotionEvent.ACTION_MOVE:
+ return "ACTION_MOVE";
+ }
+ return "?";
+ }
+
+ private static int whichButton(Rect rect, int x, int y) {
+ int cellW = rect.width() / 3,
+ cellH = rect.height() / 3;
+
+ // logBuffer("cellW="+cellW+", cellH="+cellH);
+
+ int posX = 0, posY = 0;
+
+ if (x < PADDING_DP + cellW)
+ posX = 0;
+ else if (x < PADDING_DP + cellW * 2)
+ posX = 1;
+ else
+ posX = 2;
+
+ if (y < PADDING_DP + cellH)
+ posY = 0;
+ else if (y < PADDING_DP + cellH * 2)
+ posY = 1;
+ else
+ posY = 2;
+
+ return posY * 3 + posX;
+ }
+
+ private static int gameKeyCode(int btnIndex) {
+ return btnIndex + 49;
+ }
+
+ private static void press(View v) {
+ if (Settings.isVibrateOnTouchEnabled()) {
+ v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
+ }
+ }
+
+ public void addButton(LinearLayout btn, int x, int y) {
+ btns[y * 3 + x] = btn;
+ }
+
+ private class PointerInfo {
+
+ private int id;
+ private int btnIndex = -1;
+ private boolean active = false;
+
+ PointerInfo(int id) {
+ this.id = id;
+ }
+
+ void finish() {
+ active = false;
+ btnIndex = -1;
+ }
+
+ /*void setActive() {
+ active = true;
+ }*/
+
+ void setButtonIndex(int index) {
+ active = true;
+ btnIndex = index;
+ }
+
+ LinearLayout getButton() {
+ if (!active)
+ return null;
+ return btns[btnIndex];
+ }
+
+ }
+
+}
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;
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/ActionMenuElement.java b/src/org/happysanta/gd/Menu/ActionMenuElement.java
new file mode 100755
index 0000000..fb0b706
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/ActionMenuElement.java
@@ -0,0 +1,141 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import org.happysanta.gd.Menu.Views.MenuImageView;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+import org.happysanta.gd.R;
+
+import static org.happysanta.gd.Helpers.getDp;
+import static org.happysanta.gd.Helpers.getGDActivity;
+
+public class ActionMenuElement
+ extends ClickableMenuElement
+ implements MenuHandler, MenuElement {
+
+ protected static final int DISABLED_COLOR = 0xff999999;
+ public static final int LOCK_IMAGE_MARGIN_RIGHT = 5;
+ public static final int locks[] = new int[]{
+ R.drawable.s_lock0,
+ R.drawable.s_lock1,
+ R.drawable.s_lock2
+ };
+
+ public static final int LINE_SPACING = 15;
+ public static final int X_OFFSET = 48;
+
+ public static final int OK = 0;
+ public static final int BACK = 1;
+ public static final int EXIT = 2;
+ public static final int YES = 3;
+ public static final int NO = 4;
+ public static final int PLAY_MENU = 5;
+ public static final int GO_TO_MAIN = 6;
+ public static final int RESTART = 7;
+ public static final int NEXT = 8;
+ public static final int CONTINUE = 9;
+ public static final int INSTALL = 10;
+ public static final int LOAD = 11;
+ public static final int SELECT_FILE = 12;
+ public static final int DELETE = 13;
+ public static final int RESTART_WITH_NEW_LEVEL = 14;
+ public static final int SEND_LOGS = 15;
+
+ protected MenuHandler handler;
+ protected boolean isLocked = false;
+ protected boolean isBlackLock = true;
+ protected MenuImageView lockImage = null;
+
+ protected int actionValue = -1;
+
+ public ActionMenuElement(String s, int value, MenuHandler handler) {
+ actionValue = value;
+ this.handler = handler;
+
+ text = s;
+
+ createAllViews();
+ }
+
+ @Override
+ protected void createAllViews() {
+ super.createAllViews();
+
+ Context context = getGDActivity();
+ lockImage = new MenuImageView(context);
+ lockImage.setScaleType(ImageView.ScaleType.CENTER);
+ lockImage.setVisibility(View.GONE);
+
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
+ lp.setMargins(0, 0, getDp(ActionMenuElement.LOCK_IMAGE_MARGIN_RIGHT), 0);
+ lockImage.setLayoutParams(lp);
+
+ layout.addView(lockImage, 1);
+ }
+
+ public ActionMenuElement(String s, MenuHandler handler/*, MenuScreen screen*/) {
+ this(s, -1, handler);
+ }
+
+ public int getActionValue() {
+ return actionValue;
+ }
+
+ public void setHandler(MenuHandler hander) {
+ this.handler = hander;
+ }
+
+ public void setLock(boolean flag, boolean flag1) {
+ isLocked = flag;
+ isBlackLock = flag1;
+
+ lockImage.setVisibility(isLocked ? View.VISIBLE : View.GONE);
+ lockImage.setImageResource(locks[isBlackLock ? 0 : 1]);
+ }
+
+ @Override
+ public void setText(String s) {
+ text = s;
+ updateViewText();
+ }
+
+ @Override
+ public void performAction(int k) {
+ if (disabled || handler == null) return;
+
+ if (k == MenuScreen.KEY_FIRE) {
+ handler.handleAction(this);
+ }
+ }
+
+ @Override
+ protected void onHighlightChanged() {
+ lockImage.setImageResource(locks[isHighlighted ? 2 : (isBlackLock ? 0 : 1)]);
+ }
+
+ @Override
+ public MenuScreen getCurrentMenu() {
+ return null;
+ }
+
+ @Override
+ public void setCurrentMenu(MenuScreen e1, boolean flag) {
+ }
+
+ @Override
+ public void handleAction(MenuElement item) {
+ }
+
+ public void setDisabled(boolean disabled) {
+ this.disabled = disabled;
+
+ if (disabled) {
+ ((MenuTextView) textView).setTextColor(DISABLED_COLOR);
+ } else {
+ ((MenuTextView) textView).setTextColor(defaultColorStateList());
+ }
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/BigTextMenuElement.java b/src/org/happysanta/gd/Menu/BigTextMenuElement.java
new file mode 100644
index 0000000..8b30e64
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/BigTextMenuElement.java
@@ -0,0 +1,30 @@
+package org.happysanta.gd.Menu;
+
+import android.text.Spanned;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+
+public class BigTextMenuElement
+ extends TextMenuElement {
+
+ public static final int TEXT_SIZE = 19;
+
+ public BigTextMenuElement(String s) {
+ super(s);
+ createTextView();
+ setTextParams(textView);
+ }
+
+ public BigTextMenuElement(Spanned s) {
+ super(s);
+ createTextView();
+ setTextParams(textView);
+ }
+
+ protected static void setTextParams(MenuTextView textView) {
+ textView.setTextSize(TEXT_SIZE);
+ textView.setTypeface(Global.robotoCondensedTypeface);
+ textView.setLineSpacing(0f, 1.2f);
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/ClickableMenuElement.java b/src/org/happysanta/gd/Menu/ClickableMenuElement.java
new file mode 100644
index 0000000..f33db34
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/ClickableMenuElement.java
@@ -0,0 +1,196 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.Rect;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Menu.Views.MenuHelmetView;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+import org.happysanta.gd.R;
+
+import static org.happysanta.gd.Helpers.getDp;
+import static org.happysanta.gd.Helpers.getGDActivity;
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class ClickableMenuElement
+ implements MenuElement {
+
+ public static final int TEXT_SIZE = 20;
+ public static final int PADDING_TOP = 5;
+ protected View textView;
+ protected String text;
+ protected View.OnTouchListener onTouchListener;
+ protected LinearLayout layout;
+ protected MenuHelmetView helmet;
+ protected OnMenuElementHighlightListener onMenuElementHighlightListener = null;
+ protected boolean isHighlighted = false;
+ protected Thread originalThread = null;
+ protected boolean disabled = false;
+
+ public ClickableMenuElement() {
+ }
+
+ public ClickableMenuElement(String text) {
+ this.text = text;
+ originalThread = Thread.currentThread();
+
+ createAllViews();
+ }
+
+ protected boolean inViewBounds(View view, int x, int y) {
+ Rect rect = new Rect();
+ int location[] = new int[2];
+
+ view.getDrawingRect(rect);
+ view.getLocationOnScreen(location);
+ rect.offset(location[0], location[1]);
+
+ return rect.contains(x, y);
+ }
+
+ protected void createAllViews() {
+ final ClickableMenuElement self = this;
+ Context context = getGDActivity();
+
+ layout = new LinearLayout(context);
+ layout.setOrientation(LinearLayout.HORIZONTAL);
+ layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+
+ helmet = new MenuHelmetView(context);
+ helmet.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
+
+ /*if (!isSDK11OrHigher()) {
+ helmet.setMeasuredHeight(true);
+ }*/
+
+ onTouchListener = new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View view, MotionEvent motionEvent) {
+ if (disabled) return false;
+
+ switch (motionEvent.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ view.setSelected(true);
+ helmet.setShow(true);
+
+ if (onMenuElementHighlightListener != null)
+ onMenuElementHighlightListener.onElementHighlight(self);
+
+ setHighlighted(true);
+ break;
+
+ case MotionEvent.ACTION_CANCEL:
+ case MotionEvent.ACTION_UP:
+ view.setSelected(false);
+
+ if (motionEvent.getAction() == MotionEvent.ACTION_UP && inViewBounds(view, (int) motionEvent.getRawX(), (int) motionEvent.getRawY())) {
+ performAction(MenuScreen.KEY_FIRE);
+ }
+
+ setHighlighted(false);
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ if (!inViewBounds(view, (int) motionEvent.getRawX(), (int) motionEvent.getRawY())) {
+ view.setSelected(false);
+ setHighlighted(false);
+ } else {
+ view.setSelected(true);
+ setHighlighted(true);
+ }
+ break;
+ }
+ return true;
+ }
+ };
+
+ textView = createMainView();
+
+ layout.addView(helmet);
+ layout.addView(textView);
+ layout.setOnTouchListener(onTouchListener);
+ }
+
+ protected View createMainView() {
+ Context context = getGDActivity();
+ MenuTextView mtv = new MenuTextView(context);
+ mtv.setText(getTextForView());
+ mtv.setTextColor(defaultColorStateList());
+ mtv.setTypeface(Global.robotoCondensedTypeface);
+ mtv.setTextSize(TEXT_SIZE);
+ mtv.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ));
+ mtv.setPadding(0, getDp(PADDING_TOP), 0, getDp(PADDING_TOP));
+
+ return mtv;
+ }
+
+ protected ColorStateList defaultColorStateList() {
+ return getGDActivity().getResources().getColorStateList(R.drawable.menu_item_color);
+ }
+
+ @Override
+ public boolean isSelectable() {
+ return true;
+ }
+
+ @Override
+ public View getView() {
+ return layout;
+ }
+
+ protected MenuTextView getMenuTextView() {
+ return (MenuTextView) textView;
+ }
+
+ @Override
+ public void setText(String text) {
+ this.text = text;
+ updateViewText();
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ protected void updateViewText() {
+ if (textView != null && textView instanceof MenuTextView)
+ ((MenuTextView) textView).setTextOnUiThread(getTextForView());
+ }
+
+ protected String getTextForView() {
+ return text;
+ }
+
+ @Override
+ public void performAction(int k) {
+
+ }
+
+ public void setOnHighlightListener(OnMenuElementHighlightListener listener) {
+ onMenuElementHighlightListener = listener;
+ }
+
+ public void showHelmet() {
+ helmet.setShow(true);
+ }
+
+ private void setHighlighted(boolean highlighted) {
+ isHighlighted = highlighted;
+ onHighlightChanged();
+ }
+
+ protected void onHighlightChanged() {
+ }
+
+ public boolean isDisabled() {
+ return disabled;
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java b/src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java
new file mode 100755
index 0000000..fe072ce
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java
@@ -0,0 +1,222 @@
+package org.happysanta.gd.Menu;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.view.View;
+import android.widget.RelativeLayout;
+import android.widget.Toast;
+import org.happysanta.gd.API.*;
+import org.happysanta.gd.GDActivity;
+import org.happysanta.gd.Menu.Views.MenuImageView;
+import org.happysanta.gd.R;
+import org.happysanta.gd.API.Response;
+import org.happysanta.gd.Settings;
+import org.happysanta.gd.WaitForNetworkConnection;
+
+import static org.happysanta.gd.Helpers.*;
+import static org.happysanta.gd.Helpers.getDp;
+
+public class DownloadLevelsMenuScreen extends LevelsMenuScreen {
+
+ protected final static int API_LIMIT = 100;
+ public static API.LevelsSortType sort;
+
+ protected MenuImageView sortImage;
+ // protected API api;
+ protected Request request;
+ protected int offset = 0;
+ protected boolean isLoading = false;
+ protected boolean fullLoaded = false;
+ protected WaitForNetworkConnection waitForNetworkConnection = null;
+ protected Toast toast;
+
+ public DownloadLevelsMenuScreen(String title, MenuScreen navTarget) {
+ super(title, navTarget);
+
+ // api = new API();
+ // api.setSort(sort);
+
+ Context context = getGDActivity();
+
+ // Sort icon
+ sortImage = new MenuImageView(context);
+ sortImage.setImageResource(R.drawable.ic_sort);
+ sortImage.setAdjustViewBounds(true);
+ sortImage.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showSortDialog();
+ }
+ });
+ sortImage.setVisibility(View.GONE);
+ sortImage.setPadding(getDp(10), 0, 0, 0);
+
+ RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
+ RelativeLayout.LayoutParams.WRAP_CONTENT,
+ getDp(40)
+ );
+ params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+
+ sortImage.setLayoutParams(params);
+ }
+
+ @Override
+ protected void loadLevels() {
+ try {
+ if (!checkNetwork())
+ return;
+
+ showLoading();
+ isLoading = true;
+ request = API.getLevels(offset, API_LIMIT, sort, new ResponseHandler() {
+ @Override
+ public void onResponse(final Response response) {
+ final LevelsResponse levelsResponse = new LevelsResponse(response);
+ if (status != Statuses.NORMAL) {
+ clearList();
+ setStatus(Statuses.NORMAL);
+ }
+
+ hideLoading();
+
+ addElements = new AsyncAddElements() {
+ @Override
+ protected void onPostExecute(Void v) {
+ logDebug("offset = " + offset + ", totalCount = " + levelsResponse.getTotalCount());
+ fullLoaded = offset >= levelsResponse.getTotalCount();
+ if (!fullLoaded)
+ showLoading();
+
+ isLoading = false;
+ }
+ };
+ addElements.execute(levelsResponse.getLevels());
+ }
+
+ @Override
+ public void onError(APIException error) {
+ showError(error.getMessage());
+ isLoading = false;
+ }
+ });
+
+ offset += API_LIMIT;
+ } catch (Exception e) {
+ e.printStackTrace();
+ showError(getString(R.string.download_error));
+
+ isLoading = false;
+ }
+ }
+
+ @Override
+ public void reloadLevels() {
+ if (request != null) request.cancel();
+ offset = 0;
+ isLoading = false;
+ fullLoaded = false;
+
+ super.reloadLevels();
+ }
+
+ protected void showSortDialog() {
+ final CharSequence[] items = getStringArray(R.array.sort_variants);
+
+ AlertDialog dialog = new AlertDialog.Builder(getGDActivity())
+ .setTitle(getString(R.string.sort_by))
+ .setSingleChoiceItems(items, API.getIdBySortType(sort), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int item) {
+ API.LevelsSortType newSort = API.getSortTypeById(item);
+
+ if (newSort != sort) {
+ sort = newSort;
+ // api.setSort(newSort);
+ Settings.setLevelsSort(sort);
+ reloadLevels();
+ }
+
+ dialog.dismiss();
+ }
+ })
+ .create();
+
+ dialog.show();
+ }
+
+ protected boolean checkNetwork() {
+ if (!isOnline()) {
+ if (elements.isEmpty()) {
+ showError(getString(R.string.waiting_for_network));
+
+ if (waitForNetworkConnection != null)
+ waitForNetworkConnection.cancel(true);
+
+ waitForNetworkConnection = new WaitForNetworkConnection();
+ waitForNetworkConnection.execute(null, new Runnable() {
+ @Override
+ public void run() {
+ reloadLevels();
+ }
+ });
+ } else {
+ if (toast != null) {
+ toast.cancel();
+ }
+
+ toast = Toast.makeText(getGDActivity().getApplicationContext(), getString(R.string.no_internet_connection), Toast.LENGTH_SHORT);
+ toast.show();
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public void onHide(MenuScreen newMenu) {
+ logDebug("onHide");
+ super.onHide(newMenu);
+
+ GDActivity activity = getGDActivity();
+
+ if (newMenu != getGameMenu().levelScreen) {
+ offset = 0;
+ isLoading = false;
+ fullLoaded = false;
+
+ if (request != null) request.cancel();
+ // api.cancelRequest();
+ if (waitForNetworkConnection != null)
+ waitForNetworkConnection.cancel(true);
+ }
+
+ activity.titleLayout.removeView(sortImage);
+ sortImage.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onShow() {
+ super.onShow();
+
+ GDActivity activity = getGDActivity();
+
+ activity.titleLayout.addView(sortImage);
+ sortImage.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onScroll(double percent) {
+ if (percent >= 97 && !isLoading && !fullLoaded) {
+ loadLevels();
+ }
+ }
+
+ @Override
+ public void deleteElement(LevelMenuElement el) {
+ super.deleteElement(el);
+ offset--;
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/EmptyLineMenuElement.java b/src/org/happysanta/gd/Menu/EmptyLineMenuElement.java
new file mode 100755
index 0000000..e0901f9
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/EmptyLineMenuElement.java
@@ -0,0 +1,42 @@
+package org.happysanta.gd.Menu;
+
+import android.view.View;
+import android.view.ViewGroup;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+
+import static org.happysanta.gd.Helpers.getDp;
+import static org.happysanta.gd.Helpers.getGDActivity;
+
+public class EmptyLineMenuElement implements MenuElement {
+
+ protected String text;
+ protected int offset;
+ protected MenuTextView view;
+
+ EmptyLineMenuElement(int offset) {
+ this.offset = offset;
+
+ view = new MenuTextView(getGDActivity());
+ view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getDp(offset)));
+ }
+
+ @Override
+ public View getView() {
+ return view;
+ }
+
+ @Override
+ public boolean isSelectable() {
+ return false;
+ }
+
+ @Override
+ public void setText(String s) {
+ text = s;
+ }
+
+ @Override
+ public void performAction(int k) {
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java b/src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java
new file mode 100755
index 0000000..fc392df
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java
@@ -0,0 +1,100 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.text.Spanned;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Menu.Views.MenuImageView;
+import org.happysanta.gd.Menu.Views.MenuLinearLayout;
+import org.happysanta.gd.R;
+
+import static org.happysanta.gd.Helpers.*;
+
+public class HighScoreTextMenuElement
+ extends TextMenuElement
+ implements MenuElement {
+
+ protected static final int TEXT_LEFT_MARGIN = 5;
+ protected static final int SUBTITLE_MARGIN_BOTTOM = 8;
+ protected static final int SUBTITLE_TEXT_SIZE = 20;
+ protected static final int LAYOUT_PADDING = 3;
+ protected static int medals[] = new int[]{
+ R.drawable.s_medal_gold,
+ R.drawable.s_medal_silver,
+ R.drawable.s_medal_bronze
+ };
+ protected static Typeface defaultTypeface = null;
+
+ protected boolean showMedal = false;
+ protected MenuLinearLayout layout;
+ protected MenuImageView image;
+
+ public HighScoreTextMenuElement(String s) {
+ super(s);
+ createAllViews();
+ }
+
+ public HighScoreTextMenuElement(Spanned text) {
+ super(text);
+ createAllViews();
+ }
+
+ protected void createAllViews() {
+ Context context = getGDActivity();
+
+ layout = new MenuLinearLayout(context);
+ layout.setOrientation(LinearLayout.HORIZONTAL);
+ layout.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+
+ image = new MenuImageView(context);
+ image.setScaleType(ImageView.ScaleType.CENTER);
+ image.setVisibility(View.GONE);
+
+ // textView was already created in super constructor
+ textView.setLineSpacing(0, 1);
+
+ if (defaultTypeface == null) {
+ defaultTypeface = textView.getTypeface();
+ }
+
+ LinearLayout.LayoutParams textViewLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ // textViewLayoutParams.setMargins(getDp(TEXT_LEFT_MARGIN), 0, 0, 0);
+ textView.setLayoutParams(textViewLayoutParams);
+
+ layout.addView(image, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
+ layout.addView(textView);
+ }
+
+ @Override
+ public View getView() {
+ return layout;
+ }
+
+ public void setMedal(boolean showMedal, int medalIndex) {
+ image.setVisibility(showMedal ? View.VISIBLE : View.GONE);
+ image.setImageResource(medals[medalIndex]);
+
+ LinearLayout.LayoutParams textViewLayoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
+ textViewLayoutParams.setMargins(showMedal ? getDp(TEXT_LEFT_MARGIN) : 0, 0, 0, 0);
+ textView.setLayoutParams(textViewLayoutParams);
+
+ this.showMedal = showMedal;
+ }
+
+ public void setIsSubtitle(boolean is) {
+ textView.setTextSize(is ? SUBTITLE_TEXT_SIZE : TEXT_SIZE);
+ textView.setTypeface(is ? Global.robotoCondensedTypeface : defaultTypeface);
+
+ LinearLayout.LayoutParams textViewLayoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
+ textViewLayoutParams.setMargins(!is && showMedal ? getDp(TEXT_LEFT_MARGIN) : 0, 0, 0, is ? getDp(SUBTITLE_MARGIN_BOTTOM) : 0);
+ textView.setLayoutParams(textViewLayoutParams);
+ }
+
+ public void setLayoutPadding(boolean use) {
+ layout.setPadding(0, use ? getDp(LAYOUT_PADDING) : 0, 0, use ? getDp(LAYOUT_PADDING) : 0);
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java b/src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java
new file mode 100644
index 0000000..b3adbab
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java
@@ -0,0 +1,103 @@
+package org.happysanta.gd.Menu;
+
+import android.os.AsyncTask;
+import android.view.ViewTreeObserver;
+import org.happysanta.gd.Storage.Level;
+import org.happysanta.gd.Storage.LevelsManager;
+
+import static org.happysanta.gd.Helpers.getGDActivity;
+
+public class InstalledLevelsMenuScreen extends LevelsMenuScreen {
+
+ LevelsManager levelsManager;
+ protected boolean isLoading = false;
+ AsyncLoadLevels asyncLoadLevels = null;
+
+ public InstalledLevelsMenuScreen(String title, MenuScreen navTarget) {
+ super(title, navTarget);
+ levelsManager = getGDActivity().levelsManager;
+ }
+
+ @Override
+ public void loadLevels() {
+ showLoading();
+ isLoading = true;
+
+ asyncLoadLevels = new AsyncLoadLevels() {
+ @Override
+ public void onPostExecute(Level[] levels) {
+ if (status != Statuses.NORMAL) {
+ clearList();
+ setStatus(Statuses.NORMAL);
+ }
+ hideLoading();
+
+ addElements = new AsyncAddElements() {
+ @Override
+ protected void onPostExecute(Void v) {
+ isLoading = false;
+ if (selectedIndex != -1) {
+ // listLayout.requestLayout();
+ // listLayout.invalidate();
+
+ // View someView = findViewById(R.id.someView);
+ final ViewTreeObserver obs = listLayout.getViewTreeObserver();
+ obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+
+ public boolean onPreDraw() {
+ scrollToItem(selectedIndex);
+ try {
+ obs.removeOnPreDrawListener(this);
+ } catch (IllegalStateException e) {
+ }
+
+ return true;
+ }
+ });
+
+ // scrollToItem(selectedIndex);
+ }
+ }
+ };
+ addElements.execute(levels);
+ }
+ };
+ asyncLoadLevels.execute();
+ }
+
+ @Override
+ public void onShow() {
+ super.onShow();
+ }
+
+ @Override
+ public void onHide(MenuScreen newMenu) {
+ super.onHide(newMenu);
+ }
+
+ @Override
+ protected boolean hideDate() {
+ return true;
+ }
+
+ @Override
+ public void reloadLevels() {
+ if (asyncLoadLevels != null) {
+ asyncLoadLevels.cancel(true);
+ asyncLoadLevels = null;
+ }
+
+ isLoading = false;
+ super.reloadLevels();
+ }
+
+ private class AsyncLoadLevels extends AsyncTask<Void, Void, Level[]> {
+
+ @Override
+ protected Level[] doInBackground(Void... params) {
+ return levelsManager.getAllInstalledLevels();
+ }
+
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/LevelMenuElement.java b/src/org/happysanta/gd/Menu/LevelMenuElement.java
new file mode 100755
index 0000000..e577e94
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/LevelMenuElement.java
@@ -0,0 +1,370 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.text.Html;
+import android.text.SpannableString;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import org.happysanta.gd.Callback;
+import org.happysanta.gd.GDActivity;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Menu.Views.LevelNameLeadingMarginSpan2;
+import org.happysanta.gd.Menu.Views.MenuImageView;
+import org.happysanta.gd.Menu.Views.MenuLinearLayout;
+import org.happysanta.gd.Menu.Views.MenuRelativeLayout;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+import org.happysanta.gd.R;
+import org.happysanta.gd.Storage.Level;
+import org.happysanta.gd.Storage.LevelsManager;
+
+import static org.happysanta.gd.Helpers.getDp;
+import static org.happysanta.gd.Helpers.getGDActivity;
+import static org.happysanta.gd.Helpers.getGameMenu;
+import static org.happysanta.gd.Helpers.getLevelsManager;
+import static org.happysanta.gd.Helpers.getString;
+import static org.happysanta.gd.Helpers.logDebug;
+import static org.happysanta.gd.Helpers.showConfirm;
+
+public class LevelMenuElement
+ extends ClickableMenuElement
+ implements MenuHandler {
+
+ protected static final int PADDING_TOP = 7;
+ protected static final int PADDING_BOTTOM = 7;
+ protected static final int LEVEL_TEXT_SIZE = 16;
+ protected static final int NAME_SIZE = 20;
+
+ protected static final int INSTALLED_MARGIN = 15;
+ protected static final int ACTIVE_MARGIN = 21;
+
+ protected Level level;
+
+ protected MenuTextView textView;
+ protected MenuLinearLayout mainLayout;
+ protected MenuRelativeLayout nameLayout;
+ protected MenuTextView tracksCountTextView;
+ protected MenuScreen screen;
+ protected MenuImageView installedIcon = null;
+ protected MenuImageView activeIcon = null;
+ protected boolean installed = false;
+ protected boolean active = false;
+ protected boolean showDate = true;
+
+ public LevelMenuElement() {
+ }
+
+ public LevelMenuElement(Level level, MenuScreen screen) {
+ this.level = level;
+ this.screen = screen;
+
+ createAllViews();
+ }
+
+ @Override
+ protected View createMainView() {
+ Context context = getGDActivity();
+
+ mainLayout = new MenuLinearLayout(context);
+ mainLayout.setOrientation(LinearLayout.VERTICAL);
+ mainLayout.setPadding(0, getDp(PADDING_TOP), 0, getDp(PADDING_BOTTOM));
+
+ nameLayout = new MenuRelativeLayout(context);
+ // nameLayout.setOrientation(LinearLayout.HORIZONTAL);
+
+ // Text
+ textView = new MenuTextView(context);
+ // textView.setText(level.getName());
+ updateNameLine();
+ textView.setTextColor(context.getResources().getColorStateList(R.drawable.menu_item_color));
+ textView.setTypeface(Global.robotoCondensedTypeface);
+ textView.setTextSize(NAME_SIZE);
+ textView.setLineSpacing(0f, 1.1f);
+ textView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ));
+ textView.setPadding(0, getDp(PADDING_TOP), 0, 0);
+
+ tracksCountTextView = new MenuTextView(context);
+ tracksCountTextView.setTextSize(LEVEL_TEXT_SIZE);
+ tracksCountTextView.setTypeface(Global.robotoCondensedTypeface);
+ updateLevelsLine();
+
+ nameLayout.addView(textView);
+ mainLayout.addView(nameLayout);
+ mainLayout.addView(tracksCountTextView);
+
+ return mainLayout;
+ }
+
+ public void updateNameLine() {
+ String name = level.getName() + (Global.DEBUG ? " (id" + level.getAnyId() + ")" : "");
+ // if (!active) {
+ int margin = 0;
+ if (installed)
+ margin = INSTALLED_MARGIN;
+ else if (active)
+ margin = ACTIVE_MARGIN;
+
+ SpannableString ss = new SpannableString(name);
+ ss.setSpan(new LevelNameLeadingMarginSpan2(1, installed || active ? getDp(margin) : 0), 0, ss.length(), 0);
+ textView.setTextOnUiThread(ss);
+ /*} else {
+ textView.setTextOnUiThread(Html.fromHtml(String.format(getString(R.string.active_name_tpl), name)));
+ }*/
+ }
+
+ public void updateLevelsLine() {
+ if (showDate) {
+ tracksCountTextView.setText(Html.fromHtml(String.format(getString(R.string.levels_count_tpl),
+ level.getCountEasy() + " - " + level.getCountMedium() + " - " + level.getCountHard(), level.getShortAddedDate())));
+ } else {
+ tracksCountTextView.setText(level.getCountEasy() + " - " + level.getCountMedium() + " - " + level.getCountHard());
+ }
+ }
+
+ @Override
+ protected void onHighlightChanged() {
+ if (installed && installedIcon != null) {
+ installedIcon.setImageResource(isHighlighted ? R.drawable.ic_downloaded_selected : R.drawable.ic_downloaded);
+ }
+ if (active && activeIcon != null) {
+ activeIcon.setImageResource(isHighlighted ? R.drawable.ic_installed_selected : R.drawable.ic_installed);
+ }
+ }
+
+ @Override
+ protected void createAllViews() {
+ super.createAllViews();
+
+ helmet.setMeasuredHeight(true);
+
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ );
+ lp.setMargins(0, getDp(PADDING_TOP * 2 + 5), 0, 0);
+
+ helmet.setLayoutParams(lp);
+ }
+
+ public void setInstalled(boolean installed) {
+ this.installed = installed;
+ if (installed) {
+ if (installedIcon == null) {
+ RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
+ RelativeLayout.LayoutParams.WRAP_CONTENT,
+ RelativeLayout.LayoutParams.WRAP_CONTENT
+ );
+ // params.setMargins(0, getDp(PADDING_TOP * 2 + 2), getDp(7), 0);
+ params.setMargins(0, getDp(PADDING_TOP * 2 + 2), 0, 0);
+
+ installedIcon = new MenuImageView(getGDActivity());
+ installedIcon.setLayoutParams(params);
+ installedIcon.setImageResource(R.drawable.ic_downloaded);
+ }
+
+ if (installedIcon.getParent() != nameLayout) {
+ nameLayout.addView(installedIcon);
+ }
+ } else if (!installed && installedIcon != null && installedIcon.getParent() == nameLayout) {
+ nameLayout.removeView(installedIcon);
+ }
+
+ updateNameLine();
+ }
+
+ public void setActive(boolean active) {
+ this.active = active;
+ if (active) {
+ if (activeIcon == null) {
+ RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
+ RelativeLayout.LayoutParams.WRAP_CONTENT,
+ RelativeLayout.LayoutParams.WRAP_CONTENT
+ );
+ // params.setMargins(0, getDp(PADDING_TOP * 2 + 2), getDp(7), 0);
+ params.setMargins(0, getDp(PADDING_TOP * 2 + 2), 0, 0);
+
+ activeIcon = new MenuImageView(getGDActivity());
+ activeIcon.setLayoutParams(params);
+ activeIcon.setImageResource(R.drawable.ic_installed);
+ }
+
+ if (activeIcon.getParent() != nameLayout) {
+ nameLayout.addView(activeIcon);
+ }
+ } else if (!active && activeIcon != null && activeIcon.getParent() == nameLayout) {
+ nameLayout.removeView(activeIcon);
+ }
+
+ updateNameLine();
+ }
+
+ public void setShowDate(boolean showDate) {
+ this.showDate = showDate;
+ updateLevelsLine();
+ }
+
+ @Override
+ public void performAction(int k) {
+ if (k == MenuScreen.KEY_FIRE) {
+ buildScreen();
+ }
+ }
+
+ protected void buildScreen() {
+ Menu menu = getGameMenu();
+ MenuScreen screen = menu.levelScreen;
+ LevelsManager levelsManager = getLevelsManager();
+
+ screen.clear();
+ // System.gc();
+
+ logDebug(level);
+
+ screen.setNavTarget(this.screen);
+ screen.setTitle(level.getName());
+
+ if (!level.getAuthor().equals(""))
+ screen.addItem(new BigTextMenuElement(Html.fromHtml(String.format(getString(R.string.author_tpl), level.getAuthor()))));
+ if (level.getInstalledTs() > 0)
+ screen.addItem(new BigTextMenuElement(Html.fromHtml(String.format(getString(R.string.installed_tpl), level.getFullInstalledDate()))));
+ else if (level.getAddedTs() > 0)
+ screen.addItem(new BigTextMenuElement(Html.fromHtml(String.format(getString(R.string.added_tpl), level.getFullAddedDate()))));
+ screen.addItem(new BigTextMenuElement(Html.fromHtml(String.format(getString(R.string.tracks_tpl), level.getCountEasy() + " / " + level.getCountMedium() + " / " + level.getCountHard()))));
+ screen.addItem(menu.createEmptyLine(true));
+
+ if (!level.isInstalled()) {
+ ActionMenuElement installAction = menu.createAction(ActionMenuElement.INSTALL);
+ installAction.setText(String.format(
+ getString(R.string.install_kb), level.getSizeKb()
+ ));
+ installAction.setHandler(this);
+
+ screen.addItem(installAction);
+ } else {
+ if (!level.isDefault()) {
+ ActionMenuElement installed = new ActionMenuElement(getString(R.string.installed), null);
+ installed.setDisabled(true);
+ screen.addItem(installed);
+ }
+
+ if (level.getId() == levelsManager.getCurrentId()) {
+ ActionMenuElement active = new ActionMenuElement(getString(R.string.active), null);
+ active.setDisabled(true);
+ screen.addItem(active);
+ } else {
+ ActionMenuElement loadAction = menu.createAction(ActionMenuElement.LOAD);
+ loadAction.setHandler(this);
+ screen.addItem(loadAction);
+ }
+
+ if (!level.isDefault() && levelsManager.getCurrentId() != level.getId()) {
+ ActionMenuElement deleteAction = menu.createAction(ActionMenuElement.DELETE);
+ deleteAction.setHandler(this);
+
+ screen.addItem(deleteAction);
+ }
+ }
+
+ screen.addItem(menu.createAction(ActionMenuElement.BACK));
+
+ if (menu.getCurrentMenu() != screen) {
+ menu.setCurrentMenu(screen, false);
+ } else {
+ screen.highlightElement();
+ }
+ }
+
+ @Override
+ public MenuScreen getCurrentMenu() {
+ return null;
+ }
+
+ @Override
+ public void setCurrentMenu(MenuScreen e1, boolean flag) {
+ }
+
+ @Override
+ public void handleAction(MenuElement item) {
+ if (item instanceof ActionMenuElement) {
+ final GDActivity gd = getGDActivity();
+ final Menu menu = getGameMenu();
+
+ switch (((ActionMenuElement) item).getActionValue()) {
+ case ActionMenuElement.DELETE:
+ if (!level.isInstalled())
+ break;
+
+ showConfirm(
+ getString(R.string.delete_levels),
+ getString(R.string.delete_levels_confirmation),
+ new Runnable() {
+ @Override
+ public void run() {
+ gd.levelsManager.deleteAsync(level, new Runnable() {
+ @Override
+ public void run() {
+ long id = level.getId();
+
+ MenuScreen target = menu.getCurrentMenu().getNavTarget();
+ if (target instanceof InstalledLevelsMenuScreen) {
+ InstalledLevelsMenuScreen installedScreen = (InstalledLevelsMenuScreen) target;
+ LevelMenuElement el = installedScreen.getElementByLevelId(id, 0);
+ if (el != null)
+ installedScreen.deleteElement(el);
+ level.setId(0);
+ menu.back();
+ } else if (target instanceof DownloadLevelsMenuScreen) {
+ DownloadLevelsMenuScreen downloadScreen = (DownloadLevelsMenuScreen) target;
+ LevelMenuElement el = downloadScreen.getElementByLevelId(id, 0);
+ if (el != null)
+ el.setInstalled(false);
+
+ level.setId(0);
+ buildScreen();
+ }
+ }
+ });
+ }
+ },
+ null
+ );
+ break;
+
+ case ActionMenuElement.INSTALL:
+ gd.levelsManager.downloadLevel(level, new Callback() {
+ @Override
+ public void onDone(Object... objects) {
+ long id = (long) objects[0];
+ level.setId(id);
+
+ MenuScreen target = menu.getCurrentMenu().getNavTarget();
+ if (target instanceof DownloadLevelsMenuScreen) {
+ DownloadLevelsMenuScreen downloadScreen = (DownloadLevelsMenuScreen) target;
+ LevelMenuElement el = downloadScreen.getElementByLevelId(id, 0);
+ if (el != null)
+ el.setInstalled(true);
+ }
+
+ buildScreen();
+ }
+ });
+ break;
+
+ case ActionMenuElement.LOAD:
+ gd.levelsManager.load(level);
+ // buildScreen();
+ break;
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return level.toString();
+ }
+
+} \ No newline at end of file
diff --git a/src/org/happysanta/gd/Menu/LevelsAdapter.java b/src/org/happysanta/gd/Menu/LevelsAdapter.java
new file mode 100644
index 0000000..9f7ddc9
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/LevelsAdapter.java
@@ -0,0 +1,53 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.text.Html;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.R;
+import org.happysanta.gd.Storage.Level;
+
+import java.util.ArrayList;
+
+import static org.happysanta.gd.Helpers.getString;
+
+public class LevelsAdapter extends ArrayAdapter<Level> {
+
+ private ArrayList<Level> levels;
+
+ public LevelsAdapter(Context context, ArrayList<Level> levels) {
+ super(context, R.layout.levels_list_item, levels);
+ this.levels = levels;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View v = convertView;
+ if (v == null) {
+ LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ v = inflater.inflate(R.layout.levels_list_item, null);
+ }
+
+ Level level = levels.get(position);
+ if (level != null) {
+ TextView name = (TextView) v.findViewById(R.id.level_name);
+ TextView count = (TextView) v.findViewById(R.id.level_count);
+
+ name.setTypeface(Global.robotoCondensedTypeface);
+ count.setTypeface(Global.robotoCondensedTypeface);
+
+ name.setText(level.getName());
+ count.setText(Html.fromHtml(String.format(getString(R.string.levels_count_tpl),
+ level.getCountEasy() + " - " + level.getCountMedium() + " - " + level.getCountHard(), level.getShortAddedDate())));
+ }
+
+ return v;
+ }
+
+}
+
+
diff --git a/src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java b/src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java
new file mode 100644
index 0000000..7ead337
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java
@@ -0,0 +1,86 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.LinearLayout;
+import org.happysanta.gd.Menu.Views.MenuImageView;
+import org.happysanta.gd.Menu.Views.MenuLinearLayout;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+import org.happysanta.gd.R;
+
+import static org.happysanta.gd.Helpers.getDp;
+import static org.happysanta.gd.Helpers.getGDActivity;
+
+public class LevelsCountTextMenuElement
+ extends BigTextMenuElement {
+
+ protected static final int PADDING_LEFT = 4;
+ protected static final int PADDING_RIGHT = 8;
+ protected static final int MARGIN_RIGHT = 3;
+
+ protected int tracks[];
+
+ protected MenuLinearLayout layout;
+ protected MenuImageView tracksImages[];
+ protected MenuTextView tracksTexts[];
+
+ public LevelsCountTextMenuElement(String s, int easy, int medium, int hard) {
+ super(s);
+
+ tracks = new int[3];
+ tracks[0] = easy;
+ tracks[1] = medium;
+ tracks[2] = hard;
+
+ createViews();
+ }
+
+ protected void createViews() {
+ Context context = getGDActivity();
+
+ layout = new MenuLinearLayout(context);
+ layout.setOrientation(LinearLayout.HORIZONTAL);
+ layout.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ));
+
+ tracksImages = new MenuImageView[3];
+ for (int i = 0; i < 3; i++) {
+ tracksImages[i] = new MenuImageView(context);
+ tracksImages[i].setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT));
+ }
+
+ tracksImages[0].setImageResource(R.drawable.levels_wheel0);
+ tracksImages[1].setImageResource(R.drawable.levels_wheel1);
+ tracksImages[2].setImageResource(R.drawable.levels_wheel2);
+
+ // Tracks texts
+ tracksTexts = new MenuTextView[3];
+ for (int i = 0; i < 3; i++) {
+ tracksTexts[i] = new MenuTextView(context);
+ setTextParams(tracksTexts[i]);
+
+ tracksTexts[i].setText(String.valueOf(tracks[i]));
+ tracksTexts[i].setPadding(getDp(PADDING_LEFT), 0, getDp(PADDING_RIGHT), 0);
+ }
+
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ params.setMargins(0, 0, getDp(MARGIN_RIGHT), 0);
+
+ textView.setLayoutParams(params);
+
+ layout.addView(textView);
+
+ // Add tracks to layout
+ for (int i = 0; i < 3; i++) {
+ layout.addView(tracksImages[i]);
+ layout.addView(tracksTexts[i]);
+ }
+ }
+
+ @Override
+ public View getView() {
+ return layout;
+ }
+}
diff --git a/src/org/happysanta/gd/Menu/LevelsMenuScreen.java b/src/org/happysanta/gd/Menu/LevelsMenuScreen.java
new file mode 100644
index 0000000..22b7539
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/LevelsMenuScreen.java
@@ -0,0 +1,429 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.os.AsyncTask;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import org.happysanta.gd.GDActivity;
+import org.happysanta.gd.Menu.Views.MenuLinearLayout;
+import org.happysanta.gd.R;
+import org.happysanta.gd.Storage.Level;
+import org.happysanta.gd.Storage.LevelsManager;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Vector;
+
+import static org.happysanta.gd.Helpers.getGDActivity;
+import static org.happysanta.gd.Helpers.getGDView;
+import static org.happysanta.gd.Helpers.getGameMenu;
+import static org.happysanta.gd.Helpers.getLevelsManager;
+import static org.happysanta.gd.Helpers.getString;
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class LevelsMenuScreen extends MenuScreen {
+
+ enum Statuses {NORMAL, DOWNLOADING, ERROR}
+
+ protected final static int ERROR_COLOR = 0xff777777;
+
+ protected Statuses status = Statuses.NORMAL;
+ protected int savedScrollY = 0;
+
+ protected Vector elements;
+ protected ArrayList<Level> levels;
+
+ protected FrameLayout progressWrap;
+ protected ProgressBar progressBar;
+
+ protected MenuLinearLayout listLayout;
+ protected TextMenuElement errorText;
+ protected AsyncAddElements addElements = null;
+ protected boolean leftFromScreen = false;
+
+ public LevelsMenuScreen(String title, MenuScreen navTarget) {
+ super(title, navTarget);
+
+ elements = new Vector();
+ levels = new ArrayList<>();
+
+ Context context = getGDActivity();
+
+ // Create progress
+ progressWrap = new FrameLayout(context);
+ progressWrap.setLayoutParams(new LinearLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.MATCH_PARENT
+ ));
+
+ progressBar = new ProgressBar(context);
+ progressBar.setIndeterminate(true);
+
+ // Create error
+ errorText = new TextMenuElement(getString(R.string.download_error));
+ TextView errorTextView = (TextView) errorText.getView();
+
+ errorTextView.setTextColor(ERROR_COLOR);
+ errorTextView.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT
+ ));
+ errorTextView.setGravity(Gravity.CENTER);
+
+ listLayout = new MenuLinearLayout(context);
+ listLayout.setOrientation(LinearLayout.VERTICAL);
+ listLayout.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT
+ ));
+
+ layout.addView(listLayout);
+
+ // List view
+ // listView = new ListView(context);
+ /*listView.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ));*/
+
+ // adapter = new LevelsAdapter(context, levels);
+ // listView.setAdapter(adapter);
+
+ // layout.addView(listView);
+ }
+
+ public int addListItem(MenuElement item) {
+ elements.addElement(item);
+ listLayout.addView(item.getView());
+
+ if (item instanceof ClickableMenuElement)
+ ((ClickableMenuElement) item).setOnHighlightListener(this);
+
+ return elements.size() - 1;
+ }
+
+ public void setStatus(Statuses status) {
+ this.status = status;
+
+ getGDView().invalidate();
+ }
+
+ protected void clearList() {
+ elements.removeAllElements();
+ levels.clear();
+ listLayout.removeAllViews();
+ lastHighlighted = null;
+ // System.gc();
+ }
+
+ protected void showError(String error) {
+ clearList();
+ errorText.setText(error);
+ addListItem(errorText);
+
+ setStatus(Statuses.ERROR);
+ }
+
+ protected void showLoading() {
+ // clearList();
+
+ if (elements.isEmpty()) {
+ if (progressBar.getParent() == listLayout) {
+ listLayout.removeView(progressBar);
+ } else if (progressBar.getParent() != progressWrap) {
+ progressWrap.addView(progressBar, new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.WRAP_CONTENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT,
+ Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL
+ ));
+ }
+
+ listLayout.addView(progressWrap);
+ } else {
+ if (progressBar.getParent() == progressWrap) {
+ progressWrap.removeView(progressBar);
+ } else if (progressBar.getParent() != listLayout) {
+ listLayout.addView(progressBar, new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ Gravity.CENTER_HORIZONTAL
+ ));
+ }
+ }
+
+ // setStatus(Statuses.DOWNLOADING);
+ }
+
+ protected void hideLoading() {
+ if (progressBar.getParent() == listLayout) {
+ listLayout.removeView(progressBar);
+ } else if (progressBar.getParent() == progressWrap) {
+ // progressWrap.setVisibility(GameView.GONE);
+ listLayout.removeView(progressWrap);
+ }
+ }
+
+ public void highlightFirstElement() {
+ for (int i = 0; i < elements.size(); i++) {
+ if (elements.elementAt(i) instanceof LevelMenuElement) {
+ highlightElementAt(i);
+ break;
+ }
+ }
+ }
+
+ public void highlightElementAt(int index) {
+ LevelMenuElement item = null;
+ try {
+ item = (LevelMenuElement) elements.elementAt(index);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return;
+ }
+
+ item.showHelmet();
+ lastHighlighted = item;
+ selectedIndex = index;
+ }
+
+ protected void load() {
+ clearList();
+ loadLevels();
+ }
+
+ protected void loadLevels() {
+
+ }
+
+ @Override
+ public void onShow() {
+ super.onShow();
+ GDActivity activity = getGDActivity();
+
+ if (leftFromScreen) {
+ clearList();
+ leftFromScreen = false;
+ }
+
+ switch (status) {
+ case DOWNLOADING:
+ break;
+
+ case NORMAL:
+ if (elements.isEmpty()) {
+ load();
+ }
+ break;
+ }
+
+ if (lastHighlighted != null) {
+ lastHighlighted.showHelmet();
+ }
+
+ if (savedScrollY != 0) {
+ activity.scrollView.scrollTo(0, savedScrollY);
+ }
+ }
+
+ @Override
+ public void onHide(MenuScreen newMenu) {
+ GDActivity activity = getGDActivity();
+
+ if (newMenu != getGameMenu().levelScreen) {
+ if (addElements != null) {
+ addElements.cancel(true);
+ addElements = null;
+ }
+
+ savedScrollY = 0;
+ status = Statuses.NORMAL;
+
+ hideLoading();
+ clearList();
+
+ leftFromScreen = true;
+ } else {
+ savedScrollY = activity.scrollView.getScrollY();
+ }
+ }
+
+ protected boolean hideDate() {
+ return false;
+ }
+
+ protected LevelsMenuScreen getThis() {
+ return this;
+ }
+
+ public void reloadLevels() {
+ if (addElements != null) {
+ addElements.cancel(true);
+ addElements = null;
+ }
+
+ clearList();
+ loadLevels();
+ }
+
+ public LevelMenuElement getElementByLevelId(long id, long apiId) {
+ for (Object _el : elements) {
+ LevelMenuElement el = (LevelMenuElement) _el;
+
+ if ((id > 0 && el.level.getId() == id) || apiId > 0 && el.level.getApiId() == apiId)
+ return el;
+ }
+
+ return null;
+ }
+
+ public void deleteElement(LevelMenuElement el) {
+ View view = el.getView();
+ listLayout.removeView(view);
+
+ int index = elements.indexOf(el);
+
+ elements.remove(el);
+ levels.remove(el.level);
+
+ if (el == lastHighlighted) {
+ index--;
+ if (index < 0)
+ index = 0;
+
+ highlightElementAt(index);
+ }
+ }
+
+ @Override
+ public void performAction(int k) {
+ logDebug("LevelsMenuScreen.performAction: k = " + k);
+ int from = 0;
+ switch (k) {
+ default:
+ if (selectedIndex != -1) {
+ for (int i = selectedIndex; i < elements.size(); i++) {
+ MenuElement item;
+ if ((item = (MenuElement) elements.elementAt(i)) != null && item.isSelectable()) {
+ item.performAction(k);
+ return;
+ }
+ }
+ }
+ break;
+
+ case KEY_UP:
+ if (selectedIndex > 0) {
+ from = selectedIndex - 1;
+ } else {
+ from = elements.size() - 1;
+ }
+
+ for (int i = from; i >= 0; i--) {
+ MenuElement el = (MenuElement) elements.elementAt(i);
+ if (!(el instanceof LevelMenuElement)) {
+ continue;
+ }
+
+ highlightElementAt(i);
+ scrollToItem(el);
+ break;
+ }
+ break;
+
+ case KEY_DOWN:
+ if (selectedIndex < elements.size() - 1) {
+ from = selectedIndex + 1;
+ } else {
+ from = 0;
+ }
+
+ for (int i = from; i < elements.size(); i++) {
+ MenuElement el = (MenuElement) elements.elementAt(i);
+ if (!(el instanceof LevelMenuElement)) {
+ continue;
+ }
+
+ highlightElementAt(i);
+ scrollToItem(el);
+ break;
+ }
+ break;
+ }
+ }
+
+ protected void scrollToItem(int index) {
+ LevelMenuElement el = (LevelMenuElement) elements.elementAt(index);
+ // logDebug(el);
+ scrollToItem(el);
+ }
+
+ protected class AsyncAddElements extends AsyncTask<Level[], Void, Void> {
+
+ @Override
+ protected Void doInBackground(Level[]... params) {
+ Level[] _levels = params[0];
+ boolean checkInstalled = getThis() instanceof DownloadLevelsMenuScreen;
+ boolean checkActive = getThis() instanceof InstalledLevelsMenuScreen;
+
+ ArrayList<Long> ids;
+ HashMap<Long, Long> installed = null;
+ LevelsManager levelsManager = getLevelsManager();
+
+ if (checkInstalled) {
+ ids = new ArrayList<>();
+
+ for (Level level : _levels) {
+ ids.add(level.getApiId());
+ }
+
+ installed = getGDActivity().levelsManager.findInstalledLevels(ids);
+ }
+
+ boolean alreadyHl = false;
+
+ for (Level level : _levels) {
+ if (isCancelled()) {
+ clearList();
+ return null;
+ }
+
+ LevelMenuElement el = new LevelMenuElement(level, getThis());
+ boolean toHl = false;
+
+ if (hideDate())
+ el.setShowDate(false);
+
+ if (checkInstalled && installed.containsKey(level.getApiId())) {
+ level.setId(installed.get(level.getApiId()));
+ el.setInstalled(true);
+ }
+ if (checkActive && level.getId() == levelsManager.getCurrentId()) {
+ el.setActive(true);
+ toHl = true;
+ }
+
+ if (!isCancelled()) {
+ int index = addListItem(el);
+ if (toHl && !alreadyHl) {
+ highlightElementAt(index);
+ // scrollToItem(index);
+ alreadyHl = true;
+ }
+
+ if (lastHighlighted == null)
+ highlightFirstElement();
+ }
+ }
+
+ levels.addAll(Arrays.asList(_levels));
+ return null;
+ }
+
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Menu.java b/src/org/happysanta/gd/Menu/Menu.java
new file mode 100755
index 0000000..7485176
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Menu.java
@@ -0,0 +1,1554 @@
+package org.happysanta.gd.Menu;
+
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.os.Environment;
+import android.text.Html;
+import android.text.InputType;
+import android.widget.EditText;
+import org.happysanta.gd.Command;
+import org.happysanta.gd.FileDialog;
+import org.happysanta.gd.GDActivity;
+import org.happysanta.gd.Game.GameView;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Levels.InvalidTrackException;
+import org.happysanta.gd.Levels.Loader;
+import org.happysanta.gd.R;
+import org.happysanta.gd.Settings;
+import org.happysanta.gd.Storage.HighScores;
+import org.happysanta.gd.Storage.Level;
+import org.happysanta.gd.Storage.LevelsManager;
+import org.acra.ACRA;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+
+import static org.happysanta.gd.Helpers.*;
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class Menu
+ implements MenuHandler {
+
+ // private final static int SETTINGS_LENGTH = 21;
+ // private final static boolean ENABLE_MANAGER = true;
+
+ public MenuScreen currentMenu;
+ public Level level;
+ private HighScores currentScores;
+ public int selectedLeague = 0;
+ public boolean m_blZ = false;
+ public boolean menuDisabled = false;
+ // byte[] unlockedTracks = new byte[3];
+ // byte leaguesUnlockedCount = 0;
+ // byte levelsUnlockedCount = 0;
+ int[] selectedTrack = {
+ 0, 0, 0
+ };
+ String[][] trackNames;
+ String[] leagues = new String[3];
+ String[] fullLeaguesList = new String[4];
+ // private byte[] settings;
+ // private SaveManager saveManager;
+ private Command okCommand;
+ private Command backCommand;
+ private MenuScreen mainMenu;
+ private MenuScreen playMenu;
+ private MenuScreen optionsMenu;
+ private MenuScreen aboutScreen;
+ private MenuScreen helpMenu;
+ private MenuScreen eraseScreen;
+ private MenuScreen resetScreen;
+ private MenuScreen finishedMenu;
+ private MenuScreen ingameScreen;
+ private SimpleMenuElementNew gameMenuItem;
+ // private SimpleMenuElementNew optionsMenuItem;
+ // private SimpleMenuElementNew helpMenuItem;
+ private OptionsMenuElement levelSelector;
+ private MenuScreen levelSelectorCurrentMenu;
+ private OptionsMenuElement trackSelector;
+ private MenuScreen trackSelectorCurrentMenu;
+ private OptionsMenuElement leagueSelector;
+ private MenuScreen leagueSelectorCurrentMenu;
+ private MenuScreen highScoreMenu;
+ private SimpleMenuElementNew highscoreItem;
+ private ActionMenuElement startItem;
+ private OptionsMenuElement perspectiveOptionItem;
+ private OptionsMenuElement shadowsOptionItem;
+ private OptionsMenuElement driverSpriteOptionItem;
+ private OptionsMenuElement bikeSpriteOptionItem;
+ private OptionsMenuElement inputOptionItem;
+ private OptionsMenuElement lookAheadOptionItem;
+ private OptionsMenuElement keyboardInMenuOptionItem;
+ private OptionsMenuElement vibrateOnTouchOptionItem;
+ private SimpleMenuElementNew clearHighscoreOptionItem;
+ private SimpleMenuElementNew fullResetItem;
+ // private ActionMenuElement yesAction;
+ // private ActionMenuElement noAction;
+ private SimpleMenuElementNew aboutMenuItem;
+ private MenuScreen objectiveHelpScreen;
+ private SimpleMenuElementNew objectiveHelpItem;
+ private MenuScreen keysHelpScreen;
+ private SimpleMenuElementNew keysHelpItem;
+ private MenuScreen unlockingHelpScreen;
+ private SimpleMenuElementNew unlockingHelpItem;
+ private MenuScreen highscoreHelpScreen;
+ private SimpleMenuElementNew highscoreHelpItem;
+ private MenuScreen optionsHelpScreen;
+ private SimpleMenuElementNew optionsHelpItem;
+ private NameInputMenuScreen nameScreen;
+ private ActionMenuElement continueAction;
+ // private ActionMenuElement goToMainAction;
+ // private ActionMenuElement exitMenuItem;
+ private ActionMenuElement ingameRestartAction;
+ private ActionMenuElement finishedRestartAction;
+ private ActionMenuElement nextAction;
+ // private ActionMenuElement okAction;
+ private ActionMenuElement nameAction;
+ private long lastTrackTime;
+ private int m_ajI;
+ private int m_atI;
+ private String finishedTime;
+ private byte[] nameChars;
+ // private RecordStore recordStore;
+ // private int m_afI = -1;
+ private boolean settingsLoadedOK;
+ private int levelIndex = 0;
+ private int track = 0;
+ private boolean leagueCompleted = false;
+ private boolean m_SZ = false;
+ private Object m_BObject;
+ private String[] difficultyLevels = null; /* {
+ "Easy", "Medium", "Hard"
+ }; */
+ // private long finishTime = 0L;
+ /*private byte perspectiveOptionEnabled = 0;
+ private byte shadowsOptionEnabled = 0;
+ private byte driverSpriteOptionEnabled = 0;
+ private byte bikerSpriteOptionEnabled = 0;
+ private byte inputOptionValue = 0;
+ private byte lookAheadOptionEnabled = 0;
+ private byte keyboardInMenuEnabled = 1;
+ private byte vibrateOnTouchEnabled = 1;*/
+ // private byte selectedTrackIndex = 0;
+ // private byte selectedLevel = 0;
+ // private byte selectedLeague = 0;
+ // private byte m_aTB = 0;
+ // private byte m_arB = 0;
+ private String[] onOffStrings = null;
+ private String[] keysetStrings = null;
+ // private EmptyLineMenuElement emptyLine;
+ // private EmptyLineMenuElement emptyLineBeforeAction;
+ // private AlertDialog alertDialog = null;
+ private Paint bgPaint;
+ public MenuScreen managerScreen;
+ public InstalledLevelsMenuScreen managerInstalledScreen;
+ public DownloadLevelsMenuScreen managerDownloadScreen;
+ // private MenuScreen managerDownloadOptionsScreen;
+ private SimpleMenuElementNew managerMenuItem;
+ public MenuScreen levelScreen;
+ // private SimpleMenuElement managerInstalledItem;
+ // private SimpleMenuElement managerDownloadItem;
+ // private HelmetRotationTask helmetRotationTask;
+ // private Timer helmetRotationTimer;
+ // public int helmetAngle;
+
+ public Menu() {
+ // Background color (instead of raster.png)
+ bgPaint = new Paint();
+ bgPaint.setColor(0x80FFFFFF);
+ }
+
+ public void load(int step) {
+ GDActivity activity = getGDActivity();
+ Loader loader = getLevelLoader();
+ LevelsManager levelsManager = getLevelsManager();
+
+ level = levelsManager.getCurrentLevel();
+
+ switch (step) {
+ case 1:
+ m_BObject = new Object();
+ nameChars = new byte[]{
+ 65, 65, 65 // A A A
+ };
+ onOffStrings = getStringArray(R.array.on_off);
+ keysetStrings = getStringArray(R.array.keyset);
+ difficultyLevels = getStringArray(R.array.difficulty);
+
+ // saveManager = new SaveManager();
+ lastTrackTime = -1L;
+ m_ajI = -1;
+ m_atI = -1;
+ finishedTime = null;
+ // settingsLoadedOK = false;
+ /*settings = new byte[SETTINGS_LENGTH];
+ for (int l = 0; l < SETTINGS_LENGTH; l++)
+ settings[l] = -127;*/
+
+ settingsLoadedOK = true;
+ /*try {
+ recordStore = RecordStore.openRecordStore(*//*(Loader.levelsFile != null ? Loader.levelsFile.getName().hashCode() : "") + *//*
+ getLevelsManager().getCurrentId() + "_" + "GDTRStates", true);
+ settingsLoadedOK = true;
+ return;
+ } catch (Exception _ex) {
+ settingsLoadedOK = false;
+ }*/
+
+ break;
+
+ case 2:
+ // m_afI = -1;
+ /*RecordEnumeration enumeration;
+ try {
+ enumeration = recordStore.enumerateRecords(null, null, false);
+ } catch (*//*RecordStoreNotOpen*//*Exception _ex) {
+ return;
+ }
+ if (enumeration.numRecords() > 0) {
+ byte[] abyte0;
+ try {
+ abyte0 = enumeration.nextRecord();
+ enumeration.reset();
+ m_afI = enumeration.nextRecordId();
+ } catch (Exception _ex) {
+ return;
+ }
+ if (abyte0.length <= SETTINGS_LENGTH)
+ System.arraycopy(abyte0, 0, settings, 0, abyte0.length);
+ enumeration.destroy();
+ }*/
+
+ /*byte[] chars;
+ if ((chars = readNameChars(16, (byte) -1)) != null && chars[0] != -1) {
+ for (int i = 0; i < 3; i++)
+ nameChars[i] = chars[i];
+
+ }*/
+
+ nameChars = Settings.getName();
+ // if (nameChars[0] == 82 && nameChars[1] == 75 && nameChars[2] == 69) {
+ if (isNameCheat(nameChars)) {
+ // Unlock everything for cheat
+ level.setUnlockedLeagues(3);
+ level.setUnlockedLevels(2);
+ level.setUnlocked(
+ loader.names[0].length - 1,
+ loader.names[1].length - 1,
+ loader.names[2].length - 1
+ );
+ // logDebug(level);
+ // leaguesUnlockedCount = 3;
+ // levelsUnlockedCount = 2;
+ /*unlockedTracks[0] = (byte) (loader.names[0].length - 1);
+ unlockedTracks[1] = (byte) (loader.names[1].length - 1);
+ unlockedTracks[2] = (byte) (loader.names[2].length - 1);*/
+ } else if (level.isSettingsClear()) {
+ level.setUnlockedLeagues(0);
+ level.setUnlockedLevels(1);
+ level.setUnlocked(0, 0, -1);
+ // leaguesUnlockedCount = 0;
+ // levelsUnlockedCount = 1;
+ /*unlockedTracks[0] = 0;
+ unlockedTracks[1] = 0;
+ unlockedTracks[2] = -1;*/
+ }
+ break;
+
+ case 3:
+ // Load settings
+ /*perspectiveOptionEnabled = readSetting(0, perspectiveOptionEnabled);
+ shadowsOptionEnabled = readSetting(1, shadowsOptionEnabled);
+ driverSpriteOptionEnabled = readSetting(2, driverSpriteOptionEnabled);
+ bikerSpriteOptionEnabled = readSetting(3, bikerSpriteOptionEnabled);
+ lookAheadOptionEnabled = readSetting(4, lookAheadOptionEnabled);
+
+ keyboardInMenuEnabled = readSetting(13, keyboardInMenuEnabled);
+ inputOptionValue = readSetting(14, inputOptionValue);*/
+ // m_arB = readSetting(15, m_arB); // nonsense
+
+ /*vibrateOnTouchEnabled = readSetting(19, keyboardInMenuEnabled);
+
+ selectedLevel = readSetting(10, selectedLevel);
+ selectedTrackIndex = readSetting(11, selectedTrackIndex);
+ selectedLeague = readSetting(12, selectedLeague);*/
+
+ // byte levelsSort = readSetting(20, (byte)0);
+
+ DownloadLevelsMenuScreen.sort = Settings.getLevelsSort();
+
+
+ levelIndex = level.getSelectedLevel();
+ track = level.getSelectedTrack();
+
+ if (nameChars[0] != 82 || nameChars[1] != 75 || nameChars[2] != 69) {
+ //level.setUnlockedLeagues();
+ /*leaguesUnlockedCount = readSetting(5, leaguesUnlockedCount);
+ levelsUnlockedCount = readSetting(6, levelsUnlockedCount);
+ for (int i = 0; i < 3; i++)
+ unlockedTracks[i] = readSetting(7 + i, unlockedTracks[i]);*/
+ }
+
+ try {
+ selectedTrack[level.getSelectedLevel()] = level.getSelectedTrack();
+ } catch (ArrayIndexOutOfBoundsException _ex) {
+ level.setSelectedLevel(0);
+ level.setSelectedTrack(0);
+ selectedTrack[level.getSelectedLevel()] = level.getSelectedTrack();
+ }
+ getLevelLoader().setPerspectiveEnabled(Settings.isPerspectiveEnabled());
+ getLevelLoader().setShadowsEnabled(Settings.isShadowsEnabled());
+ activity.physEngine._ifZV(Settings.isLookAheadEnabled());
+ getGDView().setInputOption(Settings.getInputOption());
+ // getGDView()._aZV(m_aTB == 0);
+ getGDView()._aZV(true);
+ String[] leaguesList = getStringArray(R.array.leagues);
+ fullLeaguesList = getStringArray(R.array.leagues_full);
+ trackNames = getLevelLoader().names;
+
+ if (level.getUnlockedLeagues() < 3) {
+ leagues = leaguesList;
+ } else {
+ leagues = fullLeaguesList;
+ }
+
+ selectedLeague = level.getSelectedLeague();
+
+ break;
+
+ case 4:
+ mainMenu = new MenuScreen(getString(R.string.main), null);
+ playMenu = new MenuScreen(getString(R.string.play), mainMenu);
+ managerScreen = new MenuScreen(getString(R.string.mods), mainMenu);
+ optionsMenu = new MenuScreen(getString(R.string.options), mainMenu);
+ aboutScreen = new MenuScreen(getString(R.string.about) + " v" + getAppVersion(), mainMenu);
+ helpMenu = new MenuScreen(getString(R.string.help), mainMenu);
+
+ continueAction = new ActionMenuElement(getString(R.string._continue), ActionMenuElement.CONTINUE, this);
+ nextAction = new ActionMenuElement(getString(R.string.track) + ": " + getLevelLoader().getLevelName(0, 1), ActionMenuElement.NEXT, this);
+ ingameRestartAction = new ActionMenuElement(getString(R.string.restart) + ": " + getLevelLoader().getLevelName(0, 0), ActionMenuElement.RESTART, this);
+ finishedRestartAction = new ActionMenuElement(getString(R.string.restart) + ": " + getLevelLoader().getLevelName(0, 0), ActionMenuElement.RESTART, this);
+
+ /*nextAction = new ActionMenuElement(getString(R.string.track) + ": DEFAULT", ActionMenuElement.NEXT, this);
+ ingameRestartAction = new ActionMenuElement(getString(R.string.restart) + ": DEFAULT", ActionMenuElement.RESTART, this);
+ finishedRestartAction = new ActionMenuElement(getString(R.string.restart) + ": DEFAULT", ActionMenuElement.RESTART, this);*/
+
+ highScoreMenu = new MenuScreen(getString(R.string.highscores), playMenu);
+ finishedMenu = new MenuScreen(getString(R.string.finished), playMenu);
+ ingameScreen = new MenuScreen(getString(R.string.ingame), playMenu);
+ nameScreen = new NameInputMenuScreen(getString(R.string.enter_name), finishedMenu, nameChars);
+ eraseScreen = new MenuScreen(getString(R.string.confirm_clear), optionsMenu);
+ resetScreen = new MenuScreen(getString(R.string.confirm_reset), eraseScreen);
+
+ gameMenuItem = new SimpleMenuElementNew(getString(R.string.play_menu), playMenu, this);
+ managerMenuItem = new SimpleMenuElementNew(getString(R.string.mods), managerScreen, this);
+ aboutMenuItem = new SimpleMenuElementNew(getString(R.string.about), aboutScreen, this);
+
+ mainMenu.addItem(gameMenuItem);
+ //if (ENABLE_MANAGER)
+ mainMenu.addItem(new SimpleMenuElementNew(getString(R.string.mods), managerScreen, this));
+ mainMenu.addItem(new SimpleMenuElementNew(getString(R.string.options), optionsMenu, this));
+ mainMenu.addItem(new SimpleMenuElementNew(getString(R.string.help), helpMenu, this));
+ mainMenu.addItem(aboutMenuItem);
+ if (Global.DEBUG) {
+ // mainMenu.addItem(createAction(ActionMenuElement.RESTART_WITH_NEW_LEVEL));
+ mainMenu.addItem(createAction(ActionMenuElement.SEND_LOGS));
+ }
+ mainMenu.addItem(createAction(ActionMenuElement.EXIT));
+
+ levelSelector = new OptionsMenuElement(getString(R.string.level), level.getSelectedLevel(), this, difficultyLevels, false, playMenu);
+ trackSelector = new OptionsMenuElement(getString(R.string.track), selectedTrack[level.getSelectedLevel()], this, trackNames[level.getSelectedLevel()], false, playMenu);
+ leagueSelector = new OptionsMenuElement(getString(R.string.league), selectedLeague, this, leagues, false, playMenu);
+ try {
+ trackSelector.setUnlockedCount(level.getUnlocked(level.getSelectedLevel()));
+ } catch (ArrayIndexOutOfBoundsException _ex) {
+ trackSelector.setUnlockedCount(0);
+ }
+ levelSelector.setUnlockedCount(level.getUnlockedLevels());
+ leagueSelector.setUnlockedCount(level.getUnlockedLeagues());
+ highscoreItem = new SimpleMenuElementNew(getString(R.string.highscores), highScoreMenu, this);
+ highScoreMenu.addItem(createAction(ActionMenuElement.BACK));
+ startItem = new ActionMenuElement(getString(R.string.start) + ">", this);
+ playMenu.addItem(startItem);
+ playMenu.addItem(levelSelector);
+ playMenu.addItem(trackSelector);
+ playMenu.addItem(leagueSelector);
+ playMenu.addItem(highscoreItem);
+ playMenu.addItem(createAction(ActionMenuElement.GO_TO_MAIN));
+ // if (hasPointer)
+ // softwareJoystickOptionItem = new ActionMenuElement("Software Joystick", m_aTB, this, onOffStrings, true, activity, optionsMenu, false);
+ perspectiveOptionItem = new OptionsMenuElement(getString(R.string.perspective), Settings.isPerspectiveEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu);
+ shadowsOptionItem = new OptionsMenuElement(getString(R.string.shadows), Settings.isShadowsEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu);
+ driverSpriteOptionItem = new OptionsMenuElement(getString(R.string.driver_sprite), Settings.isDriverSpriteEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu);
+ bikeSpriteOptionItem = new OptionsMenuElement(getString(R.string.bike_sprite), Settings.isBikeSpriteEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu);
+ inputOptionItem = new OptionsMenuElement(getString(R.string.input), Settings.getInputOption(), this, keysetStrings, false, optionsMenu);
+ lookAheadOptionItem = new OptionsMenuElement(getString(R.string.look_ahead), Settings.isLookAheadEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu);
+ vibrateOnTouchOptionItem = new OptionsMenuElement(getString(R.string.vibrate_on_touch), Settings.isVibrateOnTouchEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu);
+ keyboardInMenuOptionItem = new OptionsMenuElement(getString(R.string.keyboard_in_menu), Settings.isKeyboardInMenuEnabled() ? 0 : 1, this, onOffStrings, true, optionsMenu);
+ clearHighscoreOptionItem = new SimpleMenuElementNew(getString(R.string.clear_highscore), eraseScreen, this);
+
+ // if (hasPointer)
+ // optionsMenu.addItem(softwareJoystickOptionItem);
+ optionsMenu.addItem(perspectiveOptionItem);
+ optionsMenu.addItem(shadowsOptionItem);
+ optionsMenu.addItem(driverSpriteOptionItem);
+ optionsMenu.addItem(bikeSpriteOptionItem);
+ optionsMenu.addItem(inputOptionItem);
+ optionsMenu.addItem(lookAheadOptionItem);
+ optionsMenu.addItem(vibrateOnTouchOptionItem);
+ optionsMenu.addItem(keyboardInMenuOptionItem);
+ optionsMenu.addItem(clearHighscoreOptionItem);
+ optionsMenu.addItem(createAction(ActionMenuElement.BACK));
+
+ // noAction = new ActionMenuElement(getString(R.string.no), 0, this, null, false, mainMenu, true);
+ // yesAction = new ActionMenuElement(getString(R.string.yes), 0, this, null, false, mainMenu, true);
+ fullResetItem = new SimpleMenuElementNew(getString(R.string.full_reset), resetScreen, this);
+ eraseScreen.addItem(new TextMenuElement(getString(R.string.erase_text1)));
+ eraseScreen.addItem(new TextMenuElement(getString(R.string.erase_text2)));
+ eraseScreen.addItem(createEmptyLine(true));
+ eraseScreen.addItem(createAction(ActionMenuElement.NO));
+ eraseScreen.addItem(createAction(ActionMenuElement.YES));
+ eraseScreen.addItem(fullResetItem);
+ resetScreen.addItem(new TextMenuElement(getString(R.string.reset_text1)));
+ resetScreen.addItem(new TextMenuElement(getString(R.string.reset_text2)));
+ resetScreen.addItem(createEmptyLine(true));
+ resetScreen.addItem(createAction(ActionMenuElement.NO));
+ resetScreen.addItem(createAction(ActionMenuElement.YES));
+
+ objectiveHelpScreen = new MenuScreen(getString(R.string.objective), helpMenu);
+ objectiveHelpScreen.setIsTextScreen(true);
+ objectiveHelpItem = new SimpleMenuElementNew(getString(R.string.objective), objectiveHelpScreen, this);
+ objectiveHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.objective_text))));
+ objectiveHelpScreen.addItem(createAction(ActionMenuElement.BACK));
+
+ keysHelpScreen = new MenuScreen(getString(R.string.keys), helpMenu);
+ keysHelpScreen.setIsTextScreen(true);
+ keysHelpItem = new SimpleMenuElementNew(getString(R.string.keys), keysHelpScreen, this);
+ keysHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.keyset_text))));
+ keysHelpScreen.addItem(new ActionMenuElement(getString(R.string.back), ActionMenuElement.BACK, this));
+
+ unlockingHelpScreen = new MenuScreen(getString(R.string.unlocking), helpMenu);
+ unlockingHelpScreen.setIsTextScreen(true);
+ unlockingHelpItem = new SimpleMenuElementNew(getString(R.string.unlocking), unlockingHelpScreen, this);
+ unlockingHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.unlocking_text))));
+ unlockingHelpScreen.addItem(createAction(ActionMenuElement.BACK));
+
+ highscoreHelpScreen = new MenuScreen(getString(R.string.highscores), helpMenu);
+ highscoreHelpScreen.setIsTextScreen(true);
+ highscoreHelpItem = new SimpleMenuElementNew(getString(R.string.highscores), highscoreHelpScreen, this);
+ highscoreHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.highscore_text))));
+ highscoreHelpScreen.addItem(createAction(ActionMenuElement.BACK));
+
+ optionsHelpScreen = new MenuScreen(getString(R.string.options), helpMenu);
+ optionsHelpScreen.setIsTextScreen(true);
+ optionsHelpItem = new SimpleMenuElementNew(getString(R.string.options), optionsHelpScreen, this);
+ optionsHelpScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.options_text))));
+ optionsHelpScreen.addItem(createAction(ActionMenuElement.BACK));
+
+ helpMenu.addItem(objectiveHelpItem);
+ helpMenu.addItem(keysHelpItem);
+ helpMenu.addItem(unlockingHelpItem);
+ helpMenu.addItem(highscoreHelpItem);
+ helpMenu.addItem(optionsHelpItem);
+ helpMenu.addItem(createAction(ActionMenuElement.BACK));
+
+ aboutScreen.setIsTextScreen(true);
+ aboutScreen.addItem(new TextMenuElement(Html.fromHtml(getString(R.string.about_text))));
+ aboutScreen.addItem(createAction(ActionMenuElement.BACK));
+
+ ingameScreen.addItem(continueAction);
+ ingameScreen.addItem(ingameRestartAction);
+ ingameScreen.addItem(new SimpleMenuElementNew(getString(R.string.options), optionsMenu, this));
+ ingameScreen.addItem(new SimpleMenuElementNew(getString(R.string.help), helpMenu, this));
+ ingameScreen.addItem(createAction(ActionMenuElement.PLAY_MENU));
+ nameAction = new ActionMenuElement(getString(R.string.name) + " - " + new String(nameChars), 0, this);
+ okCommand = new Command(getString(R.string.ok), 4, 1);
+ backCommand = new Command(getString(R.string.back), 2, 1);
+ setCurrentMenu(mainMenu, false);
+
+ // LevelsManager
+ managerInstalledScreen = new InstalledLevelsMenuScreen(getString(R.string.installed_mods), managerScreen);
+ managerDownloadScreen = new DownloadLevelsMenuScreen(getString(R.string.download_mods), managerScreen);
+ // managerDownloadOptionsScreen = new MenuScreen(getString(R.string.download_options), managerDownloadScreen);
+
+ /*managerInstalledScreen.setIsLevelsList(true);
+ managerDownloadScreen.setIsLevelsList(true);*/
+
+ // LevelsManager
+ managerScreen.addItem(new SimpleMenuElementNew(getString(R.string.download_mods), managerDownloadScreen, this));
+ managerScreen.addItem(new SimpleMenuElementNew(getString(R.string.installed_mods), managerInstalledScreen, this));
+ managerScreen.addItem(createEmptyLine(true));
+ // managerScreen.addItem(new ActionMenuElement(getString(R.string.install_mrg), this));
+ managerScreen.addItem(new ActionMenuElement(getString(R.string.install_mrg), ActionMenuElement.SELECT_FILE, this));
+
+ // LevelsManager installed
+ // managerInstalledScreen.addItem(new TextMenuElement(getString(R.string.installed_levels_text)));
+
+ // Level screen
+ levelScreen = new MenuScreen("", null);
+ break;
+ }
+ }
+
+ /*public void reloadLevels() {
+ Loader loader = getLevelLoader();
+ trackNames = loader.names;
+ setUnlockedLevels();
+ }*/
+
+ protected ActionMenuElement createAction(int action) {
+ int r;
+ switch (action) {
+ case ActionMenuElement.BACK:
+ r = R.string.back;
+ break;
+
+ case ActionMenuElement.NO:
+ r = R.string.no;
+ break;
+
+ case ActionMenuElement.YES:
+ r = R.string.yes;
+ break;
+
+ case ActionMenuElement.EXIT:
+ r = R.string.exit;
+ break;
+
+ case ActionMenuElement.OK:
+ r = R.string.ok;
+ break;
+
+ case ActionMenuElement.PLAY_MENU:
+ r = R.string.play_menu;
+ break;
+
+ case ActionMenuElement.GO_TO_MAIN:
+ r = R.string.go_to_main;
+ break;
+
+ case ActionMenuElement.RESTART:
+ r = R.string.restart;
+ break;
+
+ case ActionMenuElement.NEXT:
+ r = R.string.next;
+ break;
+
+ case ActionMenuElement.CONTINUE:
+ r = R.string._continue;
+ break;
+
+ case ActionMenuElement.LOAD:
+ r = R.string.load_this_game;
+ break;
+
+ case ActionMenuElement.INSTALL:
+ r = R.string.install_kb;
+ break;
+
+ case ActionMenuElement.DELETE:
+ r = R.string.delete;
+ break;
+
+ case ActionMenuElement.RESTART_WITH_NEW_LEVEL:
+ r = R.string.restart_with_new_level;
+ break;
+
+ case ActionMenuElement.SEND_LOGS:
+ r = R.string.send_logs;
+ break;
+
+ default:
+ return null;
+ }
+
+ return new ActionMenuElement(getString(r), action, this);
+ }
+
+ public EmptyLineMenuElement createEmptyLine(boolean beforeAction) {
+ return new EmptyLineMenuElement(beforeAction ? 10 : 20);
+ }
+
+ public int getSelectedLevel() {
+ return levelSelector.getSelectedOption();
+ }
+
+ public int getSelectedTrack() {
+ return trackSelector.getSelectedOption();
+ }
+
+ // not sure about this name
+ public boolean canStartTrack() {
+ if (m_SZ) {
+ m_SZ = false;
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private void saveCompletedTrack() {
+ // ATTENTION!!!
+ // WHEN CHANGING THIS CODE, COPY-PASTE TO startTrack() !!!
+
+ LevelsManager levelsManager = getLevelsManager();
+
+ try {
+ currentScores.saveHighScore(leagueSelector.getSelectedOption(), new String(nameChars, "UTF-8"), lastTrackTime);
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ showAlert(getString(R.string.error), e.getMessage(), null);
+ }
+ // saveManager.write();
+ levelsManager.saveHighScores(currentScores);
+
+ leagueCompleted = false;
+
+ finishedMenu.clear();
+ finishedMenu.addItem(new TextMenuElement(Html.fromHtml("<b>" + getString(R.string.time) + "</b>: " + finishedTime)));
+
+ System.gc();
+ String[] as = currentScores.getScores(leagueSelector.getSelectedOption());
+ for (int k = 0; k < as.length; k++)
+ if (as[k] != null)
+ finishedMenu.addItem(new TextMenuElement("" + (k + 1) + ". " + as[k]));
+
+ byte byte0 = -1;
+ // logDebug("trackSelector.getUnlockedCount() = " + trackSelector.getUnlockedCount());
+ // logDebug("trackSelector.getSelectedOption() = " + trackSelector.getSelectedOption());
+
+ // {
+ // int unlockedTracks = trackSelector.getUnlockedCount();
+ // int selectedTrack = trackSelector.getSelectedOption();
+ // int selectedLevel = levelSelector.getSelectedOption();
+ // int unlockedInLevel = level.getUnlocked(selectedLevel);
+
+ // logDebug("unlockedTracks (trackSelector) = " + trackSelector.getUnlockedCount());
+ // logDebug("selectedTrack (trackSelector) = " + selectedTrack);
+ // logDebug("selectedLevel (levelSelector) = " + levelSelector.getSelectedOption());
+ // logDebug("unlockedInLevel (level.getUnlocked()) = " + level.getUnlocked(levelSelector.getSelectedOption()));
+
+ if (trackSelector.getUnlockedCount() >= trackSelector.getSelectedOption()) {
+ trackSelector.setUnlockedCount(
+ trackSelector.getSelectedOption() + 1 >= level.getUnlocked(levelSelector.getSelectedOption())
+ ? trackSelector.getSelectedOption() + 1
+ : level.getUnlocked(levelSelector.getSelectedOption())
+ );
+ level.setUnlocked(levelSelector.getSelectedOption(),
+ trackSelector.getUnlockedCount() >= level.getUnlocked(levelSelector.getSelectedOption())
+ ? trackSelector.getUnlockedCount()
+ : level.getUnlocked(levelSelector.getSelectedOption())
+ );
+ }
+ // }
+
+ // Completed league
+ if (trackSelector.getSelectedOption() == trackSelector.getOptionCount()) {
+ leagueCompleted = true;
+ switch (levelSelector.getSelectedOption()) {
+ default:
+ break;
+
+ case 0:
+ if (level.getUnlockedLeagues() < 1) {
+ byte0 = 1;
+ level.setUnlockedLeagues(1);
+ // leaguesUnlockedCount = 1;
+ leagueSelector.setUnlockedCount(level.getUnlockedLeagues());
+ }
+ break;
+
+ case 1:
+ if (level.getUnlockedLeagues() < 2) {
+ byte0 = 2;
+ level.setUnlockedLeagues(2);
+ // leaguesUnlockedCount = 2;
+ leagueSelector.setUnlockedCount(level.getUnlockedLeagues());
+ }
+ break;
+
+ case 2:
+ if (level.getUnlockedLeagues() < 3) {
+ byte0 = 3;
+ level.setUnlockedLeagues(3);
+ leagueSelector.setOptions(fullLeaguesList);
+ leagues = fullLeaguesList;
+ leagueSelector.setUnlockedCount(level.getUnlockedLeagues());
+ }
+ break;
+ }
+
+ levelSelector.setUnlockedCount(levelSelector.getUnlockedCount() + 1);
+
+ int newUnlocked = level.getUnlocked(levelSelector.getSelectedOption()) + 1,
+ tracksCount = level.getCount(levelSelector.getSelectedOption());
+
+ if (newUnlocked > tracksCount)
+ newUnlocked = tracksCount;
+
+ level.setUnlocked(levelSelector.getSelectedOption(), newUnlocked);
+ if (level.getUnlocked(levelSelector.getUnlockedCount()) == -1) {
+ level.setUnlocked(levelSelector.getUnlockedCount(), 0);
+ }
+ // if (unlockedTracks[levelSelector.getUnlockedCount()] == -1)
+ // unlockedTracks[levelSelector.getUnlockedCount()] = 0;
+ } else {
+ trackSelector.performAction(MenuScreen.KEY_RIGHT);
+ }
+
+ // int completedCount = _bbII(levelSelector.getSelectedOption());
+ int completedCount = level.getUnlocked(levelSelector.getSelectedOption()); // TODO test
+ finishedMenu.addItem(new TextMenuElement(Html.fromHtml(String.format(getString(R.string.tracks_completed_tpl),
+ completedCount, trackNames[levelSelector.getSelectedOption()].length, difficultyLevels[levelSelector.getSelectedOption()]))));
+ System.gc();
+
+ if (!leagueCompleted) {
+ ingameRestartAction.setText(getString(R.string.restart) + ": " + getLevelLoader().getLevelName(levelSelector.getSelectedOption(), trackSelector.getSelectedOption()));
+ nextAction.setText(getString(R.string.next) + ": " + getLevelLoader().getLevelName(levelIndex, track + 1));
+
+ // getLevelsManager().updateLevelSettings();
+ saveAll();
+ } else {
+ // League completed
+ if (levelSelector.getSelectedOption() < levelSelector.getOptionCount()) {
+ levelSelector.setSelectedOption(levelSelector.getSelectedOption() + 1);
+ trackSelector.setSelectedOption(0);
+ trackSelector.setUnlockedCount(level.getUnlocked(levelSelector.getSelectedOption()));
+ }
+
+ if (byte0 != -1) {
+ finishedMenu.addItem(new TextMenuElement(getString(R.string.congratulations) + leagues[byte0]));
+ if (byte0 == 3)
+ finishedMenu.addItem(new TextMenuElement(getString(R.string.enjoy)));
+ showAlert(getString(R.string.league_unlocked), getString(R.string.league_unlocked_text) + leagues[byte0], null);
+
+ // getLevelsManager().updateLevelSettings();
+ saveAll();
+ } else {
+ boolean flag = true;
+ for (int i1 = 0; i1 < 3; i1++)
+ if (level.getUnlocked(i1) != getLevelLoader().names[i1].length - 1)
+ flag = false;
+
+ if (!flag)
+ finishedMenu.addItem(new TextMenuElement(getString(R.string.level_completed_text)));
+ }
+ }
+
+ if (!leagueCompleted)
+ finishedMenu.addItem(nextAction);
+
+ finishedRestartAction.setText(getString(R.string.restart) + ": " + getLevelLoader().getLevelName(levelIndex, track));
+ finishedMenu.addItem(finishedRestartAction);
+ finishedMenu.addItem(createAction(ActionMenuElement.PLAY_MENU));
+
+ setCurrentMenu(finishedMenu, false);
+ }
+
+ //public void _hvV() {
+ // getGDActivity().m_di.postInvalidate();
+ //}
+
+ /* public int getGameViewScaledHeight() {
+ return getGDView().getScaledHeight();
+ }
+
+ public int getGameViewScaledWidth() {
+ return getGDView().getScaledWidth();
+ } */
+
+ public void showMenu(int k) {
+ logDebug("[Menu] showMenu()");
+ // k = 2;
+
+ GDActivity gd = getGDActivity();
+ GameView view = getGDView();
+ Loader loader = getLevelLoader();
+
+ m_blZ = false;
+ menuDisabled = false;
+ switch (k) {
+ case 0: // Just started
+ setCurrentMenu(mainMenu, false);
+ gd.physEngine._casevV();
+ m_SZ = true;
+ break;
+
+ case 1: // Ingame
+ levelIndex = levelSelector.getSelectedOption();
+ track = trackSelector.getSelectedOption();
+ ingameRestartAction.setText(getString(R.string.restart) + ": " + loader.getLevelName(levelIndex, track));
+ m_SZ = false;
+ ingameScreen.resetHighlighted();
+ setCurrentMenu(ingameScreen, false);
+ break;
+
+ case 2: // Finished
+ // finishTime = System.currentTimeMillis();
+ finishedMenu.clear();
+
+ levelIndex = levelSelector.getSelectedOption();
+ track = trackSelector.getSelectedOption();
+ HighScores scores = getLevelsManager().getHighScores(levelSelector.getSelectedOption(), trackSelector.getSelectedOption());
+ currentScores = scores;
+
+ // saveManager.setTrack(levelSelector.getSelectedOption(), trackSelector.getSelectedOption());
+ int place = scores.getPlace(leagueSelector.getSelectedOption(), lastTrackTime);
+ finishedTime = getDurationString(lastTrackTime);
+
+ if (place >= 0 && place <= 2) {
+ HighScoreTextMenuElement placeText = new HighScoreTextMenuElement("");
+ placeText.setText(getStringArray(R.array.finished_places)[place]);
+ placeText.setMedal(true, place);
+
+ finishedMenu.addItem(placeText);
+
+ TextMenuElement h2 = new TextMenuElement(finishedTime);
+ finishedMenu.addItem(h2);
+
+ // finishedMenu.addItem(createEmptyLine(true));
+ finishedMenu.addItem(createAction(ActionMenuElement.OK));
+ finishedMenu.addItem(nameAction);
+
+ setCurrentMenu(finishedMenu, false);
+ m_blZ = false;
+ } else {
+ saveCompletedTrack();
+ }
+ break;
+
+ default:
+ setCurrentMenu(mainMenu, false);
+ break;
+ }
+
+ long l1 = System.currentTimeMillis();
+ view.drawTimer = false;
+ long l4 = 0L;
+ int i1 = 50;
+ gd.physEngine._charvV();
+ gd.gameToMenu();
+
+ do {
+ if (!gd.isMenuShown() || !gd.alive || currentMenu == null)
+ break;
+
+ if (gd.m_cZ) {
+ while (gd.m_cZ) {
+ // logDebug("[Menu] showMenu() waiting loop");
+ if (!gd.alive || currentMenu == null) {
+ break;
+ }
+
+ try {
+ Thread.sleep(100L);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+ if (gd.physEngine != null && gd.physEngine._gotovZ()) {
+ int j1;
+ if ((j1 = gd.physEngine._dovI()) != 0 && j1 != 4)
+ try {
+ gd.physEngine._doZV(true);
+ } catch (NullPointerException e) {
+ }
+ gd.physEngine._charvV();
+ // _hvV();
+ long l2;
+ if ((l2 = System.currentTimeMillis()) - l4 < (long) i1) {
+ try {
+ synchronized (m_BObject) {
+ m_BObject.wait((long) i1 - (l2 - l4) >= 1L ? (long) i1 - (l2 - l4) : 1L);
+ }
+ } catch (InterruptedException e) {
+ }
+ l4 = System.currentTimeMillis();
+ } else {
+ l4 = l2;
+ }
+ } else {
+ i1 = 50;
+ long l3;
+ if ((l3 = System.currentTimeMillis()) - l4 < (long) i1) {
+ Object obj;
+ try {
+ synchronized (obj = new Object()) {
+ obj.wait((long) i1 - (l3 - l4) >= 1L ? (long) i1 - (l3 - l4) : 1L);
+ }
+ } catch (InterruptedException e) {
+ }
+ l4 = System.currentTimeMillis();
+ } else {
+ l4 = l3;
+ }
+ }
+ } while (true);
+
+ logDebug("[Menu.showMenu] out loop");
+
+ gd.m_forJ += System.currentTimeMillis() - l1;
+ if (view != null)
+ view.drawTimer = true;
+
+ if (currentMenu == null && gd != null) {
+ logDebug("[Menu.showMenu] currentMenu == null, set alive = false");
+ gd.exiting = true;
+ gd.alive = false;
+ }
+ }
+
+ public synchronized void draw(Canvas g1) {
+ if (currentMenu != null && !m_blZ) {
+ getGDView().drawGame(g1);
+ drawBackgroundColor(g1);
+ // currentMenu.draw(g1);
+ }
+ }
+
+ private void drawBackgroundColor(Canvas g1) {
+ g1.drawRect(0, 0, getGDView().getScaledWidth(), getGDView().getScaledHeight(), bgPaint);
+ }
+
+ public void _tryIV(int k) {
+ // logDebug("_tryIV k = " + k);
+ if (getGDView().getGameAction(k) != 8)
+ keyPressed(k);
+ }
+
+ public void keyPressed(int k) {
+ if (currentMenu != null && !menuDisabled)
+ switch (getGDView().getGameAction(k)) {
+ case MenuScreen.KEY_UP: // up
+ currentMenu.performAction(MenuScreen.KEY_UP);
+ return;
+
+ case MenuScreen.KEY_DOWN: // down
+ currentMenu.performAction(MenuScreen.KEY_DOWN);
+ return;
+
+ case MenuScreen.KEY_FIRE: // fire
+ currentMenu.performAction(MenuScreen.KEY_FIRE);
+ return;
+
+ case MenuScreen.KEY_RIGHT: // right
+ currentMenu.performAction(MenuScreen.KEY_RIGHT);
+ if (currentMenu == highScoreMenu) {
+ selectedLeague++;
+ if (selectedLeague > leagueSelector.getUnlockedCount())
+ selectedLeague = leagueSelector.getUnlockedCount();
+ showHighScoreMenu(selectedLeague);
+ return;
+ }
+ break;
+
+ case MenuScreen.KEY_LEFT: // left
+ currentMenu.performAction(MenuScreen.KEY_LEFT);
+ if (currentMenu != highScoreMenu)
+ break;
+ selectedLeague--;
+ if (selectedLeague < 0)
+ selectedLeague = 0;
+ showHighScoreMenu(selectedLeague);
+ break;
+ }
+ }
+
+ public void onCommand(Command command) {
+ if (command == okCommand) {
+ ok();
+ } else if (command == backCommand && currentMenu != null) {
+ back();
+ }
+ }
+
+ public void back() {
+ if (currentMenu == ingameScreen) {
+ getGDActivity().menuToGame();
+ return;
+ }
+ if (currentMenu != null)
+ setCurrentMenu(currentMenu.getNavTarget(), true);
+ }
+
+ public void ok() {
+ if (currentMenu != null) {
+ currentMenu.performAction(1);
+ return;
+ }
+ }
+
+ public MenuScreen getCurrentMenu() {
+ return currentMenu;
+ }
+
+ public void setCurrentMenu(MenuScreen newMenu, boolean flag) {
+ menuDisabled = false;
+ GDActivity gd = getGDActivity();
+ GameView view = getGDView();
+
+ if (!Settings.isKeyboardInMenuEnabled()) {
+ if (newMenu == nameScreen) {
+ gd.showKeyboardLayout();
+ } else {
+ gd.hideKeyboardLayout();
+ }
+ }
+
+ view.removeCommand(backCommand);
+ if (newMenu != mainMenu && newMenu != finishedMenu && newMenu != null)
+ view.addCommand(backCommand);
+
+ if (newMenu == highScoreMenu) {
+ selectedLeague = leagueSelector.getSelectedOption();
+ showHighScoreMenu(selectedLeague);
+ } else if (newMenu == finishedMenu) {
+ // logDebug("it's finished!!!");
+ nameChars = nameScreen.getChars();
+ nameAction.setText(getString(R.string.name) + " - " + new String(nameChars));
+ } else if (newMenu == playMenu) {
+ trackSelector.setOptions(getLevelLoader().names[levelSelector.getSelectedOption()], false);
+ if (currentMenu == trackSelectorCurrentMenu) {
+ selectedTrack[levelSelector.getSelectedOption()] = trackSelector.getSelectedOption();
+ }
+ trackSelector.setUnlockedCount(level.getUnlocked(levelSelector.getSelectedOption()));
+ trackSelector.setSelectedOption(selectedTrack[levelSelector.getSelectedOption()]);
+ }
+ if (newMenu == mainMenu || newMenu == playMenu && gd.physEngine != null)
+ gd.physEngine._casevV();
+
+ if (currentMenu != null)
+ currentMenu.onHide(newMenu);
+
+ currentMenu = newMenu;
+ if (currentMenu != null) {
+ gd.setMenu(currentMenu.getLayout());
+ currentMenu.onShow();
+
+ // getGDActivity().setMenu(currentMenu.getTable());
+ // if (!isOnOffToggle) currentMenu.scrollUp();
+ }
+
+ // getGDActivity().physEngine._casevV();
+ m_blZ = false;
+
+ // */
+ }
+
+ public void showHighScoreMenu(int league) {
+ HighScores highScores = getLevelsManager().getHighScores(levelSelector.getSelectedOption(), trackSelector.getSelectedOption());
+
+ highScoreMenu.clear();
+ highScoreMenu.setTitle(getString(R.string.highscores) + ": " + getLevelLoader().getLevelName(levelSelector.getSelectedOption(), trackSelector.getSelectedOption()));
+
+ HighScoreTextMenuElement subtitle = new HighScoreTextMenuElement(Html.fromHtml(getString(R.string.league) + ": " + leagueSelector.getOptions()[league]));
+ subtitle.setIsSubtitle(true);
+
+ highScoreMenu.addItem(subtitle);
+
+ String[] scores = highScores.getScores(league);
+
+ for (int place = 0; place < scores.length; place++) {
+ if (scores[place] == null)
+ continue;
+
+ HighScoreTextMenuElement h1 = new HighScoreTextMenuElement("" + (place + 1) + ". " + scores[place]);
+ if (place == 0)
+ h1.setMedal(true, 0);
+ else if (place == 1)
+ h1.setMedal(true, 1);
+ else if (place == 2)
+ h1.setMedal(true, 2);
+
+ h1.setLayoutPadding(true);
+ highScoreMenu.addItem(h1);
+ }
+
+ // saveManager.closeRecordStore();
+ if (scores[0] == null)
+ highScoreMenu.addItem(new TextMenuElement(getString(R.string.no_highscores)));
+
+ highScoreMenu.addItem(createAction(ActionMenuElement.BACK));
+ highScoreMenu.highlightElement();
+
+ // System.gc();
+ }
+
+ public synchronized void destroy() {
+ currentMenu = null;
+ }
+
+ public synchronized void saveAll() {
+ logDebug("saveAll()");
+
+ try {
+ if (level != null) {
+ Settings.setName(nameChars);
+
+ level.setUnlockedLeagues(leagueSelector.getUnlockedCount());
+ level.setUnlockedLevels(levelSelector.getUnlockedCount());
+
+ level.setSelectedLevel(levelSelector.getSelectedOption());
+ level.setSelectedTrack(trackSelector.getSelectedOption());
+ level.setSelectedLeague(leagueSelector.getSelectedOption());
+
+ getLevelsManager().updateLevelSettings();
+ } else {
+ logDebug("saveAll(): level == null");
+ }
+ } catch (Exception e) {
+ logDebug("saveAll exception: " + e);
+ }
+ }
+
+ public void handleAction(MenuElement item) {
+ final GDActivity gd = getGDActivity();
+
+ if (currentMenu == null) {
+ return;
+ }
+
+ if (item == startItem)
+ if (levelSelector.getSelectedOption() > levelSelector.getUnlockedCount() || trackSelector.getSelectedOption() > trackSelector.getUnlockedCount() || leagueSelector.getSelectedOption() > leagueSelector.getUnlockedCount()) {
+ showAlert("GD Classic", getString(R.string.complete_to_unlock), null);
+ return;
+ } else {
+ gd.physEngine._avV();
+ startTrack(levelSelector.getSelectedOption(), trackSelector.getSelectedOption());
+ gd.physEngine.setLeague(leagueSelector.getSelectedOption());
+ m_SZ = true;
+ gd.menuToGame();
+ return;
+ }
+
+ if (item == vibrateOnTouchOptionItem) {
+ Settings.setVibrateOnTouchEnabled(((OptionsMenuElement) item).getSelectedOption() == 0);
+ }
+ if (item == keyboardInMenuOptionItem) {
+ boolean enabled = ((OptionsMenuElement) item).getSelectedOption() == 0;
+ Settings.setKeyboardInMenuEnabled(enabled);
+ if (enabled) gd.showKeyboardLayout();
+ else gd.hideKeyboardLayout();
+ }
+ if (item == perspectiveOptionItem) {
+ gd.physEngine._aZV(perspectiveOptionItem.getSelectedOption() == 0);
+ getLevelLoader().setPerspectiveEnabled(perspectiveOptionItem.getSelectedOption() == 0);
+ Settings.setPerspectiveEnabled(perspectiveOptionItem.getSelectedOption() == 0);
+ return;
+ }
+ if (item == shadowsOptionItem) {
+ getLevelLoader().setShadowsEnabled(shadowsOptionItem.getSelectedOption() == 0);
+ Settings.setShadowsEnabled(shadowsOptionItem.getSelectedOption() == 0);
+ return;
+ }
+ if (item == driverSpriteOptionItem) {
+ if (driverSpriteOptionItem._charvZ()) {
+ driverSpriteOptionItem.setSelectedOption(driverSpriteOptionItem.getSelectedOption() + 1);
+ }
+ Settings.setDriverSpriteEnabled(driverSpriteOptionItem.getSelectedOption() == 0);
+ } else if (item == bikeSpriteOptionItem) {
+ if (bikeSpriteOptionItem._charvZ()) {
+ bikeSpriteOptionItem.setSelectedOption(bikeSpriteOptionItem.getSelectedOption() + 1);
+ }
+ Settings.setBikeSpriteEnabled(bikeSpriteOptionItem.getSelectedOption() == 0);
+ } else {
+ if (item == inputOptionItem) {
+ if (inputOptionItem._charvZ())
+ inputOptionItem.setSelectedOption(inputOptionItem.getSelectedOption() + 1);
+ getGDView().setInputOption(inputOptionItem.getSelectedOption());
+ Settings.setInputOption(inputOptionItem.getSelectedOption());
+ return;
+ }
+ if (item == lookAheadOptionItem) {
+ gd.physEngine._ifZV(lookAheadOptionItem.getSelectedOption() == 0);
+ Settings.setLookAheadEnabled(lookAheadOptionItem.getSelectedOption() == 0);
+ return;
+ }
+ if (item instanceof ActionMenuElement) {
+ if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.RESTART_WITH_NEW_LEVEL) {
+ LevelsManager manager = gd.levelsManager;
+ long nextId = manager.getCurrentId() == 1 ? 2 : 1;
+ gd.levelsManager.load(manager.getLeveL(nextId));
+ }
+ if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.SEND_LOGS) {
+ gd.sendKeyboardLogs();
+ }
+ if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.SELECT_FILE) {
+ installFromFileBrowse();
+ return;
+ }
+ if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.YES) {
+ if (currentMenu == eraseScreen) {
+ getLevelsManager().clearHighScores();
+ showAlert(getString(R.string.cleared), getString(R.string.cleared_text), null);
+ } else if (currentMenu == resetScreen) {
+ showAlert(getString(R.string.reset), getString(R.string.reset_text), new Runnable() {
+ @Override
+ public void run() {
+ resetAll();
+ }
+ });
+ }
+ setCurrentMenu(currentMenu.getNavTarget(), false);
+ return;
+ }
+ if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.NO) {
+ setCurrentMenu(currentMenu.getNavTarget(), false);
+ return;
+ }
+ if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.BACK) {
+ setCurrentMenu(currentMenu.getNavTarget(), true);
+ return;
+ }
+ if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.PLAY_MENU) {
+ levelSelector.setSelectedOption(levelIndex);
+ trackSelector.setUnlockedCount(level.getUnlocked(levelIndex));
+ trackSelector.setSelectedOption(track);
+ setCurrentMenu(currentMenu.getNavTarget(), false);
+ return;
+ }
+ if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.GO_TO_MAIN) {
+ setCurrentMenu(mainMenu, false);
+ return;
+ }
+ if (((ActionMenuElement) item).getActionValue() == ActionMenuElement.EXIT) {
+ getGDActivity().exiting = true;
+ if (currentMenu != null) {
+ setCurrentMenu(currentMenu.getNavTarget(), false);
+ } else {
+ setCurrentMenu(null, false);
+ }
+ return;
+ }
+ }
+
+ if (item == ingameRestartAction || item == finishedRestartAction) {
+ if (leagueSelector.getSelectedOption() <= leagueSelector.getUnlockedCount()) {
+ levelSelector.setSelectedOption(levelIndex);
+ trackSelector.setUnlockedCount(level.getUnlocked(levelIndex));
+ trackSelector.setSelectedOption(track);
+ gd.physEngine.setLeague(leagueSelector.getSelectedOption());
+ m_SZ = true;
+ gd.menuToGame();
+ return;
+ }
+ } else {
+ if (item == nextAction) {
+ // if (!leagueCompleted)
+ // trackSelector.performAction(MenuScreen.KEY_RIGHT);
+ startTrack(levelSelector.getSelectedOption(), trackSelector.getSelectedOption());
+ gd.physEngine.setLeague(leagueSelector.getSelectedOption());
+ // saveAll();
+ // getLevelsManager().updateLevelSettings();
+ m_SZ = true;
+ gd.menuToGame();
+ return;
+ }
+ if (item == continueAction) {
+ // _hvV();
+ gd.menuToGame();
+ return;
+ }
+ if (item == nameAction) {
+ nameScreen.resetCursorPosition();
+ setCurrentMenu(nameScreen, false);
+ return;
+ }
+ if (item instanceof ActionMenuElement && ((ActionMenuElement) item).getActionValue() == ActionMenuElement.OK) {
+ saveCompletedTrack();
+ return;
+ }
+ if (item == trackSelector) {
+ if (trackSelector._charvZ()) {
+ trackSelector.setUnlockedCount(level.getUnlocked(levelSelector.getSelectedOption()));
+ trackSelector.update();
+ trackSelectorCurrentMenu = trackSelector.getCurrentMenu();
+ setCurrentMenu(trackSelectorCurrentMenu, false);
+ // trackSelectorCurrentMenu._doIV(trackSelector.getSelectedOption());
+ }
+ selectedTrack[levelSelector.getSelectedOption()] = trackSelector.getSelectedOption();
+ return;
+ }
+ if (item == levelSelector) {
+ if (levelSelector._charvZ()) {
+ levelSelectorCurrentMenu = levelSelector.getCurrentMenu();
+ setCurrentMenu(levelSelectorCurrentMenu, false);
+ }
+ trackSelector.setOptions(getLevelLoader().names[levelSelector.getSelectedOption()], false);
+ trackSelector.setUnlockedCount(level.getUnlocked(levelSelector.getSelectedOption()));
+ trackSelector.setSelectedOption(selectedTrack[levelSelector.getSelectedOption()]);
+ // trackSelector.update();
+ // logDebug("update tracks ");
+ return;
+ }
+ if (item == leagueSelector && leagueSelector._charvZ()) {
+ leagueSelectorCurrentMenu = leagueSelector.getCurrentMenu();
+ // leagueSelector.update();
+ leagueSelector.setScreen(currentMenu);
+ setCurrentMenu(leagueSelectorCurrentMenu, false);
+ // leagueSelectorCurrentMenu._doIV(leagueSelector.getSelectedOption());
+ }
+ }
+ }
+ }
+
+ protected void startTrack(int levelIndex, int trackIndex) {
+ // ATTENTION!!!
+ // WHEN CHANGING THIS CODE, COPY-PASTE TO saveCompletedTrack() !!!
+
+ if (Global.ACRA_ENABLED) {
+ ACRA.getErrorReporter().putCustomData("level_index:", String.valueOf(levelIndex));
+ ACRA.getErrorReporter().putCustomData("track_index:", String.valueOf(trackIndex));
+ }
+
+ /*Menu _menu = null;
+ _menu.back();*/
+
+ try {
+ getLevelLoader()._doIII(levelIndex, trackIndex);
+ } catch (InvalidTrackException e) {
+ showConfirm(getString(R.string.oops), getString(R.string.e_level_damaged), new Runnable() {
+ @Override
+ public void run() {
+ if (trackSelector.getSelectedOption() + 1 < level.getCount(levelSelector.getSelectedOption())) {
+ trackSelector.setUnlockedCount(trackSelector.getSelectedOption() + 1);
+ level.setUnlocked(levelSelector.getSelectedOption(), trackSelector.getUnlockedCount());
+ } else {
+ switch (levelSelector.getSelectedOption()) {
+ case 0:
+ if (level.getUnlockedLeagues() < 1) {
+ level.setUnlockedLeagues(1);
+ leagueSelector.setUnlockedCount(level.getUnlockedLeagues());
+ }
+ break;
+
+ case 1:
+ if (level.getUnlockedLeagues() < 2) {
+ level.setUnlockedLeagues(2);
+ leagueSelector.setUnlockedCount(level.getUnlockedLeagues());
+ }
+ break;
+
+ case 2:
+ if (level.getUnlockedLeagues() < 3) {
+ level.setUnlockedLeagues(3);
+ leagueSelector.setOptions(fullLeaguesList);
+ leagues = fullLeaguesList;
+ leagueSelector.setUnlockedCount(level.getUnlockedLeagues());
+ }
+ break;
+ }
+
+ int newUnlocked = level.getUnlocked(levelSelector.getSelectedOption()) + 1,
+ tracksCount = level.getCount(levelSelector.getSelectedOption());
+
+ if (newUnlocked > tracksCount)
+ newUnlocked = tracksCount;
+
+ levelSelector.setUnlockedCount(levelSelector.getUnlockedCount() + 1);
+ level.setUnlocked(levelSelector.getSelectedOption(), newUnlocked);
+ }
+ }
+ }, null);
+ }
+ }
+
+ public int _jvI() {
+ int k = 0;
+ if (driverSpriteOptionItem.getSelectedOption() == 0)
+ k |= 2;
+ if (bikeSpriteOptionItem.getSelectedOption() == 0)
+ k |= 1;
+ return k;
+ }
+
+ public void _intIV(int k) {
+ bikeSpriteOptionItem.setSelectedOption(1);
+ driverSpriteOptionItem.setSelectedOption(1);
+ if ((k & 1) > 0)
+ bikeSpriteOptionItem.setSelectedOption(0);
+ if ((k & 2) > 0)
+ driverSpriteOptionItem.setSelectedOption(0);
+ }
+
+ /*public int _ovI() {
+ return levelSelector.getSelectedOption();
+ }
+
+ public int _nvI() {
+ return trackSelector.getSelectedOption();
+ }
+
+ public int _lvI() {
+ return leagueSelector.getSelectedOption();
+ }*/
+
+ public void setLastTrackTime(long l) {
+ lastTrackTime = l;
+ }
+
+ /*private byte[] readNameChars(int pos, byte defaultValue) {
+ switch (pos) {
+ case 16: // '\020'
+ byte[] abyte0 = new byte[3];
+ for (int l = 0; l < 3; l++)
+ abyte0[l] = settings[16 + l];
+
+ if (abyte0[0] == -127)
+ abyte0[0] = defaultValue;
+ return abyte0;
+ }
+ return null;
+ }
+
+ private byte readSetting(int index, byte defaultValue) {
+ if (settings[index] == -127)
+ return defaultValue;
+ else
+ return settings[index];
+ }
+
+ private void saveNameChars(int pos, byte[] chars) {
+ if (settingsLoadedOK && pos == 16) {
+ for (int l = 0; l < 3; l++)
+ settings[16 + l] = chars[l];
+
+ }
+ }*/
+
+ private String getDurationString(long l) {
+ m_ajI = (int) (l / 100L);
+ m_atI = (int) (l % 100L);
+ String s;
+ if (m_ajI / 60 < 10)
+ s = " 0" + m_ajI / 60;
+ else
+ s = " " + m_ajI / 60;
+ if (m_ajI % 60 < 10)
+ s = s + ":0" + m_ajI % 60;
+ else
+ s = s + ":" + m_ajI % 60;
+ if (m_atI < 10)
+ s = s + ".0" + m_atI;
+ else
+ s = s + "." + m_atI;
+ return s;
+ }
+
+ /*private void setSetting(int k, byte byte0) {
+ if (settingsLoadedOK)
+ settings[k] = byte0;
+ }*/
+
+ private void resetAll() {
+ Settings.resetAll();
+ getLevelsManager().resetAllLevelsSettings();
+ getLevelsManager().clearAllHighScores();
+
+ getGDActivity().fullResetting = true;
+ getGDActivity().destroyApp(true);
+ }
+
+ public void removeCommands() {
+ getGDView().removeCommand(okCommand);
+ getGDView().removeCommand(backCommand);
+ }
+
+ public void addCommands() {
+ if (currentMenu != mainMenu && currentMenu != finishedMenu && currentMenu != null)
+ getGDView().addCommand(backCommand);
+ getGDView().addCommand(okCommand);
+ }
+
+ /*private int _bbII(int k) {
+ String[] as = RecordStore.listRecordStores();
+ if (saveManager == null || as == null)
+ return 0;
+ int l = 0;
+ for (int i1 = 0; i1 < as.length; i1++)
+ if (as[i1].startsWith("" + k))
+ l++;
+
+ return l;
+ }*/
+
+ /*public boolean isKeyboardEnabled() {
+ return keyboardInMenuEnabled == 0;
+ }*/
+
+ // public boolean isVibrateOnTouchEnabled() {
+ // return vibrateOnTouchEnabled == 0;
+ //}
+
+ /*public void hideKeyboard(boolean firstRun) {
+ if (!Settings.isKeyboardInMenuEnabled()) {
+ getGDActivity().hideKeyboardLayout();
+ // MenuScreen.setSize(getGDView().getScaledWidth(), getGDView().getScaledHeight());
+ } else if (firstRun) {
+ getGDActivity().showKeyboardLayout();
+ }*//*else {
+ // MenuScreen.setSize(getGDView().getScaledWidth(), getGDView().getScaledHeight() - getGDActivity().getButtonsLayoutHeight());
+ }*//*
+ }
+
+ public void showKeyboard() {
+ getGDActivity().showKeyboardLayout();
+ // MenuScreen.setSize(getGDView().getScaledWidth(), getGDView().getScaledHeight() - getGDActivity().getButtonsLayoutHeight());
+ }*/
+
+ public void installFromFileBrowse() {
+ if (!LevelsManager.isExternalStorageReadable()) {
+ showAlert(getString(R.string.error), getString(R.string.e_external_storage_is_not_readable), null);
+ return;
+ }
+
+ final GDActivity gd = getGDActivity();
+ FileDialog fileDialog = new FileDialog(gd, Environment.getExternalStorageDirectory(), ".mrg");
+ fileDialog.addFileListener(new FileDialog.FileSelectedListener() {
+ public void fileSelected(final File file) {
+ final EditText input = new EditText(gd);
+ input.setInputType(InputType.TYPE_CLASS_TEXT);
+
+ AlertDialog.Builder alert = new AlertDialog.Builder(gd)
+ .setTitle(getString(R.string.enter_levels_name_title))
+ .setMessage(getString(R.string.enter_levels_name))
+ .setView(input)
+ .setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ boolean ok = true;
+ String name = input.getText().toString();
+ if (name.equals("")) name = file.getName();
+
+ ProgressDialog progressDialog = ProgressDialog.show(gd, getString(R.string.install), getString(R.string.installing), true);
+
+ try {
+ gd.levelsManager.install(file, name, "", 0);
+ } catch (Exception e) {
+ ok = false;
+ e.printStackTrace();
+ showAlert(getString(R.string.error), e.getMessage(), null);
+ } finally {
+ progressDialog.dismiss();
+ }
+
+ if (ok) {
+ gd.levelsManager.showSuccessfullyInstalledDialog();
+ }
+ }
+ })
+ .setNegativeButton(getString(R.string.cancel), null);
+ alert.show();
+ }
+ });
+ fileDialog.showDialog();
+ }
+
+ public static boolean isNameCheat(byte[] chars) {
+ return chars[0] == 82 && chars[1] == 75 && chars[2] == 69;
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/MenuElement.java b/src/org/happysanta/gd/Menu/MenuElement.java
new file mode 100644
index 0000000..82fe490
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/MenuElement.java
@@ -0,0 +1,20 @@
+package org.happysanta.gd.Menu;
+
+import android.view.View;
+
+/**
+ * Author: ch1p
+ */
+public interface MenuElement {
+
+ // public abstract void setText(String s);
+
+ public abstract boolean isSelectable();
+
+ public abstract View getView();
+
+ public abstract void setText(String text);
+
+ public void performAction(int k);
+
+}
diff --git a/src/org/happysanta/gd/Menu/MenuElementOld.java b/src/org/happysanta/gd/Menu/MenuElementOld.java
new file mode 100755
index 0000000..6a4400f
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/MenuElementOld.java
@@ -0,0 +1,32 @@
+package org.happysanta.gd.Menu;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.view.View;
+
+public interface MenuElementOld {
+
+ public abstract void setText(String s);
+
+ // Why y before x?!
+ public abstract void draw(Canvas g, int y, int x);
+
+ public abstract boolean isSelectable();
+
+ public abstract int getLineSpacing();
+
+ public abstract void performAction(int i);
+
+ public abstract void setFont(Paint font);
+
+ public abstract int getHeight();
+
+ public abstract int getFirstLineHeight();
+
+ public abstract int getXOffset();
+
+ public abstract void setPressed(boolean flag);
+
+ public abstract View getView();
+
+}
diff --git a/src/org/happysanta/gd/Menu/MenuHandler.java b/src/org/happysanta/gd/Menu/MenuHandler.java
new file mode 100755
index 0000000..208e579
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/MenuHandler.java
@@ -0,0 +1,12 @@
+package org.happysanta.gd.Menu;
+
+public interface MenuHandler {
+
+ public abstract MenuScreen getCurrentMenu();
+
+ public abstract void setCurrentMenu(MenuScreen e, boolean flag);
+
+ // public abstract void destroy();
+
+ public abstract void handleAction(MenuElement item);
+}
diff --git a/src/org/happysanta/gd/Menu/MenuScreen.java b/src/org/happysanta/gd/Menu/MenuScreen.java
new file mode 100755
index 0000000..c49c085
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/MenuScreen.java
@@ -0,0 +1,277 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.view.ViewTreeObserver;
+import android.widget.LinearLayout;
+import org.happysanta.gd.GDActivity;
+import org.happysanta.gd.Menu.Views.MenuLinearLayout;
+
+import java.util.Vector;
+
+import static org.happysanta.gd.Helpers.getDp;
+import static org.happysanta.gd.Helpers.getGDActivity;
+import static org.happysanta.gd.Helpers.isSDK11OrHigher;
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class MenuScreen
+ implements OnMenuElementHighlightListener {
+
+ public static final int KEY_FIRE = 5;
+ public static final int KEY_UP = 2;
+ public static final int KEY_DOWN = 8;
+ public static final int KEY_LEFT = 4;
+ public static final int KEY_RIGHT = 6;
+
+ protected static final int LAYOUT_LEFT_PADDING = 30;
+ protected static final int LAYOUT_TOP_PADDING = 0;
+ protected static final int LAYOUT_BOTTOM_PADDING = 15;
+
+ protected MenuScreen navTarget;
+ protected String title;
+ protected int selectedIndex;
+ protected Vector menuItems;
+ protected MenuLinearLayout layout;
+ protected ClickableMenuElement lastHighlighted;
+ protected boolean isTextScreen = false;
+
+ public MenuScreen(String title, MenuScreen navTarget) {
+ this.title = title;
+ selectedIndex = -1;
+ menuItems = new Vector();
+ this.navTarget = navTarget;
+
+ Context context = getGDActivity();
+
+ layout = new MenuLinearLayout(context);
+ layout.setOrientation(LinearLayout.VERTICAL);
+ layout.setPadding(getDp(LAYOUT_LEFT_PADDING), getDp(LAYOUT_TOP_PADDING), getDp(LAYOUT_LEFT_PADDING), getDp(LAYOUT_BOTTOM_PADDING));
+
+ // Disable multi-touch in menu
+ if (isSDK11OrHigher())
+ layout.setMotionEventSplittingEnabled(false);
+ }
+
+ public void addItem(MenuElement item) {
+ layout.addView(item.getView());
+ menuItems.add(item);
+
+ if (item instanceof ClickableMenuElement)
+ ((ClickableMenuElement) item).setOnHighlightListener(this);
+ }
+
+ protected void scrollToItem(MenuElement item) {
+ // int y = item.getView().getTop();
+ // logDebug("scrollTo: y = " + y);
+
+ // getGameMenu().scrollTo(y);
+ getGDActivity().scrollToView(item.getView());
+ }
+
+ public void performAction(int k) {
+ // logDebug("MenuScreen.performAction: k = " + k);
+ int from = 0;
+ switch (k) {
+ default:
+ // logDebug("selectedIndex = " + selectedIndex);
+ if (selectedIndex != -1) {
+ for (int i = selectedIndex; i < menuItems.size(); i++) {
+ MenuElement item;
+ if ((item = (MenuElement) menuItems.elementAt(i)) != null && item.isSelectable()) {
+ item.performAction(k);
+ return;
+ }
+ }
+ }
+ break;
+
+ case KEY_UP:
+ if (isTextScreen) {
+ getGDActivity().scrollTextMenuUp();
+ return;
+ }
+
+ if (selectedIndex > 0 && !elementIsFirstClickable(selectedIndex)) {
+ from = selectedIndex - 1;
+ } else {
+ from = menuItems.size() - 1;
+ }
+
+ for (int i = from; i >= 0; i--) {
+ MenuElement el = (MenuElement) menuItems.elementAt(i);
+ if (!(el instanceof ClickableMenuElement) || ((ClickableMenuElement) el).isDisabled()) {
+ continue;
+ }
+
+ highlightElement((ClickableMenuElement) el);
+ selectedIndex = i;
+ scrollToItem(el);
+ break;
+ }
+ break;
+
+ case KEY_DOWN:
+ if (isTextScreen) {
+ getGDActivity().scrollTextMenuDown();
+ return;
+ }
+
+ if (selectedIndex < menuItems.size() - 1) {
+ from = selectedIndex + 1;
+ } else {
+ from = 0;
+ }
+ for (int i = from; i < menuItems.size(); i++) {
+ MenuElement el = (MenuElement) menuItems.elementAt(i);
+ if (!(el instanceof ClickableMenuElement) || ((ClickableMenuElement) el).isDisabled()) {
+ continue;
+ }
+
+ highlightElement((ClickableMenuElement) el);
+ selectedIndex = i;
+ scrollToItem(el);
+ break;
+ }
+ break;
+ }
+ }
+
+ protected boolean elementIsFirstClickable(int index) {
+ for (int i = 0; i < menuItems.size(); i++) {
+ MenuElement el = (MenuElement) menuItems.elementAt(i);
+ if (!(el instanceof ClickableMenuElement) || ((ClickableMenuElement) el).isDisabled()) {
+ if (i == index) {
+ return false;
+ }
+ } else {
+ if (i < index) return false;
+ if (i == index) return true;
+ }
+ }
+
+ return false;
+ }
+
+ public MenuScreen getNavTarget() {
+ return navTarget;
+ }
+
+ public void setNavTarget(MenuScreen target) {
+ navTarget = target;
+ }
+
+ /*public void setIsLevelsList(boolean is) {
+ isLevelsList = is;
+ }*/
+
+ public void clear() {
+ menuItems.removeAllElements();
+ layout.removeAllViews();
+
+ selectedIndex = -1;
+ lastHighlighted = null;
+ }
+
+ public LinearLayout getLayout() {
+ return layout;
+ }
+
+ protected void setTitle(String s) {
+ title = s;
+ }
+
+ protected void updateTitle() {
+ final GDActivity gd = getGDActivity();
+ gd.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ gd.menuTitleTextView.setText(title);
+ // activity.menuTitleTextView.invalidate();
+ gd.titleLayout.invalidate();
+ }
+ });
+ }
+
+ public void onHide(MenuScreen newMenu) {
+ }
+
+ public void onShow() {
+ updateTitle();
+ highlightElement();
+ }
+
+ public void resetHighlighted() {
+ lastHighlighted = null;
+ }
+
+ public void highlightElement() {
+ if (lastHighlighted != null) {
+ lastHighlighted.showHelmet();
+ final ViewTreeObserver obs = layout.getViewTreeObserver();
+ obs.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
+ @Override
+ public boolean onPreDraw() {
+ try {
+ obs.removeOnPreDrawListener(this);
+ scrollToItem(lastHighlighted);
+ } catch (Exception e) {
+ }
+
+ return true;
+ }
+ });
+ } else {
+ for (int i = 0; i < menuItems.size(); i++) {
+ if (menuItems.elementAt(i) instanceof ClickableMenuElement) {
+ ClickableMenuElement item = (ClickableMenuElement) menuItems.elementAt(i);
+ if (item.isDisabled()) continue;
+
+ highlightElement(item);
+ scrollToItem(lastHighlighted);
+ selectedIndex = i;
+
+ break;
+ }
+ }
+ }
+ }
+
+ public void setSelected(int index) {
+ try {
+ if (menuItems.elementAt(index) instanceof ClickableMenuElement) {
+ ClickableMenuElement item = (ClickableMenuElement) menuItems.elementAt(index);
+ if (item.isDisabled()) return;
+
+ highlightElement(item);
+ selectedIndex = index;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void highlightElement(ClickableMenuElement el) {
+ el.showHelmet();
+ lastHighlighted = el;
+ }
+
+ public void onScroll(double percent) {
+ }
+
+ @Override
+ public void onElementHighlight(ClickableMenuElement el) {
+ lastHighlighted = el;
+
+ int index = menuItems.indexOf(el);
+ if (index != -1)
+ selectedIndex = index;
+ }
+
+ public void setIsTextScreen(boolean isTextScreen) {
+ this.isTextScreen = isTextScreen;
+ }
+
+ /*public boolean isTextScreen() {
+ return isTextScreen;
+ }*/
+
+}
diff --git a/src/org/happysanta/gd/Menu/NameInputMenuScreen.java b/src/org/happysanta/gd/Menu/NameInputMenuScreen.java
new file mode 100644
index 0000000..e742c7c
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/NameInputMenuScreen.java
@@ -0,0 +1,175 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Menu.Views.MenuLinearLayout;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+
+import static org.happysanta.gd.Helpers.getDp;
+import static org.happysanta.gd.Helpers.getGDActivity;
+import static org.happysanta.gd.Helpers.getGameMenu;
+
+public class NameInputMenuScreen extends MenuScreen {
+
+ protected static final String CURSOR = "^";
+ protected static final int WORD_SPACE = 3;
+
+ protected static int wordWidth = 0;
+
+ protected int cursorPosition = 0;
+ protected byte chars[];
+
+ protected MenuTextView nameTextViews[];
+ protected MenuTextView cursorTextViews[];
+ protected MenuLinearLayout nameLayout;
+ protected MenuLinearLayout cursorLayout;
+
+ static {
+ wordWidth = getWordWidth();
+ }
+
+ public NameInputMenuScreen(String title, MenuScreen navTarget, byte nameChars[]) {
+ super(title, navTarget);
+
+ chars = nameChars;
+
+ Context context = getGDActivity();
+
+ nameTextViews = new MenuTextView[3];
+ cursorTextViews = new MenuTextView[3];
+
+ nameLayout = new MenuLinearLayout(context);
+ nameLayout.setOrientation(LinearLayout.HORIZONTAL);
+
+ cursorLayout = new MenuLinearLayout(context);
+ cursorLayout.setOrientation(LinearLayout.HORIZONTAL);
+
+ for (int i = 0; i < 3; i++) {
+ nameTextViews[i] = createTextView();
+ nameLayout.addView(nameTextViews[i]);
+
+ cursorTextViews[i] = createTextView();
+ cursorLayout.addView(cursorTextViews[i]);
+ }
+
+ layout.addView(nameLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+ layout.addView(cursorLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+
+ updateText();
+ updateCursorPosition();
+ }
+
+ protected MenuTextView createTextView() {
+ Context context = getGDActivity();
+ MenuTextView textView = new MenuTextView(context);
+ textView.setTextColor(0xff000000);
+ textView.setTypeface(Global.robotoCondensedTypeface);
+ textView.setTextSize(ClickableMenuElement.TEXT_SIZE);
+ textView.setLayoutParams(new LinearLayout.LayoutParams(
+ wordWidth,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ));
+ return textView;
+ }
+
+ protected static int getWordWidth() {
+ Context context = getGDActivity();
+
+ String text = "W";
+ TextView textView = new TextView(context);
+ textView.setTextSize(ClickableMenuElement.TEXT_SIZE);
+ textView.setTypeface(Global.robotoCondensedTypeface);
+
+ Rect bounds = new Rect();
+
+ Paint textPaint = textView.getPaint();
+ textPaint.getTextBounds(text, 0, text.length(), bounds);
+
+ return bounds.width() + getDp(WORD_SPACE);
+ }
+
+ @Override
+ public void performAction(int k) {
+ switch (k) {
+ default:
+ break;
+
+ case MenuScreen.KEY_FIRE: // select
+ if (cursorPosition == 2) {
+ getGameMenu().setCurrentMenu(navTarget, false);
+ } else {
+ cursorPosition++;
+ updateCursorPosition();
+ }
+ break;
+
+ case MenuScreen.KEY_RIGHT: // right
+ cursorPosition++;
+ if (cursorPosition > 2) {
+ cursorPosition = 2;
+ }
+ updateCursorPosition();
+ break;
+
+ case MenuScreen.KEY_LEFT: // left
+ cursorPosition--;
+ if (cursorPosition < 0)
+ cursorPosition = 0;
+ updateCursorPosition();
+ break;
+
+ case MenuScreen.KEY_UP: // up
+ if (chars[cursorPosition] == 32) {
+ chars[cursorPosition] = 65;
+ updateText();
+ break;
+ }
+ chars[cursorPosition]++;
+ if (chars[cursorPosition] > 90) {
+ chars[cursorPosition] = 32;
+ }
+ updateText();
+ break;
+
+ case MenuScreen.KEY_DOWN: // down
+ if (chars[cursorPosition] == 32) {
+ chars[cursorPosition] = 90;
+ updateText();
+ break;
+ }
+ chars[cursorPosition]--;
+ if (chars[cursorPosition] < 65) {
+ chars[cursorPosition] = 32;
+ }
+ updateText();
+ break;
+ }
+ }
+
+ protected void updateText() {
+ for (int i = 0; i < nameTextViews.length; i++) {
+ nameTextViews[i].setTextOnUiThread(String.valueOf((char) chars[i]));
+ }
+ }
+
+ protected void updateCursorPosition() {
+ for (int i = 0; i < cursorTextViews.length; i++) {
+ cursorTextViews[i].setTextOnUiThread(i == cursorPosition ? CURSOR : "");
+ }
+ }
+
+ public byte[] getChars() {
+ return chars;
+ }
+
+ public void resetCursorPosition() {
+ cursorPosition = 0;
+ updateCursorPosition();
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java b/src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java
new file mode 100644
index 0000000..f065bf1
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java
@@ -0,0 +1,10 @@
+package org.happysanta.gd.Menu;
+
+/**
+ * Author: ch1p
+ */
+public interface OnMenuElementHighlightListener {
+
+ public abstract void onElementHighlight(ClickableMenuElement el);
+
+}
diff --git a/src/org/happysanta/gd/Menu/OptionsMenuElement.java b/src/org/happysanta/gd/Menu/OptionsMenuElement.java
new file mode 100644
index 0000000..2119b32
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/OptionsMenuElement.java
@@ -0,0 +1,301 @@
+package org.happysanta.gd.Menu;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Menu.Views.MenuImageView;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+import org.happysanta.gd.R;
+// import com.grishka.agdtr.R;
+
+import static org.happysanta.gd.Helpers.getDp;
+import static org.happysanta.gd.Helpers.getGDActivity;
+import static org.happysanta.gd.Helpers.getString;
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class OptionsMenuElement
+ extends ClickableMenuElement
+ implements MenuElement, MenuHandler {
+
+ protected int selectedIndex;
+ protected String options[];
+ protected int unlockedCount;
+ protected MenuHandler handler;
+ protected MenuScreen optionsScreen = null;
+ protected MenuScreen screen = null;
+ protected boolean isOnOffToggle;
+ protected boolean m_oZ = false;
+ protected String selectedOption;
+ protected ActionMenuElement optionsScreenItems[] = null;
+ protected MenuImageView lockImage = null;
+ protected MenuTextView optionTextView = null;
+
+ public OptionsMenuElement(String text, int selectedIndex, MenuHandler handler, String options[], boolean isOnOffToggle, MenuScreen screen) {
+ this.text = text;
+ this.selectedIndex = selectedIndex;
+ this.handler = handler;
+ this.options = options;
+ if (this.options == null) this.options = new String[]{""};
+ unlockedCount = this.options.length - 1;
+ this.isOnOffToggle = isOnOffToggle;
+
+ createAllViews();
+ setSelectedOption(selectedIndex);
+
+ if (isOnOffToggle) {
+ if (selectedIndex == 1) {
+ selectedOption = getString(R.string.off);
+ } else {
+ selectedOption = getString(R.string.on);
+ }
+ } else {
+ this.screen = screen;
+ updateSelectedOption();
+ update();
+ }
+ }
+
+ @Override
+ protected void createAllViews() {
+ Context context = getGDActivity();
+
+ super.createAllViews();
+
+ textView.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ));
+
+ optionTextView = new MenuTextView(context);
+ optionTextView.setText(selectedOption);
+ optionTextView.setTextColor(getMenuTextView().getTextColors());
+ optionTextView.setTextSize(TEXT_SIZE);
+ optionTextView.setTypeface(Global.robotoCondensedTypeface);
+ optionTextView.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.WRAP_CONTENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ));
+ optionTextView.setPadding(
+ textView.getPaddingLeft(),
+ textView.getPaddingTop(),
+ textView.getPaddingRight(),
+ textView.getPaddingBottom()
+ );
+
+ lockImage = new MenuImageView(context);
+ lockImage.setImageResource(ActionMenuElement.locks[0]);
+ lockImage.setScaleType(ImageView.ScaleType.CENTER);
+ lockImage.setVisibility(View.GONE);
+
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
+ lp.setMargins(0, 0, getDp(ActionMenuElement.LOCK_IMAGE_MARGIN_RIGHT), 0);
+ lockImage.setLayoutParams(lp);
+ lockImage.setVisibility(View.GONE);
+
+ layout.addView(lockImage);
+ layout.addView(optionTextView);
+ }
+
+ private void updateSelectedOption() {
+ selectedOption = options[selectedIndex];
+ updateViewText();
+
+ if (selectedIndex > unlockedCount && !isOnOffToggle) {
+ lockImage.setVisibility(View.VISIBLE);
+ } else {
+ lockImage.setVisibility(View.GONE);
+ }
+ }
+
+ public int getUnlockedCount() {
+ return unlockedCount;
+ }
+
+ public void setUnlockedCount(int k) {
+ unlockedCount = k;
+ if (unlockedCount > options.length - 1)
+ unlockedCount = options.length - 1;
+ if (optionsScreen != null) {
+ for (int l = 0; l < optionsScreenItems.length; l++)
+ if (l > k)
+ optionsScreenItems[l].setLock(true, true);
+ else
+ optionsScreenItems[l].setLock(false, false);
+ }
+ updateSelectedOption();
+ }
+
+ public int getOptionCount() {
+ return options.length - 1;
+ }
+
+ public String[] getOptions() {
+ return options;
+ }
+
+ public void setOptions(String as[]) {
+ setOptions(as, true);
+ }
+
+ public void setOptions(String as[], boolean update) {
+ options = as;
+ if (selectedIndex > options.length - 1)
+ selectedIndex = options.length - 1;
+ if (unlockedCount > options.length - 1)
+ unlockedCount = options.length - 1;
+ updateSelectedOption();
+ if (update) update();
+ }
+
+ public int getSelectedOption() {
+ return selectedIndex;
+ }
+
+ public void setSelectedOption(int k) {
+ selectedIndex = k;
+ if (selectedIndex > options.length - 1)
+ selectedIndex = 0;
+ if (selectedIndex < 0)
+ selectedIndex = options.length - 1;
+ updateSelectedOption();
+ }
+
+ public void update() {
+ optionsScreen = new MenuScreen(text, screen);
+ optionsScreenItems = new ActionMenuElement[options.length];
+ for (int k = 0; k < optionsScreenItems.length; k++) {
+ if (k > unlockedCount) {
+ optionsScreenItems[k] = new ActionMenuElement(options[k], this);
+ optionsScreenItems[k].setLock(true, true);
+ } else {
+ optionsScreenItems[k] = new ActionMenuElement(options[k], this);
+ }
+ optionsScreen.addItem(optionsScreenItems[k]);
+ }
+ optionsScreen.setSelected(selectedIndex);
+
+ // System.gc();
+ }
+
+ public boolean _charvZ() {
+ if (m_oZ) {
+ m_oZ = false;
+ return true;
+ } else {
+ return m_oZ;
+ }
+ }
+
+ @Override
+ public void handleAction(MenuElement item) {
+ int k = 0;
+ do {
+ if (k >= optionsScreenItems.length)
+ break;
+ if (item == optionsScreenItems[k]) {
+ selectedIndex = k;
+ updateSelectedOption();
+ break;
+ }
+ k++;
+ } while (true);
+
+ handler.setCurrentMenu(screen, true);
+ handler.handleAction(this);
+ }
+
+ @Override
+ public MenuScreen getCurrentMenu() {
+ return optionsScreen;
+ }
+
+ @Override
+ public void setCurrentMenu(MenuScreen e1, boolean flag) {
+ }
+
+ @Override
+ protected void updateViewText() {
+ if (textView != null && textView instanceof MenuTextView)
+ ((MenuTextView) textView).setTextOnUiThread(getTextForView());
+ if (optionTextView != null) optionTextView.setTextOnUiThread(selectedOption);
+ }
+
+ @Override
+ public void performAction(int k) {
+ // logDebug("OptionMenuElement performAction: k = " + k);
+ switch (k) {
+ case MenuScreen.KEY_FIRE:
+ if (isOnOffToggle) {
+ selectedIndex++;
+ if (selectedIndex > 1)
+ selectedIndex = 0;
+ if (selectedIndex == 1)
+ selectedOption = getString(R.string.off);
+ else
+ selectedOption = getString(R.string.on);
+ updateViewText();
+ handler.handleAction(this);
+ return;
+ } else {
+ m_oZ = true;
+ handler.handleAction(this);
+ return;
+ }
+
+ case MenuScreen.KEY_RIGHT:
+ if (isOnOffToggle) {
+ if (selectedIndex == 1) {
+ selectedIndex = 0;
+ selectedOption = getString(R.string.on);
+ handler.handleAction(this);
+ updateViewText();
+ }
+ return;
+ }
+ selectedIndex++;
+ if (selectedIndex > options.length - 1)
+ selectedIndex = options.length - 1;
+ else
+ handler.handleAction(this);
+ updateSelectedOption();
+ return;
+
+ case MenuScreen.KEY_LEFT: // '\003'
+ if (isOnOffToggle) {
+ if (selectedIndex == 0) {
+ selectedIndex = 1;
+ selectedOption = getString(R.string.off);
+ handler.handleAction(this);
+ updateViewText();
+ }
+ return;
+ }
+ selectedIndex--;
+ if (selectedIndex < 0) {
+ selectedIndex = 0;
+ } else {
+ updateSelectedOption();
+ handler.handleAction(this);
+ }
+ updateSelectedOption();
+ break;
+ }
+ }
+
+ public void setScreen(MenuScreen screen) {
+ this.screen = screen;
+ }
+
+ @Override
+ protected String getTextForView() {
+ return text + ": ";
+ }
+
+ @Override
+ protected void onHighlightChanged() {
+ lockImage.setImageResource(ActionMenuElement.locks[isHighlighted ? 2 : 0]);
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/SimpleMenuElement.java b/src/org/happysanta/gd/Menu/SimpleMenuElement.java
new file mode 100755
index 0000000..57842f5
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/SimpleMenuElement.java
@@ -0,0 +1,176 @@
+package org.happysanta.gd.Menu;
+
+// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.kpdus.com/jad.html
+// Decompiler options: packimports(3) fieldsfirst ansi
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.view.View;
+import android.view.ViewGroup;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+
+import java.util.TimerTask;
+
+import static org.happysanta.gd.Helpers.getGDActivity;
+import static org.happysanta.gd.Helpers.getGDView;
+
+public class SimpleMenuElement extends TimerTask
+ implements MenuElementOld {
+
+ // public static final int LINE_SPACING = 15;
+ protected static Paint gFont;
+
+ public int x;
+ public int y;
+ public int m_bI;
+ public int m_eI;
+ public int m_dI;
+ public int m_gotoI;
+ public int m_nullI;
+ public int m_longI;
+ public int m_fI;
+ int m_cI;
+ // GDActivity activity;
+ protected String text;
+ protected MenuScreen m_we;
+ protected MenuHandler m_hc;
+ protected Paint font;
+ protected boolean isPressed = false;
+ protected MenuTextView textView;
+
+ /*static {
+ gFont = ActionMenuElement.getGFont();
+ }*/
+
+ public SimpleMenuElement() {
+ init();
+ }
+
+ public SimpleMenuElement(int k) {
+ m_cI = k;
+ font = gFont;
+ }
+
+ public SimpleMenuElement(String s, MenuScreen e1, MenuHandler c1) {
+ text = s + ">";
+ m_we = e1;
+ m_hc = c1;
+ font = gFont;
+
+ textView = new MenuTextView(getGDActivity());
+ textView.setText(text);
+ textView.setTextColor(0xff000000);
+ // textView.setTextColor(R.drawable.menu_item_color);
+ textView.setTypeface(Global.robotoCondensedTypeface);
+ textView.setTextSize(20);
+ textView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ));
+ }
+
+ public void init() {
+ x = y = m_bI = 0;
+ m_eI = m_dI = m_gotoI = 0;
+ m_nullI = m_longI = m_fI = 0;
+ }
+
+ @Override
+ public View getView() {
+ return textView;
+ }
+
+ @Override
+ public void run() {
+ getGDView()._tryIV(m_cI);
+ }
+
+ @Override
+ public void setText(String s) {
+ text = s + ">";
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ @Override
+ public boolean isSelectable() {
+ return true;
+ }
+
+ @Override
+ public void performAction(int k) {
+ /*switch (k) {
+ case MenuScreen.KEY_FIRE:
+ case MenuScreen.KEY_RIGHT:
+ m_hc.handleAction(this);
+ m_we.setNavTarget(m_hc.getCurrentMenu());
+ m_hc.setCurrentMenu(m_we, false);
+ // fall through
+
+ case 3: // '\003'
+ default:
+ return;
+ }*/
+ }
+
+ /* public void _aeV(MenuScreen e1) {
+ screen = e1;
+ } */
+
+ @Override
+ public void draw(Canvas g, int y, int x) {
+ // if (isPressed)
+ // setPressedColor();
+ g.drawText(text, x, y - font.ascent(), font);
+ // if (isPressed)
+ // setNormalColor();
+ }
+
+ @Override
+ public int getLineSpacing() {
+ return ActionMenuElement.LINE_SPACING;
+ }
+
+ @Override
+ public void setFont(Paint font) {
+ this.font = font;
+ }
+
+ @Override
+ public int getHeight() {
+ return Math.round(font.descent() - font.ascent());
+ }
+
+ @Override
+ public int getFirstLineHeight() {
+ return getHeight();
+ }
+
+ /* @Override
+ public int getHeight() {
+ return getHeight() + getLineSpacing();
+ } */
+
+ @Override
+ public int getXOffset() {
+ return ActionMenuElement.X_OFFSET;
+ }
+
+ @Override
+ public void setPressed(boolean flag) {
+ isPressed = flag;
+ }
+
+ /*protected void setPressedColor() {
+ font.setColor(ActionMenuElement.PRESSED_COLOR);
+ }
+
+ protected void setNormalColor() {
+ font.setColor(ActionMenuElement.NORMAL_COLOR);
+ }*/
+
+}
diff --git a/src/org/happysanta/gd/Menu/SimpleMenuElementNew.java b/src/org/happysanta/gd/Menu/SimpleMenuElementNew.java
new file mode 100644
index 0000000..474a6ad
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/SimpleMenuElementNew.java
@@ -0,0 +1,77 @@
+package org.happysanta.gd.Menu;
+
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class SimpleMenuElementNew extends ClickableMenuElement
+ implements MenuElement {
+
+ // protected static Paint gFont;
+
+ public int x;
+ public int y;
+ /* public int m_bI;
+ public int m_eI;
+ public int m_dI;
+ public int m_gotoI;
+ public int m_nullI;
+ public int m_longI;
+ public int m_fI;
+ int m_cI; */
+ protected MenuScreen screen;
+ protected MenuHandler handler;
+ // protected Paint font;
+ // protected boolean isPressed = false;
+
+ /* static {
+ gFont = ActionMenuElement.getGFont();
+ } */
+
+ /* public SimpleMenuElementNew() {
+ init();
+ }
+
+ public SimpleMenuElementNew(int k) {
+ m_cI = k;
+ // font = gFont;
+ } */
+
+ public SimpleMenuElementNew(String text, MenuScreen screen, MenuHandler handler) {
+ this.text = text + ">";
+ this.screen = screen;
+ this.handler = handler;
+
+ createAllViews();
+
+ // textView = createAllViews();
+ }
+
+ /* public void init() {
+ x = y = m_bI = 0;
+ m_eI = m_dI = m_gotoI = 0;
+ m_nullI = m_longI = m_fI = 0;
+ } */
+
+ @Override
+ public void setText(String s) {
+ super.setText(s + ">");
+ }
+
+ // @Override
+ public void performAction(int k) {
+ logDebug("SimpleMenuElementNew performAction k = " + k);
+
+ switch (k) {
+ case MenuScreen.KEY_FIRE:
+ case MenuScreen.KEY_RIGHT:
+ handler.handleAction(this);
+ screen.setNavTarget(handler.getCurrentMenu());
+ handler.setCurrentMenu(screen, false);
+ break;
+ }
+ }
+
+ /* public void _aeV(MenuScreen e1) {
+ screen = e1;
+ } */
+
+}
diff --git a/src/org/happysanta/gd/Menu/TextMenuElement.java b/src/org/happysanta/gd/Menu/TextMenuElement.java
new file mode 100755
index 0000000..7485389
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/TextMenuElement.java
@@ -0,0 +1,80 @@
+package org.happysanta.gd.Menu;
+
+// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov.
+// Jad home page: http://www.kpdus.com/jad.html
+// Decompiler options: packimports(3) fieldsfirst ansi
+
+import android.content.Context;
+import android.text.Html;
+import android.text.Spanned;
+import android.text.SpannedString;
+import android.text.util.Linkify;
+import android.view.View;
+import android.view.ViewGroup;
+import org.happysanta.gd.Menu.Views.MenuTextView;
+
+import static org.happysanta.gd.Helpers.getGDActivity;
+
+public class TextMenuElement
+ implements MenuElement {
+
+ protected static final int TEXT_SIZE = 15;
+ protected static final int TEXT_COLOR = 0xff000000;
+
+ protected Spanned spanned;
+ protected MenuTextView textView;
+
+ public TextMenuElement(String text) {
+ this.spanned = SpannedString.valueOf(text);
+ textView = createTextView();
+ }
+
+ public TextMenuElement(Spanned text) {
+ this.spanned = text;
+ textView = createTextView();
+ }
+
+ protected MenuTextView createTextView() {
+ Context activity = getGDActivity();
+
+ MenuTextView textView = new MenuTextView(activity);
+ textView.setText(spanned);
+ textView.setTextColor(TEXT_COLOR);
+ textView.setTextSize(TEXT_SIZE);
+ textView.setLineSpacing(0f, 1.5f);
+ textView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT
+ ));
+
+ Linkify.addLinks(textView, Linkify.WEB_URLS);
+ textView.setLinksClickable(true);
+
+ return textView;
+ }
+
+ @Override
+ public View getView() {
+ return textView;
+ }
+
+ public String getText() {
+ return spanned.toString();
+ }
+
+ @Override
+ public void setText(String text) {
+ this.spanned = Html.fromHtml(text);
+ textView.setTextOnUiThread(spanned);
+ }
+
+ @Override
+ public boolean isSelectable() {
+ return false;
+ }
+
+ @Override
+ public void performAction(int k) {
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Views/LevelNameLeadingMarginSpan2.java b/src/org/happysanta/gd/Menu/Views/LevelNameLeadingMarginSpan2.java
new file mode 100644
index 0000000..09c744d
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Views/LevelNameLeadingMarginSpan2.java
@@ -0,0 +1,38 @@
+package org.happysanta.gd.Menu.Views;
+
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.text.Layout;
+import android.text.style.LeadingMarginSpan;
+
+public class LevelNameLeadingMarginSpan2 implements LeadingMarginSpan.LeadingMarginSpan2 {
+
+ private int margin;
+ private int lines;
+
+ public LevelNameLeadingMarginSpan2(int lines, int margin) {
+ this.margin = margin;
+ this.lines = lines;
+ }
+
+ @Override
+ public int getLeadingMargin(boolean first) {
+ if (first) {
+ return margin;
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
+ int top, int baseline, int bottom, CharSequence text,
+ int start, int end, boolean first, Layout layout) {
+ }
+
+ @Override
+ public int getLeadingMarginLineCount() {
+ return lines;
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Views/MenuHelmetView.java b/src/org/happysanta/gd/Menu/Views/MenuHelmetView.java
new file mode 100644
index 0000000..bb2a37a
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Views/MenuHelmetView.java
@@ -0,0 +1,111 @@
+package org.happysanta.gd.Menu.Views;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.view.View;
+import org.happysanta.gd.Game.Bitmap;
+import org.happysanta.gd.Global;
+
+import static org.happysanta.gd.Helpers.getDp;
+import static org.happysanta.gd.Helpers.isSDK11OrHigher;
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class MenuHelmetView extends View {
+
+ protected static final int WIDTH = 8;
+ protected static final int HEIGHT = 8;
+ /*protected static final int PADDING_LEFT = 0;
+ protected static final int PADDING_TOP = 5;
+ protected static final int PADDING_RIGHT = 5;
+ protected static final int PADDING_BOTTOM = 0;*/
+
+ protected static int angle = 0;
+ protected static long angleLastMs = 0;
+ protected static final int angleInterval = 50;
+ protected static final int angleDelta = 10;
+
+ protected boolean show = false;
+ protected boolean _setMeasuredHeight = false;
+ protected Bitmap helmet = Bitmap.get(Bitmap.HELMET);
+ protected static MenuHelmetView lastActive = null;
+
+ public static void clearStaticFields() {
+ lastActive = null;
+ angle = 0;
+ angleLastMs = 0;
+ }
+
+ public MenuHelmetView(Context context) {
+ super(context);
+ }
+
+ public MenuHelmetView(Context context, AttributeSet attributeSet) {
+ super(context, attributeSet);
+ }
+
+ @Override
+ public void onDraw(Canvas canvas) {
+ canvas.save();
+ canvas.scale(Global.density, Global.density);
+
+ drawHelmet(canvas);
+
+ canvas.restore();
+ invalidate();
+ }
+
+ protected void drawHelmet(Canvas canvas) {
+ if (show) {
+ long ms = System.currentTimeMillis();
+ if (angleLastMs == 0 || ms - angleLastMs >= angleInterval) {
+ angle += angleDelta;
+ if (angle >= 360) angle -= 360;
+ angleLastMs = ms;
+ }
+
+ int y = getScaledHeight() / 2 - helmet.getHeightDp() / 2;
+
+ canvas.save();
+ canvas.rotate(angle, helmet.getWidthDp() / 2, y + helmet.getHeightDp() / 2);
+ canvas.drawBitmap(helmet.bitmap, new Rect(0, 0, helmet.getWidth(), helmet.getHeight()), new RectF(0, y, helmet.getWidthDp(), y + helmet.getHeightDp()), null);
+ canvas.restore();
+ }
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ int width = MeasureSpec.getSize(getDp(WIDTH * 2.2f));
+ int height = heightMeasureSpec;
+ if (_setMeasuredHeight)
+ height = MeasureSpec.getSize(getDp(HEIGHT * 2.2f));
+ else if (!isSDK11OrHigher()) {
+ height = MeasureSpec.getSize(getDp(HEIGHT * 4.5f));
+ }
+ setMeasuredDimension(width, height);
+ }
+
+ public void setShow(boolean show) {
+ setShow(show, true);
+ }
+
+ public void setShow(boolean show, boolean checkLast) {
+ if (checkLast && lastActive != null) {
+ lastActive.setShow(false, false);
+ }
+ this.show = show;
+ lastActive = this;
+ }
+
+ protected int getScaledHeight() {
+ return Math.round(getHeight() / Global.density);
+ }
+
+ public void setMeasuredHeight(boolean setMeasuredHeight) {
+ this._setMeasuredHeight = setMeasuredHeight;
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Views/MenuImageView.java b/src/org/happysanta/gd/Menu/Views/MenuImageView.java
new file mode 100644
index 0000000..1ef3f70
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Views/MenuImageView.java
@@ -0,0 +1,34 @@
+package org.happysanta.gd.Menu.Views;
+
+import android.content.Context;
+import android.widget.ImageView;
+
+import static org.happysanta.gd.Helpers.runOnUiThread;
+
+public class MenuImageView extends ImageView {
+
+ public MenuImageView(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void setImageResource(final int resid) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuImageView.super.setImageResource(resid);
+ }
+ });
+ }
+
+ @Override
+ public void setVisibility(final int visibility) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuImageView.super.setVisibility(visibility);
+ }
+ });
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Views/MenuLinearLayout.java b/src/org/happysanta/gd/Menu/Views/MenuLinearLayout.java
new file mode 100644
index 0000000..98f665e
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Views/MenuLinearLayout.java
@@ -0,0 +1,68 @@
+package org.happysanta.gd.Menu.Views;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import static org.happysanta.gd.Helpers.runOnUiThread;
+
+public class MenuLinearLayout extends LinearLayout {
+
+ boolean interceptTouchEvents = false;
+
+ public MenuLinearLayout(Context context) {
+ super(context);
+ }
+
+ public MenuLinearLayout(Context context, boolean interceptTouchEvents) {
+ super(context);
+ this.interceptTouchEvents = interceptTouchEvents;
+ }
+
+ @Override
+ public void removeAllViews() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuLinearLayout.super.removeAllViews();
+ }
+ });
+ }
+
+ @Override
+ public void setVisibility(final int visibility) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuLinearLayout.super.setVisibility(visibility);
+ }
+ });
+ }
+
+ @Override
+ public void addView(final View view) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuLinearLayout.super.addView(view);
+ }
+ });
+ }
+
+ @Override
+ public void setPadding(final int left, final int top, final int right, final int bottom) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuLinearLayout.super.setPadding(left, top, right, bottom);
+ }
+ });
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent evt) {
+ return interceptTouchEvents;
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Views/MenuRelativeLayout.java b/src/org/happysanta/gd/Menu/Views/MenuRelativeLayout.java
new file mode 100644
index 0000000..3e5e0d2
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Views/MenuRelativeLayout.java
@@ -0,0 +1,55 @@
+package org.happysanta.gd.Menu.Views;
+
+import android.content.Context;
+import android.view.View;
+import android.widget.RelativeLayout;
+
+import static org.happysanta.gd.Helpers.runOnUiThread;
+
+public class MenuRelativeLayout extends RelativeLayout {
+
+ public MenuRelativeLayout(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void removeAllViews() {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuRelativeLayout.super.removeAllViews();
+ }
+ });
+ }
+
+ @Override
+ public void setVisibility(final int visibility) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuRelativeLayout.super.setVisibility(visibility);
+ }
+ });
+ }
+
+ @Override
+ public void addView(final View view) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuRelativeLayout.super.addView(view);
+ }
+ });
+ }
+
+ @Override
+ public void setPadding(final int left, final int top, final int right, final int bottom) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuRelativeLayout.super.setPadding(left, top, right, bottom);
+ }
+ });
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Views/MenuTextView.java b/src/org/happysanta/gd/Menu/Views/MenuTextView.java
new file mode 100644
index 0000000..4b48f5f
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Views/MenuTextView.java
@@ -0,0 +1,73 @@
+package org.happysanta.gd.Menu.Views;
+
+import android.content.Context;
+import android.graphics.Typeface;
+import android.widget.TextView;
+
+import static org.happysanta.gd.Helpers.runOnUiThread;
+
+public class MenuTextView extends TextView {
+
+ protected boolean isAttached = false;
+
+ public MenuTextView(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ isAttached = true;
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ isAttached = false;
+ }
+
+ @Override
+ public boolean isAttachedToWindow() {
+ return isAttached;
+ }
+
+ public void setTextOnUiThread(final CharSequence sequence) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuTextView.super.setText(sequence);
+ }
+ });
+ }
+
+ @Override
+ public void setTextSize(final float size) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuTextView.super.setTextSize(size);
+ }
+ });
+ }
+
+ @Override
+ public void setTypeface(final Typeface typeface) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuTextView.super.setTypeface(typeface);
+ }
+ });
+ }
+
+ @Override
+ public void setVisibility(final int visibility) {
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ MenuTextView.super.setVisibility(visibility);
+ }
+ });
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Views/MenuTitleLinearLayout.java b/src/org/happysanta/gd/Menu/Views/MenuTitleLinearLayout.java
new file mode 100644
index 0000000..5c3f790
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Views/MenuTitleLinearLayout.java
@@ -0,0 +1,39 @@
+package org.happysanta.gd.Menu.Views;
+
+import android.app.Activity;
+import android.widget.RelativeLayout;
+
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class MenuTitleLinearLayout extends RelativeLayout {
+
+ private Callback onSizeChangedCallback = null;
+
+ public MenuTitleLinearLayout(Activity activity) {
+ super(activity);
+ }
+
+ @Override
+ public void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+
+ if (onSizeChangedCallback != null) {
+ onSizeChangedCallback.run(w, h, oldw, oldh);
+ }
+ }
+
+ /*public void forceInvokeOnSizeChangedCallback() {
+ if (onSizeChangedCallback != null) {
+ onSizeChangedCallback.run(getWidth(), getHeight(), 0, 0);
+ }
+ }*/
+
+ public void setOnSizeChangedCallback(Callback callback) {
+ onSizeChangedCallback = callback;
+ }
+
+ public interface Callback {
+ public abstract void run(int w, int h, int oldw, int oldh);
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Views/MenuView.java b/src/org/happysanta/gd/Menu/Views/MenuView.java
new file mode 100644
index 0000000..ba47071
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Views/MenuView.java
@@ -0,0 +1,12 @@
+package org.happysanta.gd.Menu.Views;
+
+import android.view.View;
+import org.happysanta.gd.GDActivity;
+
+public class MenuView extends View {
+
+ public MenuView(GDActivity activity) {
+ super(activity);
+ }
+
+}
diff --git a/src/org/happysanta/gd/Menu/Views/ObservableScrollView.java b/src/org/happysanta/gd/Menu/Views/ObservableScrollView.java
new file mode 100644
index 0000000..5801928
--- /dev/null
+++ b/src/org/happysanta/gd/Menu/Views/ObservableScrollView.java
@@ -0,0 +1,31 @@
+package org.happysanta.gd.Menu.Views;
+
+import android.content.Context;
+import android.widget.ScrollView;
+
+public class ObservableScrollView
+ extends ScrollView {
+
+ private OnScrollListener scrollListener = null;
+
+ public ObservableScrollView(Context context) {
+ super(context);
+ }
+
+ public void setOnScrollListener(OnScrollListener scrollListener) {
+ this.scrollListener = scrollListener;
+ }
+
+ @Override
+ protected void onScrollChanged(int x, int y, int oldx, int oldy) {
+ super.onScrollChanged(x, y, oldx, oldy);
+ if (scrollListener != null) {
+ scrollListener.onScroll(this, x, y, oldx, oldy);
+ }
+ }
+
+ public interface OnScrollListener {
+ public abstract void onScroll(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);
+ }
+
+}
diff --git a/src/org/happysanta/gd/Settings.java b/src/org/happysanta/gd/Settings.java
new file mode 100644
index 0000000..93857ca
--- /dev/null
+++ b/src/org/happysanta/gd/Settings.java
@@ -0,0 +1,215 @@
+package org.happysanta.gd;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Build;
+import org.happysanta.gd.API.API;
+
+import static org.happysanta.gd.Helpers.getGDActivity;
+
+public class Settings {
+
+ private static final String LEVEL_ID = "level_id";
+ private static final int LEVEL_ID_DEFAULT = 0;
+
+ private static final String PERSPECTIVE_ENABLED = "perspective_enabled";
+ private static final boolean PERSPECTIVE_ENABLED_DEFAULT = true;
+
+ private static final String SHADOWS_ENABLED = "shadows_enabled";
+ private static final boolean SHADOWS_ENABLED_DEFAULT = true;
+
+ private static final String DRIVER_SPRITE_ENABLED = "driver_sprite_enabled";
+ private static final boolean DRIVER_SPRITE_ENABLED_DEFAULT = true;
+
+ private static final String BIKE_SPRITE_ENABLED = "bike_sprite_enabled";
+ private static final boolean BIKE_SPRITE_ENABLED_DEFAULT = true;
+
+ private static final String INPUT_OPTION = "input_option";
+ private static final int INPUT_OPTION_DEFAULT = 0;
+
+ private static final String LOOK_AHEAD_ENABLED = "look_ahead_enabled";
+ private static final boolean LOOK_AHEAD_ENABLED_DEFAULT = true;
+
+ private static final String VIBRATE_ENABLED = "vibrate_enabled";
+ private static final boolean VIBRATE_ENABLED_DEFAULT = true;
+
+ private static final String KEYBOARD_IN_MENU_ENABLED = "keyboard_enabled";
+ private static final boolean KEYBOARD_IN_MENU_ENABLED_DEFAULT = true;
+
+ private static final String LAST_SEND_STATS = "last_send_stats";
+ private static final long LAST_SEND_STATS_DEFAULT = 0;
+
+ private static final String NAME = "name";
+ public static final String NAME_DEFAULT = "AAA";
+ public static final byte[] NAME_CHARS_DEFALUT = new byte[]{65, 65, 65};
+
+ private static final String LEVELS_SORT = "level_sort"; // in download list
+ private static final int LEVELS_SORT_DEFAULT = 0;
+
+ private static SharedPreferences preferences;
+
+ static {
+ preferences = getGDActivity().getSharedPreferences("GDSettings", Context.MODE_PRIVATE);
+ }
+
+ public static void resetAll() {
+ setPerspectiveEnabled(PERSPECTIVE_ENABLED_DEFAULT);
+ setShadowsEnabled(SHADOWS_ENABLED_DEFAULT);
+ setDriverSpriteEnabled(DRIVER_SPRITE_ENABLED_DEFAULT);
+ setBikeSpriteEnabled(BIKE_SPRITE_ENABLED_DEFAULT);
+ setLookAheadEnabled(LOOK_AHEAD_ENABLED_DEFAULT);
+ setVibrateOnTouchEnabled(VIBRATE_ENABLED_DEFAULT);
+ setKeyboardInMenuEnabled(KEYBOARD_IN_MENU_ENABLED_DEFAULT);
+ setInputOption(INPUT_OPTION_DEFAULT);
+ setLevelsSort(LEVELS_SORT_DEFAULT);
+ setName(NAME_CHARS_DEFALUT);
+ }
+
+ public static long getLevelId() {
+ return preferences.getLong(LEVEL_ID, LEVEL_ID_DEFAULT);
+ }
+
+ public static void setLevelId(long levelId) {
+ setLong(LEVEL_ID, levelId);
+ }
+
+ public static boolean isPerspectiveEnabled() {
+ return preferences.getBoolean(PERSPECTIVE_ENABLED, PERSPECTIVE_ENABLED_DEFAULT);
+ }
+
+ public static void setPerspectiveEnabled(boolean enabled) {
+ setBoolean(PERSPECTIVE_ENABLED, enabled);
+ }
+
+ public static boolean isShadowsEnabled() {
+ return preferences.getBoolean(SHADOWS_ENABLED, SHADOWS_ENABLED_DEFAULT);
+ }
+
+ public static void setShadowsEnabled(boolean enabled) {
+ setBoolean(SHADOWS_ENABLED, enabled);
+ }
+
+ public static boolean isDriverSpriteEnabled() {
+ return preferences.getBoolean(DRIVER_SPRITE_ENABLED, DRIVER_SPRITE_ENABLED_DEFAULT);
+ }
+
+ public static void setDriverSpriteEnabled(boolean enabled) {
+ setBoolean(DRIVER_SPRITE_ENABLED, enabled);
+ }
+
+ public static boolean isBikeSpriteEnabled() {
+ return preferences.getBoolean(BIKE_SPRITE_ENABLED, BIKE_SPRITE_ENABLED_DEFAULT);
+ }
+
+ public static void setBikeSpriteEnabled(boolean enabled) {
+ setBoolean(BIKE_SPRITE_ENABLED, enabled);
+ }
+
+ public static boolean isLookAheadEnabled() {
+ return preferences.getBoolean(LOOK_AHEAD_ENABLED, LOOK_AHEAD_ENABLED_DEFAULT);
+ }
+
+ public static void setLookAheadEnabled(boolean enabled) {
+ setBoolean(LOOK_AHEAD_ENABLED, enabled);
+ }
+
+ public static boolean isKeyboardInMenuEnabled() {
+ return preferences.getBoolean(KEYBOARD_IN_MENU_ENABLED, KEYBOARD_IN_MENU_ENABLED_DEFAULT);
+ }
+
+ public static void setKeyboardInMenuEnabled(boolean enabled) {
+ setBoolean(KEYBOARD_IN_MENU_ENABLED, enabled);
+ }
+
+ public static boolean isVibrateOnTouchEnabled() {
+ return preferences.getBoolean(VIBRATE_ENABLED, VIBRATE_ENABLED_DEFAULT);
+ }
+
+ public static void setVibrateOnTouchEnabled(boolean enabled) {
+ setBoolean(VIBRATE_ENABLED, enabled);
+ }
+
+ public static int getInputOption() {
+ return preferences.getInt(INPUT_OPTION, INPUT_OPTION_DEFAULT);
+ }
+
+ public static void setInputOption(int value) {
+ setInt(INPUT_OPTION, value);
+ }
+
+ public static long getLastSendStats() {
+ return preferences.getLong(LAST_SEND_STATS, LAST_SEND_STATS_DEFAULT);
+ }
+
+ public static void setLastSendStats(long value) {
+ setLong(LAST_SEND_STATS, value);
+ }
+
+ public static API.LevelsSortType getLevelsSort() {
+ return API.getSortTypeById(preferences.getInt(LEVELS_SORT, LEVELS_SORT_DEFAULT));
+ }
+
+ public static void setLevelsSort(API.LevelsSortType type) {
+ setInt(LEVELS_SORT, API.getIdBySortType(type));
+ }
+
+ public static void setLevelsSort(int type) {
+ setInt(LEVELS_SORT, type);
+ }
+
+ public static byte[] getName() {
+ String name = preferences.getString(NAME, NAME_DEFAULT);
+ if (name.length() < 3) {
+ name = NAME_DEFAULT;
+ }
+ return new byte[]{
+ (byte) name.charAt(0),
+ (byte) name.charAt(1),
+ (byte) name.charAt(2)
+ };
+ }
+
+ public static void setName(byte[] chars) {
+ if (chars.length < 3) {
+ setString(NAME, NAME_DEFAULT);
+ } else {
+ String name = "";
+ for (int i = 0; i < 3; i++) {
+ name += String.valueOf((char) chars[i]);
+ }
+ setString(NAME, name);
+ }
+ }
+
+ private static void setLong(String key, long value) {
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putLong(key, value);
+ editorApply(editor);
+ }
+
+ private static void setInt(String key, int value) {
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putInt(key, value);
+ editorApply(editor);
+ }
+
+ private static void setBoolean(String key, boolean value) {
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putBoolean(key, value);
+ editorApply(editor);
+ }
+
+ private static void setString(String key, String value) {
+ SharedPreferences.Editor editor = preferences.edit();
+ editor.putString(key, value);
+ editorApply(editor);
+ }
+
+ private static void editorApply(SharedPreferences.Editor editor) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD)
+ editor.apply();
+ else
+ editor.commit();
+ }
+
+}
diff --git a/src/org/happysanta/gd/Storage/HighScores.java b/src/org/happysanta/gd/Storage/HighScores.java
new file mode 100644
index 0000000..e3678c9
--- /dev/null
+++ b/src/org/happysanta/gd/Storage/HighScores.java
@@ -0,0 +1,152 @@
+package org.happysanta.gd.Storage;
+
+import org.happysanta.gd.Settings;
+
+public class HighScores {
+
+ private static final long MAX_TIME = 0xffff28L;
+
+ private long id;
+ private long levelId = 0;
+ private int level = 0;
+ private int track = 0;
+ private long[][] times = new long[4][3];
+ private String[][] names = new String[4][3];
+
+ public HighScores() {
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getLevelId() {
+ return levelId;
+ }
+
+ public void setLevelId(long levelId) {
+ this.levelId = levelId;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public void setLevel(int level) {
+ this.level = level;
+ }
+
+ public long getTrack() {
+ return track;
+ }
+
+ public void setTrack(int track) {
+ this.track = track;
+ }
+
+ public long getTime(int league, int place) {
+ return times[league][place];
+ }
+
+ public void setTime(int league, int place, long value) {
+ times[league][place] = value;
+ }
+
+ public String getName(int league, int place) {
+ return names[league][place];
+ }
+
+ public void setName(int league, int place, String value) {
+ names[league][place] = value;
+ }
+
+ public String[] getScores(int league) {
+ String[] scores = new String[3];
+ for (int places = 0; places < 3; places++) {
+ if (times[league][places] != 0L) {
+ int k = (int) times[league][places] / 100;
+ int l = (int) times[league][places] % 100;
+ scores[places] = names[league][places] + " ";
+ if (k / 60 < 10)
+ scores[places] += " 0" + k / 60;
+ else
+ scores[places] += " " + k / 60;
+ if (k % 60 < 10)
+ scores[places] += ":0" + k % 60;
+ else
+ scores[places] += ":" + k % 60;
+ if (l < 10)
+ scores[places] += ".0" + l;
+ else
+ scores[places] += "." + l;
+ } else {
+ scores[places] = null;
+ }
+ }
+
+ return scores;
+ }
+
+ public int getPlace(int league, long time) {
+ for (int place = 0; place < 3; place++)
+ if (times[league][place] > time || times[league][place] == 0L)
+ return place;
+
+ return 3;
+ }
+
+ private void clearTimes() {
+ for (int leagues = 0; leagues < 4; leagues++) {
+ for (int places = 0; places < 3; places++)
+ times[leagues][places] = 0L;
+ }
+ }
+
+ public void saveHighScore(int league, String name, long time) {
+ name = trimName(name);
+ int place;
+ if ((place = getPlace(league, time)) != 3) {
+ if (time > MAX_TIME)
+ time = MAX_TIME;
+ moveScoreEntries(league, place);
+
+ times[league][place] = time;
+ names[league][place] = name;
+ }
+ }
+
+ private void moveScoreEntries(int league, int i) {
+ for (int place = 2; place > i; place--) {
+ times[league][place] = times[league][place - 1];
+ names[league][place] = names[league][place - 1];
+ }
+ }
+
+ private static String trimName(String name) {
+ if (name.length() > 3)
+ name = name.substring(0, 3);
+ else if (name.length() < 3)
+ name = Settings.NAME_DEFAULT;
+
+ return name.toUpperCase();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("Storage.HighScores {");
+
+ s.append("id: " + id + ", ");
+ s.append("level_id: " + levelId + ", ");
+ s.append("level: " + level + ", ");
+ s.append("track: " + track);
+
+ s.append("}");
+ return s.toString();
+ }
+
+}
diff --git a/src/org/happysanta/gd/Storage/Level.java b/src/org/happysanta/gd/Storage/Level.java
new file mode 100644
index 0000000..3030b7b
--- /dev/null
+++ b/src/org/happysanta/gd/Storage/Level.java
@@ -0,0 +1,300 @@
+package org.happysanta.gd.Storage;
+
+import android.text.format.DateUtils;
+
+import static org.happysanta.gd.Helpers.getGDActivity;
+
+public class Level {
+
+ private long id = 0;
+ private String name;
+ private String author;
+ private int[] count;
+ private int size = 0;
+ private long addedTs = 0;
+ private long installedTs = 0;
+ private boolean _isDefault = false;
+ private long apiId = 0;
+ private int[] unlocked;
+ private int selectedTrack = 0;
+ private int selectedLevel = 0;
+ private int selectedLeague = 0;
+ private int unlockedLevels = 0;
+ private int unlockedLeagues = 0;
+
+ public Level() {
+ count = new int[3];
+ unlocked = new int[3];
+ }
+
+ public Level(long id, String name, String author, int countEasy, int countMedium, int countHard, int addedTs, int size, long apiId) {
+ this(id, name, author, countEasy, countMedium, countHard, addedTs, size, apiId, 0, 0, 0);
+ }
+
+ public Level(long id, String name, String author, int countEasy, int countMedium, int countHard, int addedTs, int size, long apiId, int unlockedEasy, int unlockedMedium, int unlockedHard) {
+ this.id = id;
+ this.name = name;
+ this.author = author;
+ this.count = new int[]{
+ countEasy, countMedium, countHard
+ };
+ this.addedTs = addedTs;
+ this.size = size;
+ this.apiId = apiId;
+ this.unlocked = new int[]{
+ unlockedEasy, unlockedMedium, unlockedHard
+ };
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public long getAnyId() {
+ return id > 0 ? id : apiId;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public int getCountEasy() {
+ return this.count[0];
+ }
+
+ public int getCountMedium() {
+ return this.count[1];
+ }
+
+ public int getCountHard() {
+ return this.count[2];
+ }
+
+ public int getCount(int level) {
+ return this.count[level];
+ }
+
+ public void setCountEasy(int count) {
+ this.count[0] = count;
+ }
+
+ public void setCountMedium(int count) {
+ this.count[1] = count;
+ }
+
+ public void setCountHard(int count) {
+ this.count[2] = count;
+ }
+
+ public void setCount(int easy, int medium, int hard) {
+ setCountEasy(easy);
+ setCountMedium(medium);
+ setCountHard(hard);
+ }
+
+ public long getAddedTs() {
+ return addedTs;
+ }
+
+ public void setAddedTs(long ts) {
+ addedTs = ts;
+ }
+
+ public long getInstalledTs() {
+ return installedTs;
+ }
+
+ public void setInstalledTs(long ts) {
+ installedTs = ts;
+ }
+
+ public void setIsDefault(boolean isDefault) {
+ this._isDefault = isDefault;
+ }
+
+ public boolean isDefault() {
+ return _isDefault;
+ }
+
+ public long getApiId() {
+ return apiId;
+ }
+
+ public void setApiId(long apiId) {
+ this.apiId = apiId;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ public void setSize(int size) {
+ this.size = size;
+ }
+
+ public boolean isInstalled() {
+ return id > 0;
+ }
+
+ public String getSizeKb() {
+ return String.valueOf(Math.round((size / 1024f) * 100f) / 100f);
+ }
+
+ public String getShortAddedDate() {
+ return getShortDate(addedTs);
+ }
+
+ public String getFullAddedDate() {
+ return getFullDate(addedTs);
+ }
+
+ public String getShortInstalledDate() {
+ return getShortDate(installedTs);
+ }
+
+ public String getFullInstalledDate() {
+ return getFullDate(installedTs);
+ }
+
+ public int getUnlockedEasy() {
+ return this.unlocked[0];
+ }
+
+ public int getUnlockedMedium() {
+ return this.unlocked[1];
+ }
+
+ public int getUnlockedHard() {
+ return this.unlocked[2];
+ }
+
+ public int getUnlocked(int level) {
+ //if (level < 3)
+ return unlocked[level];
+
+ //logDebug("Level.getUnlocked: level = " + level + ", out of bounds");
+ //return 0;
+ }
+
+ public int[] getUnlockedAll() {
+ return unlocked;
+ }
+
+ public void setUnlockedEasy(int unlocked) {
+ this.unlocked[0] = unlocked;
+ }
+
+ public void setUnlockedMedium(int unlocked) {
+ this.unlocked[1] = unlocked;
+ }
+
+ public void setUnlockedHard(int unlocked) {
+ this.unlocked[2] = unlocked;
+ }
+
+ public void setUnlocked(int easy, int medium, int hard) {
+ setUnlockedEasy(easy);
+ setUnlockedMedium(medium);
+ setUnlockedHard(hard);
+ }
+
+ public void setUnlocked(int level, int value) {
+ unlocked[level] = value;
+ }
+
+ public int getSelectedTrack() {
+ return selectedTrack;
+ }
+
+ public int getSelectedLevel() {
+ return selectedLevel;
+ }
+
+ public int getSelectedLeague() {
+ return selectedLeague;
+ }
+
+ public void setSelectedTrack(int selectedTrack) {
+ this.selectedTrack = selectedTrack;
+ }
+
+ public void setSelectedLevel(int selectedLevel) {
+ this.selectedLevel = selectedLevel;
+ }
+
+ public void setSelectedLeague(int selectedLeague) {
+ this.selectedLeague = selectedLeague;
+ }
+
+ public int getUnlockedLevels() {
+ return unlockedLevels;
+ }
+
+ public int getUnlockedLeagues() {
+ return unlockedLeagues;
+ }
+
+ public void setUnlockedLevels(int unlockedLevels) {
+ this.unlockedLevels = unlockedLevels;
+ }
+
+ public void setUnlockedLeagues(int unlockedLeagues) {
+ this.unlockedLeagues = unlockedLeagues;
+ }
+
+ public boolean isSettingsClear() {
+ return unlockedLevels == 0
+ && unlocked[0] == 0
+ && unlocked[1] == 0
+ && unlocked[2] == 0;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder s = new StringBuilder();
+ s.append("Storage.Level {");
+
+ s.append("id: " + id + ", ");
+ s.append("name: \"" + name + "\", ");
+ s.append("author: \"" + author + "\", ");
+ s.append("count: " + count[0] + "/" + count[1] + "/" + count[2] + ", ");
+ s.append("added_ts: " + addedTs + ", ");
+ s.append("installed_ts: " + installedTs + ", ");
+ s.append("default: " + (_isDefault ? 1 : 0) + ", ");
+ s.append("api_id: " + apiId + ", ");
+ s.append("unlocked: " + unlocked[0] + "/" + unlocked[1] + "/" + unlocked[2] + ", ");
+ s.append("selected_track: " + selectedTrack + ", ");
+ s.append("selected_level: " + selectedLevel + ", ");
+ s.append("selected_league: " + selectedLeague + ", ");
+ s.append("unlocked_levels: " + unlockedLevels + ", ");
+ s.append("unlocked_leagues: " + unlockedLeagues);
+
+ s.append("}");
+ return s.toString();
+ }
+
+ private static String getShortDate(long date) {
+ return DateUtils.formatDateTime(getGDActivity(), date * 1000L, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_ABBREV_MONTH);
+ }
+
+ private static String getFullDate(long date) {
+ return DateUtils.formatDateTime(getGDActivity(), date * 1000L, DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR);
+ }
+
+}
diff --git a/src/org/happysanta/gd/Storage/LevelsDataSource.java b/src/org/happysanta/gd/Storage/LevelsDataSource.java
new file mode 100644
index 0000000..40e7f14
--- /dev/null
+++ b/src/org/happysanta/gd/Storage/LevelsDataSource.java
@@ -0,0 +1,293 @@
+package org.happysanta.gd.Storage;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class LevelsDataSource {
+
+ private SQLiteDatabase db;
+ private LevelsSQLiteOpenHelper dbHelper;
+
+ public LevelsDataSource(Context context) {
+ dbHelper = new LevelsSQLiteOpenHelper(context);
+ }
+
+ public synchronized void open() throws SQLException {
+ db = dbHelper.getWritableDatabase();
+ }
+
+ public synchronized void close() {
+ dbHelper.close();
+ }
+
+ public synchronized Level createLevel(String name, String author, int countEasy, int countMedium, int countHard, long addedTs, long installedTs, boolean isDefault, long apiId) {
+ ContentValues values = new ContentValues();
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_NAME, name);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_AUTHOR, author);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_COUNT_EASY, countEasy);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_COUNT_MEDIUM, countMedium);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_COUNT_HARD, countHard);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_ADDED, addedTs);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_INSTALLED, installedTs);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_IS_DEFAULT, isDefault ? 1 : 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_API_ID, apiId);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_EASY, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_MEDIUM, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_HARD, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_TRACK, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_LEVEL, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_LEAGUE, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_LEVELS, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_LEAGUES, 0);
+
+ long insertId = db.insert(LevelsSQLiteOpenHelper.TABLE_LEVELS, null, values);
+ Cursor cursor = db.query(LevelsSQLiteOpenHelper.TABLE_LEVELS, null,
+ LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID + " = " + insertId,
+ null, null, null, null);
+
+ cursor.moveToFirst();
+
+ Level level = cursorToLevel(cursor);
+ cursor.close();
+ return level;
+ }
+
+ public synchronized void deleteLevel(Level level) {
+ long id = level.getId();
+ db.delete(LevelsSQLiteOpenHelper.TABLE_LEVELS, LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID + " = " + id, null);
+ db.delete(LevelsSQLiteOpenHelper.TABLE_HIGHSCORES, LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_LEVEL_ID + " = " + id, null);
+ }
+
+ // This will also reset auto increment counter
+ public synchronized void deleteAllLevels() {
+ db.delete(LevelsSQLiteOpenHelper.TABLE_LEVELS, null, null);
+ db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + LevelsSQLiteOpenHelper.TABLE_LEVELS + "'");
+ }
+
+ public synchronized void resetAllLevelsSettings() {
+ ContentValues values = new ContentValues();
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_EASY, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_MEDIUM, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_HARD, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_LEAGUE, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_LEVEL, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_TRACK, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_LEAGUES, 0);
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_LEVELS, 0);
+
+ int result = db.update(LevelsSQLiteOpenHelper.TABLE_LEVELS, values, null, null);
+ logDebug("LevelsDataSource.resetAllLevelsSettings: result = " + result);
+ }
+
+ public synchronized void updateLevel(Level level) {
+ ContentValues values = new ContentValues();
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_EASY, level.getUnlockedEasy());
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_MEDIUM, level.getUnlockedMedium());
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_HARD, level.getUnlockedHard());
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_LEAGUE, level.getSelectedLeague());
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_LEVEL, level.getSelectedLevel());
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_TRACK, level.getSelectedTrack());
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_LEAGUES, level.getUnlockedLeagues());
+ values.put(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_LEVELS, level.getUnlockedLevels());
+
+ // logDebug("LevelsDataSource.updateLevel selectedLeague: " + level.getSelectedLeague());
+
+ db.update(LevelsSQLiteOpenHelper.TABLE_LEVELS, values, LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID + " = " + level.getId(), null);
+ }
+
+ public synchronized HashMap<Long, Long> findInstalledLevels(ArrayList<Long> apiIds) {
+ HashMap<Long, Long> installed = new HashMap<>();
+
+ String[] apiIdsArray = new String[apiIds.size()];
+ for (int i = 0; i < apiIdsArray.length; i++) {
+ apiIdsArray[i] = apiIds.get(i).toString();
+ }
+
+ Cursor cursor = db.rawQuery("SELECT " + LevelsSQLiteOpenHelper.LEVELS_COLUMN_API_ID + ", " + LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID + " FROM " + LevelsSQLiteOpenHelper.TABLE_LEVELS + " WHERE " + LevelsSQLiteOpenHelper.LEVELS_COLUMN_API_ID + " IN (" + makePlaceholders(apiIdsArray.length) + ")", apiIdsArray);
+ cursor.moveToFirst();
+
+ while (!cursor.isAfterLast()) {
+ long apiId = cursor.getLong(0),
+ id = cursor.getLong(1);
+ installed.put(apiId, id);
+ cursor.moveToNext();
+ }
+ cursor.close();
+
+ return installed;
+ }
+
+ public synchronized List<Level> getAllLevels() {
+ Cursor cursor = db.query(LevelsSQLiteOpenHelper.TABLE_LEVELS, null, null, null, null, null, null);
+
+ List<Level> levels = levelsFromCursor(cursor);
+ cursor.close();
+
+ return levels;
+ }
+
+ public synchronized List<Level> getLevels(int offset, int count) {
+ Cursor cursor = db.query(LevelsSQLiteOpenHelper.TABLE_LEVELS, null, null, null, null, LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID + " ASC", offset + ", " + count);
+
+ List<Level> levels = levelsFromCursor(cursor);
+ cursor.close();
+
+ return levels;
+ }
+
+ public synchronized Level getLevel(long id) {
+ Cursor cursor = db.query(LevelsSQLiteOpenHelper.TABLE_LEVELS, null, LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID + " = " + id, null, null, null, null);
+ cursor.moveToFirst();
+
+ Level level = null;
+ if (cursor.getCount() > 0) {
+ level = cursorToLevel(cursor);
+ }
+
+ cursor.close();
+ return level;
+ }
+
+ public List<Level> levelsFromCursor(Cursor cursor) {
+ cursor.moveToFirst();
+ List<Level> levels = new ArrayList<>();
+ while (!cursor.isAfterLast()) {
+ Level level = cursorToLevel(cursor);
+ levels.add(level);
+ cursor.moveToNext();
+ }
+ return levels;
+ }
+
+ public synchronized boolean isDefaultLevelCreated() {
+ Cursor cursor = db.query(LevelsSQLiteOpenHelper.TABLE_LEVELS, new String[]{LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID}, LevelsSQLiteOpenHelper.LEVELS_COLUMN_IS_DEFAULT + " = 1", null, null, null, null);
+ boolean created = cursor.getCount() > 0;
+ cursor.close();
+ return created;
+ }
+
+ public synchronized boolean isApiIdInstalled(long apiId) {
+ Cursor cursor = db.query(LevelsSQLiteOpenHelper.TABLE_LEVELS, new String[]{LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID}, LevelsSQLiteOpenHelper.LEVELS_COLUMN_API_ID + " = " + apiId, null, null, null, null);
+ boolean installed = cursor.getCount() > 0;
+ cursor.close();
+ return installed;
+ }
+
+ public synchronized HighScores getHighScores(long levelId, int level, int track) {
+ Cursor cursor = db.query(LevelsSQLiteOpenHelper.TABLE_HIGHSCORES, null,
+ LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_LEVEL_ID + " = " + levelId + " AND " + LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_LEVEL + " = " + level + " AND " + LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_TRACK + " = " + track,
+ null, null, null, null);
+ cursor.moveToFirst();
+
+ HighScores highScores = new HighScores();
+ highScores.setLevelId(levelId);
+ highScores.setLevel(level);
+ highScores.setTrack(track);
+ if (cursor.getCount() > 0)
+ fillHighScoresFromCursor(cursor, highScores);
+ else {
+ long id = createEmptyHighScore(levelId, level, track);
+ highScores.setId(id);
+ }
+
+ cursor.close();
+ return highScores;
+ }
+
+ private synchronized long createEmptyHighScore(long levelId, int level, int track) {
+ ContentValues values = new ContentValues();
+ values.put(LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_LEVEL_ID, levelId);
+ values.put(LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_LEVEL, level);
+ values.put(LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_TRACK, track);
+ for (int league = 0; league < 4; league++) {
+ for (int place = 0; place < 3; place++) {
+ values.put(LevelsSQLiteOpenHelper.getHighscoresTimeColumn(league, place), 0);
+ values.put(LevelsSQLiteOpenHelper.getHighscoresNameColumn(league, place), 0);
+ }
+ }
+
+ long insertId = db.insert(LevelsSQLiteOpenHelper.TABLE_HIGHSCORES, null, values);
+ return insertId;
+ }
+
+ public synchronized void updateHighScores(HighScores scores) {
+ ContentValues values = new ContentValues();
+ for (int league = 0; league < 4; league++) {
+ for (int place = 0; place < 3; place++) {
+ values.put(LevelsSQLiteOpenHelper.getHighscoresTimeColumn(league, place), scores.getTime(league, place));
+ values.put(LevelsSQLiteOpenHelper.getHighscoresNameColumn(league, place), scores.getName(league, place));
+ }
+ }
+
+ db.update(LevelsSQLiteOpenHelper.TABLE_HIGHSCORES, values, LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_ID + " = " + scores.getId(), null);
+ }
+
+ public synchronized void clearHighScores(long levelId) {
+ db.delete(LevelsSQLiteOpenHelper.TABLE_HIGHSCORES,
+ levelId > 0 ? LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_LEVEL_ID + " = " + levelId : null,
+ null);
+ if (levelId == 0) {
+ db.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = '" + LevelsSQLiteOpenHelper.TABLE_HIGHSCORES + "'");
+ }
+ }
+
+ private Level cursorToLevel(Cursor cursor) {
+ Level level = new Level();
+ level.setId(cursor.getLong(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID)));
+ level.setName(cursor.getString(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_NAME)));
+ level.setAuthor(cursor.getString(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_AUTHOR)));
+ level.setCount(
+ cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_COUNT_EASY)),
+ cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_COUNT_MEDIUM)),
+ cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_COUNT_HARD)));
+ level.setAddedTs(cursor.getLong(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_ADDED)));
+ level.setInstalledTs(cursor.getLong(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_INSTALLED)));
+ level.setIsDefault(cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_IS_DEFAULT)) == 1);
+ level.setApiId(cursor.getLong(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_API_ID)));
+ level.setUnlocked(
+ cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_EASY)),
+ cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_MEDIUM)),
+ cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_HARD)));
+ level.setSelectedLevel(cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_LEVEL)));
+ level.setSelectedTrack(cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_TRACK)));
+ level.setSelectedLeague(cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_SELECTED_LEAGUE)));
+ level.setUnlockedLevels(cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_LEVELS)));
+ level.setUnlockedLeagues(cursor.getInt(cursor.getColumnIndex(LevelsSQLiteOpenHelper.LEVELS_COLUMN_UNLOCKED_LEAGUES)));
+
+ return level;
+ }
+
+ private void fillHighScoresFromCursor(Cursor cursor, HighScores highScores) {
+ highScores.setId(cursor.getLong(cursor.getColumnIndex(LevelsSQLiteOpenHelper.HIGHSCORES_COLUMN_ID)));
+
+ for (int league = 0; league < 4; league++) {
+ for (int place = 0; place < 3; place++) {
+ highScores.setTime(league, place, cursor.getLong(cursor.getColumnIndex(LevelsSQLiteOpenHelper.getHighscoresTimeColumn(league, place))));
+ highScores.setName(league, place, cursor.getString(cursor.getColumnIndex(LevelsSQLiteOpenHelper.getHighscoresNameColumn(league, place))));
+ }
+ }
+ }
+
+ private String makePlaceholders(int len) {
+ if (len < 1) {
+ throw new RuntimeException("No placeholders");
+ } else {
+ StringBuilder sb = new StringBuilder(len * 2 - 1);
+ sb.append("?");
+ for (int i = 1; i < len; i++) {
+ sb.append(",?");
+ }
+ return sb.toString();
+ }
+ }
+
+}
diff --git a/src/org/happysanta/gd/Storage/LevelsManager.java b/src/org/happysanta/gd/Storage/LevelsManager.java
new file mode 100644
index 0000000..697c9ff
--- /dev/null
+++ b/src/org/happysanta/gd/Storage/LevelsManager.java
@@ -0,0 +1,503 @@
+package org.happysanta.gd.Storage;
+
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.content.DialogInterface;
+import android.os.AsyncTask;
+import android.os.Environment;
+import android.os.StatFs;
+import org.happysanta.gd.API.API;
+import org.happysanta.gd.API.DownloadFile;
+import org.happysanta.gd.API.DownloadHandler;
+import org.happysanta.gd.Callback;
+import org.happysanta.gd.DoubleCallback;
+import org.happysanta.gd.GDActivity;
+import org.happysanta.gd.Global;
+import org.happysanta.gd.Levels.LevelHeader;
+import org.happysanta.gd.Levels.Reader;
+import org.happysanta.gd.Menu.Menu;
+import org.happysanta.gd.Menu.MenuScreen;
+import org.happysanta.gd.R;
+import org.happysanta.gd.Settings;
+import org.acra.ACRA;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import static org.happysanta.gd.Helpers.getGDActivity;
+import static org.happysanta.gd.Helpers.getGameMenu;
+import static org.happysanta.gd.Helpers.getString;
+import static org.happysanta.gd.Helpers.getTimestamp;
+import static org.happysanta.gd.Helpers.isOnline;
+import static org.happysanta.gd.Helpers.logDebug;
+import static org.happysanta.gd.Helpers.showAlert;
+
+public class LevelsManager {
+
+ private LevelsDataSource dataSource;
+ private boolean dbOK = false;
+ private Level currentLevel;
+
+ public LevelsManager() {
+ GDActivity gd = getGDActivity();
+ dataSource = new LevelsDataSource(gd);
+
+ try {
+ dataSource.open();
+
+ if (!dataSource.isDefaultLevelCreated()) {
+ Level level = dataSource.createLevel("GDTR original", "Codebrew Software", 10, 10, 10, 0, 0, true, 1);
+ logDebug("LevelsManager: Default level created!");
+ logDebug(level);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ logDebug("LevelsManager: db feels bad :(");
+ // return;
+ }
+
+ logDebug("LevelsManager: db feels OK :)");
+
+ // Shared prefs
+ // SharedPreferences settings = getSharedPreferences();
+ // long levelId = settings.getLong(PREFS_LEVEL_ID, 0);
+ long levelId = Settings.getLevelId();
+ if (levelId < 1 || !mrgIsAvailable(levelId)) {
+ logDebug("LevelsManager: levelId = " + levelId + ", < 1 or mrg is not available; now: reset id");
+ /*SharedPreferences.Editor editor = settings.edit();
+ editor.putLong(PREFS_LEVEL_ID, 1);
+ editor.commit();*/
+ resetId();
+ }
+
+ reload();
+ dbOK = true;
+ }
+
+ public void resetId() {
+ Settings.setLevelId(1);
+ }
+
+ public void reload() {
+ long id = Settings.getLevelId();
+ currentLevel = dataSource.getLevel(id);
+
+ if (currentLevel == null) {
+ logDebug("LevelsManager: failed to load currentLevel; currentId = " + id);
+ } else {
+ logDebug("LevelsManager: level = " + currentLevel);
+ }
+
+ if (Global.ACRA_ENABLED) {
+ ACRA.getErrorReporter().putCustomData("level_api_id:", String.valueOf(currentLevel.getApiId()));
+ }
+ }
+
+ public void closeDataSource() {
+ dataSource.close();
+ }
+
+ public long getCurrentId() {
+ return currentLevel.getId();
+ }
+
+ public void setCurrentId(long id) {
+ // currentId = id;
+ Settings.setLevelId(id);
+ /*SharedPreferences settings = getSharedPreferences();
+ SharedPreferences.Editor edit = settings.edit();
+ edit.putLong(PREFS_LEVEL_ID, id);
+ edit.commit();*/
+ }
+
+ public Level getCurrentLevel() {
+ return currentLevel;
+ }
+
+ public File getCurrentLevelsFile() {
+ if (currentLevel.getId() > 1)
+ return getMrgFileById(currentLevel.getId());
+
+ return null;
+ }
+
+ private boolean mrgIsAvailable(long id) {
+ if (id == 1) // This is default built-in levels.mrg
+ return true;
+
+ File file = getMrgFileById(id);
+ return isExternalStorageReadable() && file.exists();
+ }
+
+ public boolean isDbOK() {
+ return dbOK;
+ }
+
+ public long install(File file, String name, String author, long apiId) throws Exception {
+ if (!isSpaceAvailable(file.length())) {
+ throw new Exception(getString(R.string.e_no_space_left));
+ }
+
+ InputStream inputStream = new FileInputStream(file);
+ LevelHeader header = Reader.readHeader(inputStream);
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ }
+
+ if (!header.isCountsOk()) {
+ throw new IOException(file.getName() + " is not valid");
+ }
+
+ Level level = dataSource.createLevel(name, author, header.getCount(0), header.getCount(1), header.getCount(2), 0, getTimestamp(), false, apiId);
+ long id = level.getId();
+ if (id < 1) {
+ throw new Exception(getString(R.string.e_cannot_save_level));
+ }
+
+ File newFile = getMrgFileById(id);
+ copy(file, newFile);
+
+ return id;
+ }
+
+ public void installAsync(File file, String name, String author, long apiId, final DoubleCallback callback) {
+ GDActivity gd = getGDActivity();
+ final ProgressDialog progressDialog = ProgressDialog.show(gd, getString(R.string.install), getString(R.string.installing), true);
+
+ new AsyncInstallLevel() {
+ @Override
+ protected void onPostExecute(Object result) {
+ progressDialog.dismiss();
+
+ if (result instanceof Throwable) {
+ Throwable throwable = (Throwable) result;
+ throwable.printStackTrace();
+ showAlert(getString(R.string.error), throwable.getMessage(), null);
+ if (callback != null)
+ callback.onFail();
+ return;
+ }
+
+ if (callback != null)
+ callback.onDone((long) result);
+ }
+ }.execute(file, name, author, apiId);
+ }
+
+ public void load(Level level) throws RuntimeException {
+ /*File file = getMrgFileById(level.getId());
+ if (!mrgIsAvailable(level.getId())) {
+ throw new RuntimeException("Unable to load levels \"" +level.getName() + "\"");
+ }*/
+
+ // Loader loader = getLevelLoader();
+ // Menu menu = getGameMenu();
+
+ // loader.setLevelsFile(file);
+ // menu.reloadLevels();
+
+ setCurrentId(level.getId());
+ getGDActivity().restartApp();
+ }
+
+ public boolean isApiIdInstalled(long apiId) {
+ return dataSource.isApiIdInstalled(apiId);
+ }
+
+ public Level[] getInstalledLevels(int offset, int count) {
+ return dataSource.getLevels(offset, count).toArray(new Level[0]);
+ }
+
+ public Level getLeveL(long id) {
+ return dataSource.getLevel(id);
+ }
+
+ public Level[] getAllInstalledLevels() {
+ return dataSource.getAllLevels().toArray(new Level[0]);
+ }
+
+ public synchronized HashMap<String, Double> getLevelsStat() {
+ Level[] levels = getAllInstalledLevels();
+ HashMap<String, Double> stat = new HashMap<>();
+ if (levels.length > 0) {
+ for (Level level : levels) {
+ int[] completed = level.getUnlockedAll();
+ int completedCount = 0;
+ for (int i = 0; i < completed.length; i++) {
+ if (completed[i] < 0) completed[i] = 0;
+ completedCount += completed[i];
+ }
+
+ double totalCount = level.getCountEasy() + level.getCountMedium() + level.getCountHard();
+ double per = completedCount / totalCount * 100;
+
+ stat.put(String.valueOf(level.getApiId()), per);
+ }
+ }
+ return stat;
+ }
+
+ public void delete(Level level) {
+ dataSource.deleteLevel(level);
+ File file = getMrgFileById(level.getId());
+ try {
+ if (file.exists()) {
+ file.delete();
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void deleteAsync(Level level, final Runnable callback) {
+ GDActivity gd = getGDActivity();
+ final ProgressDialog progressDialog = ProgressDialog.show(gd, getString(R.string.delete), getString(R.string.deleting), true);
+
+ new AsyncDeleteLevel() {
+ @Override
+ protected void onPostExecute(Void v) {
+ progressDialog.dismiss();
+ if (callback != null)
+ callback.run();
+ }
+ }.execute(level);
+ }
+
+ public void updateLevelSettings() {
+ dataSource.updateLevel(currentLevel);
+ }
+
+ public void downloadLevel(final Level level, final Callback successCallback) {
+ final GDActivity gd = getGDActivity();
+ File outputDir = gd.getCacheDir();
+
+ try {
+ boolean readable = isExternalStorageReadable();
+ if (!readable) {
+ throw new Exception(getString(R.string.e_external_storage_is_not_readable));
+ }
+
+ if (!isOnline()) {
+ throw new Exception(getString(R.string.e_no_network_connection));
+ }
+
+ if (!isSpaceAvailable(level.getSize())) {
+ throw new Exception(getString(R.string.e_no_space_left));
+ }
+
+ final File outputFile = File.createTempFile("levels" + level.getApiId(), "mrg", outputDir);
+ FileOutputStream out = new FileOutputStream(outputFile);
+
+ // logDebug("downloadLevel: 4");
+ // final API api = new API();
+ final ProgressDialog progress;
+ final DownloadFile downloadFile = new DownloadFile(API.getMrgURL(level.getApiId()), out);
+
+ progress = new ProgressDialog(gd);
+ progress.setMessage(getString(R.string.downloading));
+ progress.setIndeterminate(true);
+ progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ progress.setCancelable(true);
+
+ final DownloadHandler handler = new DownloadHandler() {
+ @Override
+ public void onFinish(Throwable error) {
+ progress.dismiss();
+
+ if (error != null) {
+ // error.printStackTrace();
+ error.printStackTrace();
+ showAlert(getString(R.string.error), error.getMessage(), null);
+
+ outputFile.delete();
+ return;
+ }
+
+ // Install
+ installAsync(outputFile, level.getName(), level.getAuthor(), level.getApiId(), new DoubleCallback() {
+ @Override
+ public void onDone(Object... objects) {
+ long id = (long) objects[0];
+ outputFile.delete();
+
+ if (successCallback != null)
+ successCallback.onDone(id);
+ }
+
+ @Override
+ public void onFail() {
+ outputFile.delete();
+ }
+ });
+ }
+
+ @Override
+ public void onStart() {
+ progress.show();
+ }
+
+ @Override
+ public void onProgress(int pr) {
+ progress.setIndeterminate(false);
+ progress.setMax(100);
+ progress.setProgress(pr);
+ }
+ };
+ progress.setOnCancelListener(new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ downloadFile.cancel();
+ handler.onFinish(new InterruptedException(getString(R.string.e_downloading_was_interrupted)));
+ }
+ });
+
+ downloadFile.setDownloadHandler(handler);
+ downloadFile.start();
+ } catch (Exception e) {
+ showAlert(getString(R.string.error), e.getMessage(), null);
+ }
+ }
+
+ public void showSuccessfullyInstalledDialog() {
+ GDActivity gd = getGDActivity();
+ AlertDialog success = new AlertDialog.Builder(gd)
+ .setTitle(getString(R.string.installed))
+ .setMessage(getString(R.string.successfully_installed))
+ .setPositiveButton(getString(R.string.ok), null)
+ .setNegativeButton(getString(R.string.open_installed), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ Menu menu = getGameMenu();
+ MenuScreen currentMenu = getGameMenu().getCurrentMenu(),
+ newMenu = menu.managerInstalledScreen;
+
+ if (currentMenu == menu.managerDownloadScreen || currentMenu.getNavTarget() == menu.managerDownloadScreen) {
+ menu.managerDownloadScreen.onHide(menu.managerScreen);
+ }
+
+ menu.setCurrentMenu(newMenu, false);
+ }
+ })
+ .create();
+ success.show();
+ }
+
+ public HashMap<Long, Long> findInstalledLevels(ArrayList<Long> apiIds) {
+ return dataSource.findInstalledLevels(apiIds);
+ }
+
+ public HighScores getHighScores(int level, int track) {
+ HighScores scores = dataSource.getHighScores(currentLevel.getId(), level, track);
+ // logDebug("LevelsManager.getHighScores: " + scores);
+ return scores;
+ }
+
+ public void saveHighScores(HighScores scores) {
+ dataSource.updateHighScores(scores);
+ }
+
+ public void clearHighScores() {
+ dataSource.clearHighScores(currentLevel.getId());
+ }
+
+ public void clearAllHighScores() {
+ dataSource.clearHighScores(0);
+ }
+
+ public void resetAllLevelsSettings() {
+ dataSource.resetAllLevelsSettings();
+
+ logDebug("All levels now: " + dataSource.getAllLevels());
+ logDebug("Level#1: " + dataSource.getLevel(1));
+ }
+
+ public static boolean isExternalStorageWritable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state)) {
+ return true;
+ }
+ return false;
+ }
+
+ public static boolean isExternalStorageReadable() {
+ String state = Environment.getExternalStorageState();
+ if (Environment.MEDIA_MOUNTED.equals(state) ||
+ Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
+ return true;
+ }
+ return false;
+ }
+
+ public static File getLevelsDirectory() {
+ File file = new File(Environment.getExternalStorageDirectory(), "GDLevels");
+ if (!file.mkdirs()) {
+ logDebug("LevelsManager.getLevelsDirectory: directory not created");
+ }
+ return file;
+ }
+
+ public static String getMrgFileNameById(long id) {
+ return getLevelsDirectory().getAbsolutePath() + "/" + id + ".mrg";
+ }
+
+ public static File getMrgFileById(long id) {
+ if (id == 1) return null;
+ return new File(getMrgFileNameById(id));
+ }
+
+ public static void copy(File src, File dst) throws IOException {
+ InputStream in = new FileInputStream(src);
+ OutputStream out = new FileOutputStream(dst);
+
+ byte[] buf = new byte[1024];
+ int len;
+ while ((len = in.read(buf)) > 0) {
+ out.write(buf, 0, len);
+ }
+
+ in.close();
+ out.close();
+ }
+
+ public static boolean isSpaceAvailable(long bytes) {
+ StatFs stat = new StatFs(getLevelsDirectory().getPath());
+ long bytesAvailable = (long) stat.getBlockSize() * (long) stat.getAvailableBlocks();
+ return bytesAvailable >= bytes;
+ }
+
+ private class AsyncDeleteLevel extends AsyncTask<Level, Void, Void> {
+ @Override
+ protected Void doInBackground(Level... levels) {
+ delete(levels[0]);
+ return null;
+ }
+ }
+
+ private class AsyncInstallLevel extends AsyncTask<Object, Void, Object> {
+ @Override
+ protected Object doInBackground(Object... objects) {
+ File file = (File) objects[0];
+ String name = (String) objects[1];
+ String author = (String) objects[2];
+ long apiId = (long) objects[3];
+
+ long id = 0;
+ try {
+ id = install(file, name, author, apiId);
+ } catch (Throwable e) {
+ return e;
+ }
+
+ return id;
+ }
+ }
+
+}
diff --git a/src/org/happysanta/gd/Storage/LevelsSQLiteOpenHelper.java b/src/org/happysanta/gd/Storage/LevelsSQLiteOpenHelper.java
new file mode 100644
index 0000000..024a17f
--- /dev/null
+++ b/src/org/happysanta/gd/Storage/LevelsSQLiteOpenHelper.java
@@ -0,0 +1,141 @@
+package org.happysanta.gd.Storage;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+public class LevelsSQLiteOpenHelper extends SQLiteOpenHelper {
+
+ private static final int DATABASE_VERSION = 1;
+ private static final String DATABASE_NAME = "levels.db";
+
+ public static final String TABLE_LEVELS = "levels";
+ public static final String TABLE_HIGHSCORES = "highscores";
+
+ public static final String LEVELS_COLUMN_ID = "_id";
+ public static final String LEVELS_COLUMN_NAME = "name";
+ public static final String LEVELS_COLUMN_AUTHOR = "author";
+ public static final String LEVELS_COLUMN_COUNT_EASY = "count_easy";
+ public static final String LEVELS_COLUMN_COUNT_MEDIUM = "count_medium";
+ public static final String LEVELS_COLUMN_COUNT_HARD = "count_hard";
+ public static final String LEVELS_COLUMN_ADDED = "added_ts";
+ public static final String LEVELS_COLUMN_INSTALLED = "installed_ts";
+ public static final String LEVELS_COLUMN_IS_DEFAULT = "is_default";
+ public static final String LEVELS_COLUMN_API_ID = "api_id";
+ public static final String LEVELS_COLUMN_UNLOCKED_EASY = "unlocked_easy";
+ public static final String LEVELS_COLUMN_UNLOCKED_MEDIUM = "unlocked_medium";
+ public static final String LEVELS_COLUMN_UNLOCKED_HARD = "unlocked_hard";
+ public static final String LEVELS_COLUMN_SELECTED_LEVEL = "selected_level";
+ public static final String LEVELS_COLUMN_SELECTED_TRACK = "selected_track";
+ public static final String LEVELS_COLUMN_SELECTED_LEAGUE = "selected_league";
+ public static final String LEVELS_COLUMN_UNLOCKED_LEVELS = "unlocked_levels";
+ public static final String LEVELS_COLUMN_UNLOCKED_LEAGUES = "unlocked_leagues";
+
+ public static final String HIGHSCORES_COLUMN_ID = "_id";
+ public static final String HIGHSCORES_COLUMN_LEVEL_ID = "level_id";
+ public static final String HIGHSCORES_COLUMN_LEVEL = "level";
+ public static final String HIGHSCORES_COLUMN_TRACK = "track";
+
+ private static final String TABLE_LEVELS_CREATE = "CREATE TABLE "
+ + TABLE_LEVELS + "("
+ + LEVELS_COLUMN_ID + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
+ + LEVELS_COLUMN_NAME + " TEXT NOT NULL, "
+ + LEVELS_COLUMN_AUTHOR + " TEXT NOT NULL, "
+ + LEVELS_COLUMN_COUNT_EASY + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_COUNT_MEDIUM + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_COUNT_HARD + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_ADDED + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_INSTALLED + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_IS_DEFAULT + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_API_ID + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_UNLOCKED_EASY + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_UNLOCKED_MEDIUM + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_UNLOCKED_HARD + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_SELECTED_LEVEL + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_SELECTED_TRACK + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_SELECTED_LEAGUE + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_UNLOCKED_LEVELS + " INTEGER NOT NULL, "
+ + LEVELS_COLUMN_UNLOCKED_LEAGUES + " INTEGER NOT NULL"
+ + ");";
+
+ private static final String TABLE_HIGHSCORES_CREATE = " CREATE TABLE "
+ + TABLE_HIGHSCORES + "("
+ + HIGHSCORES_COLUMN_ID + " INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
+ + HIGHSCORES_COLUMN_LEVEL_ID + " INTEGER NOT NULL, "
+ + HIGHSCORES_COLUMN_LEVEL + " INTEGER NOT NULL, "
+ + HIGHSCORES_COLUMN_TRACK + " INTEGER NOT NULL, "
+
+ // 100cc
+ + getHighscoresTimeColumn(0, 0) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(0, 0) + " TEXT, "
+ + getHighscoresTimeColumn(0, 1) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(0, 1) + " TEXT, "
+ + getHighscoresTimeColumn(0, 2) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(0, 2) + " TEXT, "
+
+ // 175cc
+ + getHighscoresTimeColumn(1, 0) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(1, 0) + " TEXT, "
+ + getHighscoresTimeColumn(1, 1) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(1, 1) + " TEXT, "
+ + getHighscoresTimeColumn(1, 2) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(1, 2) + " TEXT, "
+
+ // 220cc
+ + getHighscoresTimeColumn(2, 0) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(2, 0) + " TEXT, "
+ + getHighscoresTimeColumn(2, 1) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(2, 1) + " TEXT, "
+ + getHighscoresTimeColumn(2, 2) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(2, 2) + " TEXT, "
+
+ // 325cc
+ + getHighscoresTimeColumn(3, 0) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(3, 0) + " TEXT, "
+ + getHighscoresTimeColumn(3, 1) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(3, 1) + " TEXT, "
+ + getHighscoresTimeColumn(3, 2) + " INTEGER NOT NULL, "
+ + getHighscoresNameColumn(3, 2) + " TEXT"
+
+ + ")";
+
+ LevelsSQLiteOpenHelper(Context context) {
+ super(context, DATABASE_NAME, null, DATABASE_VERSION);
+ }
+
+ @Override
+ public void onCreate(SQLiteDatabase db) {
+ db.execSQL(TABLE_LEVELS_CREATE);
+ createLevelsIndexes(db);
+
+ db.execSQL(TABLE_HIGHSCORES_CREATE);
+ createHighscoresIndexes(db);
+ }
+
+ @Override
+ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+
+ }
+
+ private void createLevelsIndexes(SQLiteDatabase db) {
+ db.execSQL("CREATE INDEX " + LEVELS_COLUMN_API_ID + "_index ON " + TABLE_LEVELS + "(" + LEVELS_COLUMN_API_ID + ")");
+ db.execSQL("CREATE INDEX " + LEVELS_COLUMN_IS_DEFAULT + "_index ON " + TABLE_LEVELS + "(" + LEVELS_COLUMN_IS_DEFAULT + ")");
+ }
+
+ private void createHighscoresIndexes(SQLiteDatabase db) {
+ db.execSQL("CREATE INDEX level_id_level_track_index ON " + TABLE_HIGHSCORES + "("
+ + HIGHSCORES_COLUMN_LEVEL_ID + ", "
+ + HIGHSCORES_COLUMN_LEVEL + ", "
+ + HIGHSCORES_COLUMN_TRACK
+ + ")");
+ }
+
+ public static String getHighscoresTimeColumn(int league, int place) {
+ return "l" + league + "_p" + place + "_time";
+ }
+
+ public static String getHighscoresNameColumn(int league, int place) {
+ return "l" + league + "_p" + place + "_name";
+ }
+
+}
diff --git a/src/org/happysanta/gd/Util/HexDump.java b/src/org/happysanta/gd/Util/HexDump.java
new file mode 100755
index 0000000..443555c
--- /dev/null
+++ b/src/org/happysanta/gd/Util/HexDump.java
@@ -0,0 +1,124 @@
+package org.happysanta.gd.Util;
+
+public class HexDump {
+ private final static char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+ public static String dumpHexString(byte[] array) {
+ return dumpHexString(array, 0, array.length);
+ }
+
+ public static String dumpHexString(byte[] array, int offset, int length) {
+ StringBuilder result = new StringBuilder();
+
+ byte[] line = new byte[16];
+ int lineIndex = 0;
+
+ result.append("\n0x");
+ result.append(toHexString(offset));
+
+ for (int i = offset; i < offset + length; i++) {
+ if (lineIndex == 16) {
+ result.append(" ");
+
+ for (int j = 0; j < 16; j++) {
+ if (line[j] > ' ' && line[j] < '~') {
+ result.append(new String(line, j, 1));
+ } else {
+ result.append(".");
+ }
+ }
+
+ result.append("\n0x");
+ result.append(toHexString(i));
+ lineIndex = 0;
+ }
+
+ byte b = array[i];
+ result.append(" ");
+ result.append(HEX_DIGITS[(b >>> 4) & 0x0F]);
+ result.append(HEX_DIGITS[b & 0x0F]);
+
+ line[lineIndex++] = b;
+ }
+
+ if (lineIndex != 16) {
+ int count = (16 - lineIndex) * 3;
+ count++;
+ for (int i = 0; i < count; i++) {
+ result.append(" ");
+ }
+
+ for (int i = 0; i < lineIndex; i++) {
+ if (line[i] > ' ' && line[i] < '~') {
+ result.append(new String(line, i, 1));
+ } else {
+ result.append(".");
+ }
+ }
+ }
+
+ return result.toString();
+ }
+
+ public static String toHexString(byte b) {
+ return toHexString(toByteArray(b));
+ }
+
+ public static String toHexString(byte[] array) {
+ return toHexString(array, 0, array.length);
+ }
+
+ public static String toHexString(byte[] array, int offset, int length) {
+ char[] buf = new char[length * 2];
+
+ int bufIndex = 0;
+ for (int i = offset; i < offset + length; i++) {
+ byte b = array[i];
+ buf[bufIndex++] = HEX_DIGITS[(b >>> 4) & 0x0F];
+ buf[bufIndex++] = HEX_DIGITS[b & 0x0F];
+ }
+
+ return new String(buf);
+ }
+
+ public static String toHexString(int i) {
+ return toHexString(toByteArray(i));
+ }
+
+ public static byte[] toByteArray(byte b) {
+ byte[] array = new byte[1];
+ array[0] = b;
+ return array;
+ }
+
+ public static byte[] toByteArray(int i) {
+ byte[] array = new byte[4];
+
+ array[3] = (byte) (i & 0xFF);
+ array[2] = (byte) ((i >> 8) & 0xFF);
+ array[1] = (byte) ((i >> 16) & 0xFF);
+ array[0] = (byte) ((i >> 24) & 0xFF);
+
+ return array;
+ }
+
+ private static int toByte(char c) {
+ if (c >= '0' && c <= '9') return (c - '0');
+ if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
+ if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
+
+ throw new RuntimeException("Invalid hex char '" + c + "'");
+ }
+
+ public static byte[] hexStringToByteArray(String hexString) {
+ int length = hexString.length();
+ byte[] buffer = new byte[length / 2];
+
+ for (int i = 0; i < length; i += 2) {
+ buffer[i / 2] = (byte) ((toByte(hexString.charAt(i)) << 4) | toByte(hexString.charAt(i + 1)));
+ }
+
+ return buffer;
+ }
+}
+
diff --git a/src/org/happysanta/gd/WaitForNetworkConnection.java b/src/org/happysanta/gd/WaitForNetworkConnection.java
new file mode 100644
index 0000000..d711715
--- /dev/null
+++ b/src/org/happysanta/gd/WaitForNetworkConnection.java
@@ -0,0 +1,34 @@
+package org.happysanta.gd;
+
+import android.os.AsyncTask;
+
+import static org.happysanta.gd.Helpers.isOnline;
+import static org.happysanta.gd.Helpers.logDebug;
+
+public class WaitForNetworkConnection extends AsyncTask<Object, Void, Void> {
+
+ protected Runnable callback;
+
+ @Override
+ public Void doInBackground(Object... params) {
+ callback = (Runnable) params[1];
+
+ while (!isOnline()) {
+ logDebug("Waiting for network...");
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ break;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public void onPostExecute(Void v) {
+ logDebug("Network OK, callback.run() now...");
+ callback.run();
+ }
+
+}