From ae0e6ec634d8ab515ae381145a89d9ce649ba082 Mon Sep 17 00:00:00 2001 From: evgenyzinoviev Date: Fri, 14 Aug 2015 17:11:48 +0300 Subject: initial --- .classpath | 9 + .idea/.name | 1 + .idea/artifacts/Gravity_Defied_Classic.xml | 22 + .idea/codeStyleSettings.xml | 14 + .idea/compiler.xml | 25 + .idea/copyright/profiles_settings.xml | 3 + .idea/encodings.xml | 5 + .idea/libraries/acra_4_5_0.xml | 9 + .idea/libraries/android_support_v4.xml | 9 + ...support_v4_c1a500050aef26b42ae63e5fd8ee3115.xml | 9 + .idea/misc.xml | 120 ++ .idea/modules.xml | 9 + .idea/scopes/scope_settings.xml | 5 + .idea/src.iml | 9 + .idea/uiDesigner.xml | 125 ++ .idea/vcs.xml | 7 + .idea/workspace.xml | 1767 ++++++++++++++++++++ .project | 33 + AGDTR.iml | 20 + AndroidManifest.xml | 37 + README.md | 27 + assets/RobotoCondensed-Regular.ttf | Bin 0 -> 114568 bytes assets/levels.mrg | Bin 0 -> 5123 bytes libs/acra-4.5.0.jar | Bin 0 -> 126013 bytes proguard-project.txt | 20 + project.properties | 14 + psd/drawables/drawable-hdpi/flag_h.psd | Bin 0 -> 104864 bytes psd/drawables/drawable-hdpi/helmet.psd | Bin 0 -> 35458 bytes psd/drawables/drawable-hdpi/ic_downloaded.psd | Bin 0 -> 22126 bytes psd/drawables/drawable-hdpi/ic_menu_down.psd | Bin 0 -> 29276 bytes psd/drawables/drawable-hdpi/ic_menu_up.psd | Bin 0 -> 29262 bytes psd/drawables/drawable-hdpi/ic_sort.psd | Bin 0 -> 30972 bytes psd/drawables/drawable-mdpi/ic_downloaded.psd | Bin 0 -> 25710 bytes psd/drawables/drawable-mdpi/ic_menu_down.psd | Bin 0 -> 33644 bytes psd/drawables/drawable-mdpi/ic_menu_up.psd | Bin 0 -> 33582 bytes psd/drawables/drawable-mdpi/ic_sort.psd | Bin 0 -> 27278 bytes psd/drawables/drawable-mdpi/s_flag_mdpi.psd | Bin 0 -> 23030 bytes psd/drawables/drawable-mdpi/s_lock_mdpi.psd | Bin 0 -> 22398 bytes psd/drawables/drawable-xhdpi/bluearm.psd | Bin 0 -> 26732 bytes psd/drawables/drawable-xhdpi/bluebody.psd | Bin 0 -> 28445 bytes psd/drawables/drawable-xhdpi/blueleg.psd | Bin 0 -> 28304 bytes psd/drawables/drawable-xhdpi/btn_bottom_left.psd | Bin 0 -> 52136 bytes psd/drawables/drawable-xhdpi/btn_bottom_right.psd | Bin 0 -> 52128 bytes psd/drawables/drawable-xhdpi/btn_left_right.psd | Bin 0 -> 52120 bytes psd/drawables/drawable-xhdpi/btn_middle.psd | Bin 0 -> 66556 bytes .../drawable-xhdpi/btn_top_bottom_middle.psd | Bin 0 -> 64402 bytes psd/drawables/drawable-xhdpi/btn_top_left.psd | Bin 0 -> 48070 bytes psd/drawables/drawable-xhdpi/btn_top_right.psd | Bin 0 -> 48996 bytes psd/drawables/drawable-xhdpi/engine.psd | Bin 0 -> 1101269 bytes psd/drawables/drawable-xhdpi/engine_hdpi.psd | Bin 0 -> 43578 bytes psd/drawables/drawable-xhdpi/engine_xx.psd | Bin 0 -> 1110318 bytes psd/drawables/drawable-xhdpi/fender.psd | Bin 0 -> 47654 bytes psd/drawables/drawable-xhdpi/fender_hdpi.psd | Bin 0 -> 34322 bytes psd/drawables/drawable-xhdpi/flag.psd | Bin 0 -> 107633 bytes psd/drawables/drawable-xhdpi/helmet1.psd | Bin 0 -> 152793 bytes psd/drawables/drawable-xhdpi/ic_downloaded.psd | Bin 0 -> 26706 bytes psd/drawables/drawable-xhdpi/ic_menu_down.psd | Bin 0 -> 36592 bytes psd/drawables/drawable-xhdpi/ic_menu_up.psd | Bin 0 -> 36608 bytes psd/drawables/drawable-xhdpi/ic_sort.psd | Bin 0 -> 27466 bytes psd/drawables/drawable-xhdpi/lock.psd | Bin 0 -> 33047 bytes psd/drawables/drawable-xhdpi/medal.psd | Bin 0 -> 50962 bytes psd/drawables/drawable-xhdpi/s_arrow_down.psd | Bin 0 -> 23361 bytes psd/drawables/drawable-xhdpi/s_arrow_up.psd | Bin 0 -> 22485 bytes psd/drawables/drawable-xhdpi/s_steering.psd | Bin 0 -> 27194 bytes psd/drawables/drawable-xhdpi/wheel1.psd | Bin 0 -> 48775 bytes psd/drawables/drawable-xhdpi/wheel_1x.psd | Bin 0 -> 24550 bytes psd/drawables/drawable-xxhdpi/flag_xxh.psd | Bin 0 -> 112915 bytes psd/drawables/drawable-xxhdpi/helmet1.psd | Bin 0 -> 38354 bytes psd/drawables/drawable-xxhdpi/ic_downloaded.psd | Bin 0 -> 27764 bytes psd/drawables/drawable-xxhdpi/ic_menu_down.psd | Bin 0 -> 39482 bytes psd/drawables/drawable-xxhdpi/ic_menu_up.psd | Bin 0 -> 39416 bytes psd/drawables/drawable-xxhdpi/ic_sort.psd | Bin 0 -> 32786 bytes psd/drawables/drawable-xxhdpi/medal_xx.psd | Bin 0 -> 46462 bytes psd/icon/icon_512.psd | Bin 0 -> 429262 bytes psd/icon/icon_hdpi.psd | Bin 0 -> 67414 bytes psd/icon/icon_mdpi.psd | Bin 0 -> 56483 bytes psd/icon/icon_xhdpi.psd | Bin 0 -> 78042 bytes psd/icon/icon_xxhdpi.psd | Bin 0 -> 103243 bytes psd/icon/icon_xxxhdpi.psd | Bin 0 -> 131005 bytes res/drawable-hdpi/btn_b_down.9.png | Bin 0 -> 171 bytes res/drawable-hdpi/btn_b_up.9.png | Bin 0 -> 161 bytes res/drawable-hdpi/btn_br_down.9.png | Bin 0 -> 168 bytes res/drawable-hdpi/btn_br_up.9.png | Bin 0 -> 163 bytes res/drawable-hdpi/btn_n_down.9.png | Bin 0 -> 159 bytes res/drawable-hdpi/btn_n_up.9.png | Bin 0 -> 85 bytes res/drawable-hdpi/btn_r_down.9.png | Bin 0 -> 162 bytes res/drawable-hdpi/btn_r_up.9.png | Bin 0 -> 159 bytes res/drawable-hdpi/codebrew.png | Bin 0 -> 7829 bytes res/drawable-hdpi/gd.png | Bin 0 -> 11615 bytes res/drawable-hdpi/ic_downloaded.png | Bin 0 -> 180 bytes res/drawable-hdpi/ic_downloaded_selected.png | Bin 0 -> 179 bytes res/drawable-hdpi/ic_installed.png | Bin 0 -> 449 bytes res/drawable-hdpi/ic_installed_selected.png | Bin 0 -> 449 bytes res/drawable-hdpi/ic_launcher.png | Bin 0 -> 9397 bytes res/drawable-hdpi/ic_menu_down.png | Bin 0 -> 231 bytes res/drawable-hdpi/ic_menu_up.png | Bin 0 -> 221 bytes res/drawable-hdpi/ic_sort_down.png | Bin 0 -> 167 bytes res/drawable-hdpi/ic_sort_up.png | Bin 0 -> 167 bytes res/drawable-hdpi/icon.png | Bin 0 -> 877 bytes res/drawable-hdpi/levels_wheel0.png | Bin 0 -> 450 bytes res/drawable-hdpi/levels_wheel1.png | Bin 0 -> 498 bytes res/drawable-hdpi/levels_wheel2.png | Bin 0 -> 495 bytes res/drawable-hdpi/s_arrow_down.png | Bin 0 -> 170 bytes res/drawable-hdpi/s_arrow_up.png | Bin 0 -> 174 bytes res/drawable-hdpi/s_bluearm.png | Bin 0 -> 305 bytes res/drawable-hdpi/s_bluebody.png | Bin 0 -> 283 bytes res/drawable-hdpi/s_blueleg.png | Bin 0 -> 246 bytes res/drawable-hdpi/s_engine.png | Bin 0 -> 967 bytes res/drawable-hdpi/s_fender.png | Bin 0 -> 770 bytes res/drawable-hdpi/s_flag_finish0.png | Bin 0 -> 487 bytes res/drawable-hdpi/s_flag_finish1.png | Bin 0 -> 501 bytes res/drawable-hdpi/s_flag_finish2.png | Bin 0 -> 483 bytes res/drawable-hdpi/s_flag_start0.png | Bin 0 -> 425 bytes res/drawable-hdpi/s_flag_start1.png | Bin 0 -> 421 bytes res/drawable-hdpi/s_flag_start2.png | Bin 0 -> 453 bytes res/drawable-hdpi/s_helmet.png | Bin 0 -> 543 bytes res/drawable-hdpi/s_lock0.png | Bin 0 -> 275 bytes res/drawable-hdpi/s_lock1.png | Bin 0 -> 498 bytes res/drawable-hdpi/s_lock2.png | Bin 0 -> 302 bytes res/drawable-hdpi/s_medal_bronze.png | Bin 0 -> 320 bytes res/drawable-hdpi/s_medal_gold.png | Bin 0 -> 325 bytes res/drawable-hdpi/s_medal_silver.png | Bin 0 -> 311 bytes res/drawable-hdpi/s_steering.png | Bin 0 -> 152 bytes res/drawable-hdpi/s_wheel1.png | Bin 0 -> 540 bytes res/drawable-hdpi/s_wheel2.png | Bin 0 -> 547 bytes res/drawable-mdpi/btn_b_down.9.png | Bin 0 -> 93 bytes res/drawable-mdpi/btn_b_up.9.png | Bin 0 -> 91 bytes res/drawable-mdpi/btn_br_down.9.png | Bin 0 -> 94 bytes res/drawable-mdpi/btn_br_up.9.png | Bin 0 -> 90 bytes res/drawable-mdpi/btn_n_down.9.png | Bin 0 -> 86 bytes res/drawable-mdpi/btn_n_up.9.png | Bin 0 -> 85 bytes res/drawable-mdpi/btn_r_down.9.png | Bin 0 -> 90 bytes res/drawable-mdpi/btn_r_up.9.png | Bin 0 -> 88 bytes res/drawable-mdpi/codebrew.png | Bin 0 -> 4775 bytes res/drawable-mdpi/gd.png | Bin 0 -> 6483 bytes res/drawable-mdpi/ic_downloaded.png | Bin 0 -> 166 bytes res/drawable-mdpi/ic_downloaded_selected.png | Bin 0 -> 166 bytes res/drawable-mdpi/ic_installed.png | Bin 0 -> 314 bytes res/drawable-mdpi/ic_installed_selected.png | Bin 0 -> 309 bytes res/drawable-mdpi/ic_launcher.png | Bin 0 -> 5237 bytes res/drawable-mdpi/ic_menu_down.png | Bin 0 -> 187 bytes res/drawable-mdpi/ic_menu_up.png | Bin 0 -> 187 bytes res/drawable-mdpi/ic_sort_down.png | Bin 0 -> 158 bytes res/drawable-mdpi/ic_sort_up.png | Bin 0 -> 158 bytes res/drawable-mdpi/icon.png | Bin 0 -> 669 bytes res/drawable-mdpi/levels_wheel0.png | Bin 0 -> 304 bytes res/drawable-mdpi/levels_wheel1.png | Bin 0 -> 331 bytes res/drawable-mdpi/levels_wheel2.png | Bin 0 -> 337 bytes res/drawable-mdpi/s_arrow_down.png | Bin 0 -> 153 bytes res/drawable-mdpi/s_arrow_up.png | Bin 0 -> 151 bytes res/drawable-mdpi/s_bluearm.png | Bin 0 -> 185 bytes res/drawable-mdpi/s_bluebody.png | Bin 0 -> 248 bytes res/drawable-mdpi/s_blueleg.png | Bin 0 -> 198 bytes res/drawable-mdpi/s_engine.png | Bin 0 -> 458 bytes res/drawable-mdpi/s_fender.png | Bin 0 -> 308 bytes res/drawable-mdpi/s_flag_finish0.png | Bin 0 -> 254 bytes res/drawable-mdpi/s_flag_finish1.png | Bin 0 -> 284 bytes res/drawable-mdpi/s_flag_finish2.png | Bin 0 -> 261 bytes res/drawable-mdpi/s_flag_start0.png | Bin 0 -> 301 bytes res/drawable-mdpi/s_flag_start1.png | Bin 0 -> 282 bytes res/drawable-mdpi/s_flag_start2.png | Bin 0 -> 289 bytes res/drawable-mdpi/s_helmet.png | Bin 0 -> 230 bytes res/drawable-mdpi/s_lock0.png | Bin 0 -> 236 bytes res/drawable-mdpi/s_lock1.png | Bin 0 -> 282 bytes res/drawable-mdpi/s_lock2.png | Bin 0 -> 261 bytes res/drawable-mdpi/s_medal_bronze.png | Bin 0 -> 238 bytes res/drawable-mdpi/s_medal_gold.png | Bin 0 -> 250 bytes res/drawable-mdpi/s_medal_silver.png | Bin 0 -> 254 bytes res/drawable-mdpi/s_wheel1.png | Bin 0 -> 392 bytes res/drawable-mdpi/s_wheel2.png | Bin 0 -> 383 bytes res/drawable-xhdpi/btn_b_down.9.png | Bin 0 -> 169 bytes res/drawable-xhdpi/btn_b_up.9.png | Bin 0 -> 169 bytes res/drawable-xhdpi/btn_br_down.9.png | Bin 0 -> 172 bytes res/drawable-xhdpi/btn_br_up.9.png | Bin 0 -> 174 bytes res/drawable-xhdpi/btn_n_down.9.png | Bin 0 -> 157 bytes res/drawable-xhdpi/btn_n_up.9.png | Bin 0 -> 169 bytes res/drawable-xhdpi/btn_r_down.9.png | Bin 0 -> 166 bytes res/drawable-xhdpi/btn_r_up.9.png | Bin 0 -> 173 bytes res/drawable-xhdpi/codebrew.png | Bin 0 -> 11774 bytes res/drawable-xhdpi/flag.png | Bin 0 -> 590 bytes res/drawable-xhdpi/gd.png | Bin 0 -> 18596 bytes res/drawable-xhdpi/ic_downloaded.png | Bin 0 -> 192 bytes res/drawable-xhdpi/ic_downloaded_selected.png | Bin 0 -> 188 bytes res/drawable-xhdpi/ic_installed.png | Bin 0 -> 563 bytes res/drawable-xhdpi/ic_installed_selected.png | Bin 0 -> 560 bytes res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 14383 bytes res/drawable-xhdpi/ic_menu_down.png | Bin 0 -> 247 bytes res/drawable-xhdpi/ic_menu_up.png | Bin 0 -> 255 bytes res/drawable-xhdpi/ic_sort_down.png | Bin 0 -> 179 bytes res/drawable-xhdpi/ic_sort_up.png | Bin 0 -> 179 bytes res/drawable-xhdpi/icon_xhdpi.png | Bin 0 -> 1055 bytes res/drawable-xhdpi/levels_wheel0.png | Bin 0 -> 589 bytes res/drawable-xhdpi/levels_wheel1.png | Bin 0 -> 608 bytes res/drawable-xhdpi/levels_wheel2.png | Bin 0 -> 692 bytes res/drawable-xhdpi/s_arrow_down.png | Bin 0 -> 199 bytes res/drawable-xhdpi/s_arrow_up.png | Bin 0 -> 196 bytes res/drawable-xhdpi/s_bluearm.png | Bin 0 -> 346 bytes res/drawable-xhdpi/s_bluebody.png | Bin 0 -> 330 bytes res/drawable-xhdpi/s_blueleg.png | Bin 0 -> 276 bytes res/drawable-xhdpi/s_engine.png | Bin 0 -> 1366 bytes res/drawable-xhdpi/s_fender.png | Bin 0 -> 1071 bytes res/drawable-xhdpi/s_flag_finish0.png | Bin 0 -> 593 bytes res/drawable-xhdpi/s_flag_finish1.png | Bin 0 -> 571 bytes res/drawable-xhdpi/s_flag_finish2.png | Bin 0 -> 576 bytes res/drawable-xhdpi/s_flag_start0.png | Bin 0 -> 533 bytes res/drawable-xhdpi/s_flag_start1.png | Bin 0 -> 526 bytes res/drawable-xhdpi/s_flag_start2.png | Bin 0 -> 574 bytes res/drawable-xhdpi/s_helmet.png | Bin 0 -> 793 bytes res/drawable-xhdpi/s_lock0.png | Bin 0 -> 315 bytes res/drawable-xhdpi/s_lock1.png | Bin 0 -> 737 bytes res/drawable-xhdpi/s_lock2.png | Bin 0 -> 369 bytes res/drawable-xhdpi/s_medal_bronze.png | Bin 0 -> 481 bytes res/drawable-xhdpi/s_medal_gold.png | Bin 0 -> 487 bytes res/drawable-xhdpi/s_medal_silver.png | Bin 0 -> 417 bytes res/drawable-xhdpi/s_steering.png | Bin 0 -> 134 bytes res/drawable-xhdpi/s_wheel1.png | Bin 0 -> 697 bytes res/drawable-xhdpi/s_wheel2.png | Bin 0 -> 606 bytes res/drawable-xxhdpi/btn_b_down.9.png | Bin 0 -> 171 bytes res/drawable-xxhdpi/btn_b_up.9.png | Bin 0 -> 165 bytes res/drawable-xxhdpi/btn_br_down.9.png | Bin 0 -> 171 bytes res/drawable-xxhdpi/btn_br_up.9.png | Bin 0 -> 170 bytes res/drawable-xxhdpi/btn_n_down.9.png | Bin 0 -> 158 bytes res/drawable-xxhdpi/btn_n_up.9.png | Bin 0 -> 154 bytes res/drawable-xxhdpi/btn_r_down.9.png | Bin 0 -> 165 bytes res/drawable-xxhdpi/btn_r_up.9.png | Bin 0 -> 163 bytes res/drawable-xxhdpi/ic_downloaded.png | Bin 0 -> 223 bytes res/drawable-xxhdpi/ic_downloaded_selected.png | Bin 0 -> 217 bytes res/drawable-xxhdpi/ic_installed.png | Bin 0 -> 808 bytes res/drawable-xxhdpi/ic_installed_selected.png | Bin 0 -> 807 bytes res/drawable-xxhdpi/ic_menu_down.png | Bin 0 -> 353 bytes res/drawable-xxhdpi/ic_menu_up.png | Bin 0 -> 352 bytes res/drawable-xxhdpi/ic_sort_down.png | Bin 0 -> 217 bytes res/drawable-xxhdpi/ic_sort_up.png | Bin 0 -> 217 bytes res/drawable-xxhdpi/icon.png | Bin 0 -> 1406 bytes res/drawable-xxhdpi/levels_wheel0.png | Bin 0 -> 869 bytes res/drawable-xxhdpi/levels_wheel1.png | Bin 0 -> 963 bytes res/drawable-xxhdpi/levels_wheel2.png | Bin 0 -> 953 bytes res/drawable-xxhdpi/s_arrow_down.png | Bin 0 -> 245 bytes res/drawable-xxhdpi/s_arrow_up.png | Bin 0 -> 231 bytes res/drawable-xxhdpi/s_bluearm.png | Bin 0 -> 474 bytes res/drawable-xxhdpi/s_bluebody.png | Bin 0 -> 429 bytes res/drawable-xxhdpi/s_blueleg.png | Bin 0 -> 392 bytes res/drawable-xxhdpi/s_engine.png | Bin 0 -> 2263 bytes res/drawable-xxhdpi/s_fender.png | Bin 0 -> 1769 bytes res/drawable-xxhdpi/s_flag_finish0.png | Bin 0 -> 894 bytes res/drawable-xxhdpi/s_flag_finish1.png | Bin 0 -> 870 bytes res/drawable-xxhdpi/s_flag_finish2.png | Bin 0 -> 895 bytes res/drawable-xxhdpi/s_flag_start0.png | Bin 0 -> 717 bytes res/drawable-xxhdpi/s_flag_start1.png | Bin 0 -> 743 bytes res/drawable-xxhdpi/s_flag_start2.png | Bin 0 -> 784 bytes res/drawable-xxhdpi/s_helmet.png | Bin 0 -> 1297 bytes res/drawable-xxhdpi/s_lock0.png | Bin 0 -> 436 bytes res/drawable-xxhdpi/s_lock1.png | Bin 0 -> 1184 bytes res/drawable-xxhdpi/s_lock2.png | Bin 0 -> 473 bytes res/drawable-xxhdpi/s_medal_bronze.png | Bin 0 -> 702 bytes res/drawable-xxhdpi/s_medal_gold.png | Bin 0 -> 706 bytes res/drawable-xxhdpi/s_medal_silver.png | Bin 0 -> 548 bytes res/drawable-xxhdpi/s_steering.png | Bin 0 -> 133 bytes res/drawable-xxhdpi/s_wheel1.png | Bin 0 -> 968 bytes res/drawable-xxhdpi/s_wheel2.png | Bin 0 -> 972 bytes res/drawable-xxxhdpi/icon.png | Bin 0 -> 1898 bytes res/drawable/btn_b.xml | 8 + res/drawable/btn_br.xml | 8 + res/drawable/btn_n.xml | 8 + res/drawable/btn_r.xml | 8 + res/drawable/ic_menu.xml | 7 + res/drawable/ic_sort.xml | 7 + res/drawable/menu_item_color.xml | 8 + res/layout/activity_gdtr.xml | 11 + res/layout/levels_list_item.xml | 43 + res/menu/gdtr.xml | 9 + res/values-sw600dp/dimens.xml | 8 + res/values-sw600dp/screen.xml | 4 + res/values-sw720dp-land/dimens.xml | 9 + res/values-sw720dp-land/screen.xml | 4 + res/values-v11/styles.xml | 11 + res/values-v14/styles.xml | 12 + res/values/dimens.xml | 7 + res/values/screen.xml | 4 + res/values/strings.xml | 236 +++ res/values/styles.xml | 21 + src/org/happysanta/gd/API/API.java | 101 ++ src/org/happysanta/gd/API/APIException.java | 9 + src/org/happysanta/gd/API/DownloadFile.java | 144 ++ src/org/happysanta/gd/API/DownloadHandler.java | 14 + src/org/happysanta/gd/API/LevelsResponse.java | 64 + .../happysanta/gd/API/NotificationsResponse.java | 76 + src/org/happysanta/gd/API/Request.java | 143 ++ src/org/happysanta/gd/API/Response.java | 26 + src/org/happysanta/gd/API/ResponseHandler.java | 9 + src/org/happysanta/gd/Callback.java | 7 + src/org/happysanta/gd/Command.java | 11 + src/org/happysanta/gd/CommandListener.java | 7 + src/org/happysanta/gd/DoubleCallback.java | 7 + src/org/happysanta/gd/FileDialog.java | 209 +++ src/org/happysanta/gd/GDActivity.java | 1177 +++++++++++++ src/org/happysanta/gd/GDApplication.java | 24 + src/org/happysanta/gd/Game/Bitmap.java | 184 ++ src/org/happysanta/gd/Game/FPMath.java | 80 + src/org/happysanta/gd/Game/GameView.java | 968 +++++++++++ src/org/happysanta/gd/Game/Physics.java | 1336 +++++++++++++++ src/org/happysanta/gd/Game/k.java | 34 + src/org/happysanta/gd/Global.java | 21 + src/org/happysanta/gd/Helpers.java | 309 ++++ src/org/happysanta/gd/KeyboardController.java | 303 ++++ .../gd/Levels/InvalidTrackException.java | 12 + src/org/happysanta/gd/Levels/Level.java | 245 +++ src/org/happysanta/gd/Levels/LevelHeader.java | 53 + src/org/happysanta/gd/Levels/Loader.java | 335 ++++ src/org/happysanta/gd/Levels/Reader.java | 52 + src/org/happysanta/gd/Menu/ActionMenuElement.java | 141 ++ src/org/happysanta/gd/Menu/BigTextMenuElement.java | 30 + .../happysanta/gd/Menu/ClickableMenuElement.java | 196 +++ .../gd/Menu/DownloadLevelsMenuScreen.java | 222 +++ .../happysanta/gd/Menu/EmptyLineMenuElement.java | 42 + .../gd/Menu/HighScoreTextMenuElement.java | 100 ++ .../gd/Menu/InstalledLevelsMenuScreen.java | 103 ++ src/org/happysanta/gd/Menu/LevelMenuElement.java | 370 ++++ src/org/happysanta/gd/Menu/LevelsAdapter.java | 53 + .../gd/Menu/LevelsCountTextMenuElement.java | 86 + src/org/happysanta/gd/Menu/LevelsMenuScreen.java | 429 +++++ src/org/happysanta/gd/Menu/Menu.java | 1554 +++++++++++++++++ src/org/happysanta/gd/Menu/MenuElement.java | 20 + src/org/happysanta/gd/Menu/MenuElementOld.java | 32 + src/org/happysanta/gd/Menu/MenuHandler.java | 12 + src/org/happysanta/gd/Menu/MenuScreen.java | 277 +++ .../happysanta/gd/Menu/NameInputMenuScreen.java | 175 ++ .../gd/Menu/OnMenuElementHighlightListener.java | 10 + src/org/happysanta/gd/Menu/OptionsMenuElement.java | 301 ++++ src/org/happysanta/gd/Menu/SimpleMenuElement.java | 176 ++ .../happysanta/gd/Menu/SimpleMenuElementNew.java | 77 + src/org/happysanta/gd/Menu/TextMenuElement.java | 80 + .../gd/Menu/Views/LevelNameLeadingMarginSpan2.java | 38 + .../happysanta/gd/Menu/Views/MenuHelmetView.java | 111 ++ .../happysanta/gd/Menu/Views/MenuImageView.java | 34 + .../happysanta/gd/Menu/Views/MenuLinearLayout.java | 68 + .../gd/Menu/Views/MenuRelativeLayout.java | 55 + src/org/happysanta/gd/Menu/Views/MenuTextView.java | 73 + .../gd/Menu/Views/MenuTitleLinearLayout.java | 39 + src/org/happysanta/gd/Menu/Views/MenuView.java | 12 + .../gd/Menu/Views/ObservableScrollView.java | 31 + src/org/happysanta/gd/Settings.java | 215 +++ src/org/happysanta/gd/Storage/HighScores.java | 152 ++ src/org/happysanta/gd/Storage/Level.java | 300 ++++ .../happysanta/gd/Storage/LevelsDataSource.java | 293 ++++ src/org/happysanta/gd/Storage/LevelsManager.java | 503 ++++++ .../gd/Storage/LevelsSQLiteOpenHelper.java | 141 ++ src/org/happysanta/gd/Util/HexDump.java | 124 ++ .../happysanta/gd/WaitForNetworkConnection.java | 34 + 349 files changed, 15401 insertions(+) create mode 100755 .classpath create mode 100755 .idea/.name create mode 100644 .idea/artifacts/Gravity_Defied_Classic.xml create mode 100755 .idea/codeStyleSettings.xml create mode 100755 .idea/compiler.xml create mode 100755 .idea/copyright/profiles_settings.xml create mode 100755 .idea/encodings.xml create mode 100644 .idea/libraries/acra_4_5_0.xml create mode 100644 .idea/libraries/android_support_v4.xml create mode 100644 .idea/libraries/android_support_v4_c1a500050aef26b42ae63e5fd8ee3115.xml create mode 100755 .idea/misc.xml create mode 100755 .idea/modules.xml create mode 100755 .idea/scopes/scope_settings.xml create mode 100644 .idea/src.iml create mode 100755 .idea/uiDesigner.xml create mode 100755 .idea/vcs.xml create mode 100755 .idea/workspace.xml create mode 100755 .project create mode 100644 AGDTR.iml create mode 100755 AndroidManifest.xml create mode 100644 README.md create mode 100755 assets/RobotoCondensed-Regular.ttf create mode 100755 assets/levels.mrg create mode 100644 libs/acra-4.5.0.jar create mode 100755 proguard-project.txt create mode 100755 project.properties create mode 100755 psd/drawables/drawable-hdpi/flag_h.psd create mode 100755 psd/drawables/drawable-hdpi/helmet.psd create mode 100644 psd/drawables/drawable-hdpi/ic_downloaded.psd create mode 100644 psd/drawables/drawable-hdpi/ic_menu_down.psd create mode 100644 psd/drawables/drawable-hdpi/ic_menu_up.psd create mode 100644 psd/drawables/drawable-hdpi/ic_sort.psd create mode 100644 psd/drawables/drawable-mdpi/ic_downloaded.psd create mode 100644 psd/drawables/drawable-mdpi/ic_menu_down.psd create mode 100644 psd/drawables/drawable-mdpi/ic_menu_up.psd create mode 100644 psd/drawables/drawable-mdpi/ic_sort.psd create mode 100755 psd/drawables/drawable-mdpi/s_flag_mdpi.psd create mode 100755 psd/drawables/drawable-mdpi/s_lock_mdpi.psd create mode 100755 psd/drawables/drawable-xhdpi/bluearm.psd create mode 100755 psd/drawables/drawable-xhdpi/bluebody.psd create mode 100755 psd/drawables/drawable-xhdpi/blueleg.psd create mode 100755 psd/drawables/drawable-xhdpi/btn_bottom_left.psd create mode 100755 psd/drawables/drawable-xhdpi/btn_bottom_right.psd create mode 100755 psd/drawables/drawable-xhdpi/btn_left_right.psd create mode 100755 psd/drawables/drawable-xhdpi/btn_middle.psd create mode 100755 psd/drawables/drawable-xhdpi/btn_top_bottom_middle.psd create mode 100755 psd/drawables/drawable-xhdpi/btn_top_left.psd create mode 100755 psd/drawables/drawable-xhdpi/btn_top_right.psd create mode 100755 psd/drawables/drawable-xhdpi/engine.psd create mode 100755 psd/drawables/drawable-xhdpi/engine_hdpi.psd create mode 100755 psd/drawables/drawable-xhdpi/engine_xx.psd create mode 100755 psd/drawables/drawable-xhdpi/fender.psd create mode 100755 psd/drawables/drawable-xhdpi/fender_hdpi.psd create mode 100755 psd/drawables/drawable-xhdpi/flag.psd create mode 100755 psd/drawables/drawable-xhdpi/helmet1.psd create mode 100644 psd/drawables/drawable-xhdpi/ic_downloaded.psd create mode 100644 psd/drawables/drawable-xhdpi/ic_menu_down.psd create mode 100644 psd/drawables/drawable-xhdpi/ic_menu_up.psd create mode 100644 psd/drawables/drawable-xhdpi/ic_sort.psd create mode 100755 psd/drawables/drawable-xhdpi/lock.psd create mode 100755 psd/drawables/drawable-xhdpi/medal.psd create mode 100755 psd/drawables/drawable-xhdpi/s_arrow_down.psd create mode 100755 psd/drawables/drawable-xhdpi/s_arrow_up.psd create mode 100755 psd/drawables/drawable-xhdpi/s_steering.psd create mode 100755 psd/drawables/drawable-xhdpi/wheel1.psd create mode 100755 psd/drawables/drawable-xhdpi/wheel_1x.psd create mode 100755 psd/drawables/drawable-xxhdpi/flag_xxh.psd create mode 100755 psd/drawables/drawable-xxhdpi/helmet1.psd create mode 100644 psd/drawables/drawable-xxhdpi/ic_downloaded.psd create mode 100644 psd/drawables/drawable-xxhdpi/ic_menu_down.psd create mode 100644 psd/drawables/drawable-xxhdpi/ic_menu_up.psd create mode 100644 psd/drawables/drawable-xxhdpi/ic_sort.psd create mode 100755 psd/drawables/drawable-xxhdpi/medal_xx.psd create mode 100644 psd/icon/icon_512.psd create mode 100644 psd/icon/icon_hdpi.psd create mode 100644 psd/icon/icon_mdpi.psd create mode 100644 psd/icon/icon_xhdpi.psd create mode 100644 psd/icon/icon_xxhdpi.psd create mode 100644 psd/icon/icon_xxxhdpi.psd create mode 100755 res/drawable-hdpi/btn_b_down.9.png create mode 100755 res/drawable-hdpi/btn_b_up.9.png create mode 100755 res/drawable-hdpi/btn_br_down.9.png create mode 100755 res/drawable-hdpi/btn_br_up.9.png create mode 100755 res/drawable-hdpi/btn_n_down.9.png create mode 100755 res/drawable-hdpi/btn_n_up.9.png create mode 100755 res/drawable-hdpi/btn_r_down.9.png create mode 100755 res/drawable-hdpi/btn_r_up.9.png create mode 100755 res/drawable-hdpi/codebrew.png create mode 100755 res/drawable-hdpi/gd.png create mode 100644 res/drawable-hdpi/ic_downloaded.png create mode 100644 res/drawable-hdpi/ic_downloaded_selected.png create mode 100644 res/drawable-hdpi/ic_installed.png create mode 100644 res/drawable-hdpi/ic_installed_selected.png create mode 100755 res/drawable-hdpi/ic_launcher.png create mode 100755 res/drawable-hdpi/ic_menu_down.png create mode 100755 res/drawable-hdpi/ic_menu_up.png create mode 100644 res/drawable-hdpi/ic_sort_down.png create mode 100644 res/drawable-hdpi/ic_sort_up.png create mode 100644 res/drawable-hdpi/icon.png create mode 100755 res/drawable-hdpi/levels_wheel0.png create mode 100755 res/drawable-hdpi/levels_wheel1.png create mode 100755 res/drawable-hdpi/levels_wheel2.png create mode 100755 res/drawable-hdpi/s_arrow_down.png create mode 100755 res/drawable-hdpi/s_arrow_up.png create mode 100755 res/drawable-hdpi/s_bluearm.png create mode 100755 res/drawable-hdpi/s_bluebody.png create mode 100755 res/drawable-hdpi/s_blueleg.png create mode 100755 res/drawable-hdpi/s_engine.png create mode 100755 res/drawable-hdpi/s_fender.png create mode 100755 res/drawable-hdpi/s_flag_finish0.png create mode 100755 res/drawable-hdpi/s_flag_finish1.png create mode 100755 res/drawable-hdpi/s_flag_finish2.png create mode 100755 res/drawable-hdpi/s_flag_start0.png create mode 100755 res/drawable-hdpi/s_flag_start1.png create mode 100755 res/drawable-hdpi/s_flag_start2.png create mode 100755 res/drawable-hdpi/s_helmet.png create mode 100755 res/drawable-hdpi/s_lock0.png create mode 100755 res/drawable-hdpi/s_lock1.png create mode 100755 res/drawable-hdpi/s_lock2.png create mode 100755 res/drawable-hdpi/s_medal_bronze.png create mode 100755 res/drawable-hdpi/s_medal_gold.png create mode 100755 res/drawable-hdpi/s_medal_silver.png create mode 100755 res/drawable-hdpi/s_steering.png create mode 100755 res/drawable-hdpi/s_wheel1.png create mode 100755 res/drawable-hdpi/s_wheel2.png create mode 100755 res/drawable-mdpi/btn_b_down.9.png create mode 100755 res/drawable-mdpi/btn_b_up.9.png create mode 100755 res/drawable-mdpi/btn_br_down.9.png create mode 100755 res/drawable-mdpi/btn_br_up.9.png create mode 100755 res/drawable-mdpi/btn_n_down.9.png create mode 100755 res/drawable-mdpi/btn_n_up.9.png create mode 100755 res/drawable-mdpi/btn_r_down.9.png create mode 100755 res/drawable-mdpi/btn_r_up.9.png create mode 100755 res/drawable-mdpi/codebrew.png create mode 100755 res/drawable-mdpi/gd.png create mode 100644 res/drawable-mdpi/ic_downloaded.png create mode 100644 res/drawable-mdpi/ic_downloaded_selected.png create mode 100644 res/drawable-mdpi/ic_installed.png create mode 100644 res/drawable-mdpi/ic_installed_selected.png create mode 100755 res/drawable-mdpi/ic_launcher.png create mode 100755 res/drawable-mdpi/ic_menu_down.png create mode 100755 res/drawable-mdpi/ic_menu_up.png create mode 100644 res/drawable-mdpi/ic_sort_down.png create mode 100644 res/drawable-mdpi/ic_sort_up.png create mode 100644 res/drawable-mdpi/icon.png create mode 100755 res/drawable-mdpi/levels_wheel0.png create mode 100755 res/drawable-mdpi/levels_wheel1.png create mode 100755 res/drawable-mdpi/levels_wheel2.png create mode 100755 res/drawable-mdpi/s_arrow_down.png create mode 100755 res/drawable-mdpi/s_arrow_up.png create mode 100755 res/drawable-mdpi/s_bluearm.png create mode 100755 res/drawable-mdpi/s_bluebody.png create mode 100755 res/drawable-mdpi/s_blueleg.png create mode 100755 res/drawable-mdpi/s_engine.png create mode 100755 res/drawable-mdpi/s_fender.png create mode 100755 res/drawable-mdpi/s_flag_finish0.png create mode 100755 res/drawable-mdpi/s_flag_finish1.png create mode 100755 res/drawable-mdpi/s_flag_finish2.png create mode 100755 res/drawable-mdpi/s_flag_start0.png create mode 100755 res/drawable-mdpi/s_flag_start1.png create mode 100755 res/drawable-mdpi/s_flag_start2.png create mode 100755 res/drawable-mdpi/s_helmet.png create mode 100755 res/drawable-mdpi/s_lock0.png create mode 100755 res/drawable-mdpi/s_lock1.png create mode 100755 res/drawable-mdpi/s_lock2.png create mode 100755 res/drawable-mdpi/s_medal_bronze.png create mode 100755 res/drawable-mdpi/s_medal_gold.png create mode 100755 res/drawable-mdpi/s_medal_silver.png create mode 100755 res/drawable-mdpi/s_wheel1.png create mode 100755 res/drawable-mdpi/s_wheel2.png create mode 100755 res/drawable-xhdpi/btn_b_down.9.png create mode 100755 res/drawable-xhdpi/btn_b_up.9.png create mode 100755 res/drawable-xhdpi/btn_br_down.9.png create mode 100755 res/drawable-xhdpi/btn_br_up.9.png create mode 100755 res/drawable-xhdpi/btn_n_down.9.png create mode 100755 res/drawable-xhdpi/btn_n_up.9.png create mode 100755 res/drawable-xhdpi/btn_r_down.9.png create mode 100755 res/drawable-xhdpi/btn_r_up.9.png create mode 100755 res/drawable-xhdpi/codebrew.png create mode 100755 res/drawable-xhdpi/flag.png create mode 100755 res/drawable-xhdpi/gd.png create mode 100644 res/drawable-xhdpi/ic_downloaded.png create mode 100644 res/drawable-xhdpi/ic_downloaded_selected.png create mode 100644 res/drawable-xhdpi/ic_installed.png create mode 100644 res/drawable-xhdpi/ic_installed_selected.png create mode 100755 res/drawable-xhdpi/ic_launcher.png create mode 100755 res/drawable-xhdpi/ic_menu_down.png create mode 100755 res/drawable-xhdpi/ic_menu_up.png create mode 100644 res/drawable-xhdpi/ic_sort_down.png create mode 100644 res/drawable-xhdpi/ic_sort_up.png create mode 100644 res/drawable-xhdpi/icon_xhdpi.png create mode 100755 res/drawable-xhdpi/levels_wheel0.png create mode 100755 res/drawable-xhdpi/levels_wheel1.png create mode 100755 res/drawable-xhdpi/levels_wheel2.png create mode 100755 res/drawable-xhdpi/s_arrow_down.png create mode 100755 res/drawable-xhdpi/s_arrow_up.png create mode 100755 res/drawable-xhdpi/s_bluearm.png create mode 100755 res/drawable-xhdpi/s_bluebody.png create mode 100755 res/drawable-xhdpi/s_blueleg.png create mode 100755 res/drawable-xhdpi/s_engine.png create mode 100755 res/drawable-xhdpi/s_fender.png create mode 100755 res/drawable-xhdpi/s_flag_finish0.png create mode 100755 res/drawable-xhdpi/s_flag_finish1.png create mode 100755 res/drawable-xhdpi/s_flag_finish2.png create mode 100755 res/drawable-xhdpi/s_flag_start0.png create mode 100755 res/drawable-xhdpi/s_flag_start1.png create mode 100755 res/drawable-xhdpi/s_flag_start2.png create mode 100755 res/drawable-xhdpi/s_helmet.png create mode 100755 res/drawable-xhdpi/s_lock0.png create mode 100755 res/drawable-xhdpi/s_lock1.png create mode 100755 res/drawable-xhdpi/s_lock2.png create mode 100755 res/drawable-xhdpi/s_medal_bronze.png create mode 100755 res/drawable-xhdpi/s_medal_gold.png create mode 100755 res/drawable-xhdpi/s_medal_silver.png create mode 100755 res/drawable-xhdpi/s_steering.png create mode 100755 res/drawable-xhdpi/s_wheel1.png create mode 100755 res/drawable-xhdpi/s_wheel2.png create mode 100755 res/drawable-xxhdpi/btn_b_down.9.png create mode 100755 res/drawable-xxhdpi/btn_b_up.9.png create mode 100755 res/drawable-xxhdpi/btn_br_down.9.png create mode 100755 res/drawable-xxhdpi/btn_br_up.9.png create mode 100755 res/drawable-xxhdpi/btn_n_down.9.png create mode 100755 res/drawable-xxhdpi/btn_n_up.9.png create mode 100755 res/drawable-xxhdpi/btn_r_down.9.png create mode 100755 res/drawable-xxhdpi/btn_r_up.9.png create mode 100644 res/drawable-xxhdpi/ic_downloaded.png create mode 100644 res/drawable-xxhdpi/ic_downloaded_selected.png create mode 100644 res/drawable-xxhdpi/ic_installed.png create mode 100644 res/drawable-xxhdpi/ic_installed_selected.png create mode 100755 res/drawable-xxhdpi/ic_menu_down.png create mode 100755 res/drawable-xxhdpi/ic_menu_up.png create mode 100644 res/drawable-xxhdpi/ic_sort_down.png create mode 100644 res/drawable-xxhdpi/ic_sort_up.png create mode 100644 res/drawable-xxhdpi/icon.png create mode 100755 res/drawable-xxhdpi/levels_wheel0.png create mode 100755 res/drawable-xxhdpi/levels_wheel1.png create mode 100755 res/drawable-xxhdpi/levels_wheel2.png create mode 100755 res/drawable-xxhdpi/s_arrow_down.png create mode 100755 res/drawable-xxhdpi/s_arrow_up.png create mode 100755 res/drawable-xxhdpi/s_bluearm.png create mode 100755 res/drawable-xxhdpi/s_bluebody.png create mode 100755 res/drawable-xxhdpi/s_blueleg.png create mode 100755 res/drawable-xxhdpi/s_engine.png create mode 100755 res/drawable-xxhdpi/s_fender.png create mode 100755 res/drawable-xxhdpi/s_flag_finish0.png create mode 100755 res/drawable-xxhdpi/s_flag_finish1.png create mode 100755 res/drawable-xxhdpi/s_flag_finish2.png create mode 100755 res/drawable-xxhdpi/s_flag_start0.png create mode 100755 res/drawable-xxhdpi/s_flag_start1.png create mode 100755 res/drawable-xxhdpi/s_flag_start2.png create mode 100755 res/drawable-xxhdpi/s_helmet.png create mode 100755 res/drawable-xxhdpi/s_lock0.png create mode 100755 res/drawable-xxhdpi/s_lock1.png create mode 100755 res/drawable-xxhdpi/s_lock2.png create mode 100755 res/drawable-xxhdpi/s_medal_bronze.png create mode 100755 res/drawable-xxhdpi/s_medal_gold.png create mode 100755 res/drawable-xxhdpi/s_medal_silver.png create mode 100755 res/drawable-xxhdpi/s_steering.png create mode 100755 res/drawable-xxhdpi/s_wheel1.png create mode 100755 res/drawable-xxhdpi/s_wheel2.png create mode 100644 res/drawable-xxxhdpi/icon.png create mode 100755 res/drawable/btn_b.xml create mode 100755 res/drawable/btn_br.xml create mode 100755 res/drawable/btn_n.xml create mode 100755 res/drawable/btn_r.xml create mode 100755 res/drawable/ic_menu.xml create mode 100644 res/drawable/ic_sort.xml create mode 100644 res/drawable/menu_item_color.xml create mode 100755 res/layout/activity_gdtr.xml create mode 100644 res/layout/levels_list_item.xml create mode 100755 res/menu/gdtr.xml create mode 100755 res/values-sw600dp/dimens.xml create mode 100644 res/values-sw600dp/screen.xml create mode 100755 res/values-sw720dp-land/dimens.xml create mode 100644 res/values-sw720dp-land/screen.xml create mode 100755 res/values-v11/styles.xml create mode 100755 res/values-v14/styles.xml create mode 100755 res/values/dimens.xml create mode 100644 res/values/screen.xml create mode 100755 res/values/strings.xml create mode 100755 res/values/styles.xml create mode 100755 src/org/happysanta/gd/API/API.java create mode 100755 src/org/happysanta/gd/API/APIException.java create mode 100644 src/org/happysanta/gd/API/DownloadFile.java create mode 100644 src/org/happysanta/gd/API/DownloadHandler.java create mode 100755 src/org/happysanta/gd/API/LevelsResponse.java create mode 100644 src/org/happysanta/gd/API/NotificationsResponse.java create mode 100644 src/org/happysanta/gd/API/Request.java create mode 100644 src/org/happysanta/gd/API/Response.java create mode 100755 src/org/happysanta/gd/API/ResponseHandler.java create mode 100644 src/org/happysanta/gd/Callback.java create mode 100755 src/org/happysanta/gd/Command.java create mode 100755 src/org/happysanta/gd/CommandListener.java create mode 100644 src/org/happysanta/gd/DoubleCallback.java create mode 100644 src/org/happysanta/gd/FileDialog.java create mode 100755 src/org/happysanta/gd/GDActivity.java create mode 100644 src/org/happysanta/gd/GDApplication.java create mode 100755 src/org/happysanta/gd/Game/Bitmap.java create mode 100755 src/org/happysanta/gd/Game/FPMath.java create mode 100755 src/org/happysanta/gd/Game/GameView.java create mode 100755 src/org/happysanta/gd/Game/Physics.java create mode 100755 src/org/happysanta/gd/Game/k.java create mode 100755 src/org/happysanta/gd/Global.java create mode 100755 src/org/happysanta/gd/Helpers.java create mode 100644 src/org/happysanta/gd/KeyboardController.java create mode 100644 src/org/happysanta/gd/Levels/InvalidTrackException.java create mode 100755 src/org/happysanta/gd/Levels/Level.java create mode 100644 src/org/happysanta/gd/Levels/LevelHeader.java create mode 100755 src/org/happysanta/gd/Levels/Loader.java create mode 100644 src/org/happysanta/gd/Levels/Reader.java create mode 100755 src/org/happysanta/gd/Menu/ActionMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/BigTextMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/ClickableMenuElement.java create mode 100755 src/org/happysanta/gd/Menu/DownloadLevelsMenuScreen.java create mode 100755 src/org/happysanta/gd/Menu/EmptyLineMenuElement.java create mode 100755 src/org/happysanta/gd/Menu/HighScoreTextMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/InstalledLevelsMenuScreen.java create mode 100755 src/org/happysanta/gd/Menu/LevelMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/LevelsAdapter.java create mode 100644 src/org/happysanta/gd/Menu/LevelsCountTextMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/LevelsMenuScreen.java create mode 100755 src/org/happysanta/gd/Menu/Menu.java create mode 100644 src/org/happysanta/gd/Menu/MenuElement.java create mode 100755 src/org/happysanta/gd/Menu/MenuElementOld.java create mode 100755 src/org/happysanta/gd/Menu/MenuHandler.java create mode 100755 src/org/happysanta/gd/Menu/MenuScreen.java create mode 100644 src/org/happysanta/gd/Menu/NameInputMenuScreen.java create mode 100644 src/org/happysanta/gd/Menu/OnMenuElementHighlightListener.java create mode 100644 src/org/happysanta/gd/Menu/OptionsMenuElement.java create mode 100755 src/org/happysanta/gd/Menu/SimpleMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/SimpleMenuElementNew.java create mode 100755 src/org/happysanta/gd/Menu/TextMenuElement.java create mode 100644 src/org/happysanta/gd/Menu/Views/LevelNameLeadingMarginSpan2.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuHelmetView.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuImageView.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuLinearLayout.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuRelativeLayout.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuTextView.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuTitleLinearLayout.java create mode 100644 src/org/happysanta/gd/Menu/Views/MenuView.java create mode 100644 src/org/happysanta/gd/Menu/Views/ObservableScrollView.java create mode 100644 src/org/happysanta/gd/Settings.java create mode 100644 src/org/happysanta/gd/Storage/HighScores.java create mode 100644 src/org/happysanta/gd/Storage/Level.java create mode 100644 src/org/happysanta/gd/Storage/LevelsDataSource.java create mode 100644 src/org/happysanta/gd/Storage/LevelsManager.java create mode 100644 src/org/happysanta/gd/Storage/LevelsSQLiteOpenHelper.java create mode 100755 src/org/happysanta/gd/Util/HexDump.java create mode 100644 src/org/happysanta/gd/WaitForNetworkConnection.java diff --git a/.classpath b/.classpath new file mode 100755 index 0000000..7bc01d9 --- /dev/null +++ b/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + 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 @@ + + + $PROJECT_DIR$/out/artifacts/Gravity_Defied_Classic + + + + + + + + + + \ 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 @@ + + + + + + + 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 @@ + + + + + + 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 @@ + + + \ 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 @@ + + + + + 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 @@ + + + + + + + + + \ 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 @@ + + + + + + + + + \ 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 @@ + + + + + + + + + \ 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + + \ 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 @@ + + + + + + + + + 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 @@ + + + + \ 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 @@ + + + + + + + + + \ 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 @@ + + + + + + + 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + localhost + 5050 + + + + + + + + + + + 125 + + + + + 1396515407992 + + + 1402860904223 + + + 1402861981255 + + + 1402862022693 + + + 1402950475748 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Gravity_Defied_Classic + + + + + + + + Detection + + + + + + + + + + + + + + + Android API 19 Platform (1) + + + + + + + + AGDTR + + + + + + + + 1.7 + + + + + + + + android-support-v4 + + + + + + + + \ 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 @@ + + + AGDTR + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/AGDTR.iml b/AGDTR.iml new file mode 100644 index 0000000..a138db1 --- /dev/null +++ b/AGDTR.iml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100755 index 0000000..737d563 --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + 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 Binary files /dev/null and b/assets/RobotoCondensed-Regular.ttf differ diff --git a/assets/levels.mrg b/assets/levels.mrg new file mode 100755 index 0000000..e495c2a Binary files /dev/null and b/assets/levels.mrg differ diff --git a/libs/acra-4.5.0.jar b/libs/acra-4.5.0.jar new file mode 100644 index 0000000..81d8cd0 Binary files /dev/null and b/libs/acra-4.5.0.jar 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 Binary files /dev/null and b/psd/drawables/drawable-hdpi/flag_h.psd differ diff --git a/psd/drawables/drawable-hdpi/helmet.psd b/psd/drawables/drawable-hdpi/helmet.psd new file mode 100755 index 0000000..25807cc Binary files /dev/null and b/psd/drawables/drawable-hdpi/helmet.psd 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 Binary files /dev/null and b/psd/drawables/drawable-hdpi/ic_downloaded.psd 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 Binary files /dev/null and b/psd/drawables/drawable-hdpi/ic_menu_down.psd 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 Binary files /dev/null and b/psd/drawables/drawable-hdpi/ic_menu_up.psd 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 Binary files /dev/null and b/psd/drawables/drawable-hdpi/ic_sort.psd 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 Binary files /dev/null and b/psd/drawables/drawable-mdpi/ic_downloaded.psd 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 Binary files /dev/null and b/psd/drawables/drawable-mdpi/ic_menu_down.psd 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 Binary files /dev/null and b/psd/drawables/drawable-mdpi/ic_menu_up.psd 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 Binary files /dev/null and b/psd/drawables/drawable-mdpi/ic_sort.psd 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 Binary files /dev/null and b/psd/drawables/drawable-mdpi/s_flag_mdpi.psd 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 Binary files /dev/null and b/psd/drawables/drawable-mdpi/s_lock_mdpi.psd differ diff --git a/psd/drawables/drawable-xhdpi/bluearm.psd b/psd/drawables/drawable-xhdpi/bluearm.psd new file mode 100755 index 0000000..186eb66 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/bluearm.psd differ diff --git a/psd/drawables/drawable-xhdpi/bluebody.psd b/psd/drawables/drawable-xhdpi/bluebody.psd new file mode 100755 index 0000000..3c67ac3 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/bluebody.psd differ diff --git a/psd/drawables/drawable-xhdpi/blueleg.psd b/psd/drawables/drawable-xhdpi/blueleg.psd new file mode 100755 index 0000000..05a3c89 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/blueleg.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/btn_bottom_left.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/btn_bottom_right.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/btn_left_right.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/btn_middle.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/btn_top_bottom_middle.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/btn_top_left.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/btn_top_right.psd differ diff --git a/psd/drawables/drawable-xhdpi/engine.psd b/psd/drawables/drawable-xhdpi/engine.psd new file mode 100755 index 0000000..2c2f603 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/engine.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/engine_hdpi.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/engine_xx.psd differ diff --git a/psd/drawables/drawable-xhdpi/fender.psd b/psd/drawables/drawable-xhdpi/fender.psd new file mode 100755 index 0000000..da0cda0 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/fender.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/fender_hdpi.psd differ diff --git a/psd/drawables/drawable-xhdpi/flag.psd b/psd/drawables/drawable-xhdpi/flag.psd new file mode 100755 index 0000000..e79ea3e Binary files /dev/null and b/psd/drawables/drawable-xhdpi/flag.psd differ diff --git a/psd/drawables/drawable-xhdpi/helmet1.psd b/psd/drawables/drawable-xhdpi/helmet1.psd new file mode 100755 index 0000000..5af538d Binary files /dev/null and b/psd/drawables/drawable-xhdpi/helmet1.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/ic_downloaded.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/ic_menu_down.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/ic_menu_up.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/ic_sort.psd differ diff --git a/psd/drawables/drawable-xhdpi/lock.psd b/psd/drawables/drawable-xhdpi/lock.psd new file mode 100755 index 0000000..9ae2b21 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/lock.psd differ diff --git a/psd/drawables/drawable-xhdpi/medal.psd b/psd/drawables/drawable-xhdpi/medal.psd new file mode 100755 index 0000000..fdb3c39 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/medal.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/s_arrow_down.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/s_arrow_up.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/s_steering.psd differ diff --git a/psd/drawables/drawable-xhdpi/wheel1.psd b/psd/drawables/drawable-xhdpi/wheel1.psd new file mode 100755 index 0000000..39d48ec Binary files /dev/null and b/psd/drawables/drawable-xhdpi/wheel1.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xhdpi/wheel_1x.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xxhdpi/flag_xxh.psd differ diff --git a/psd/drawables/drawable-xxhdpi/helmet1.psd b/psd/drawables/drawable-xxhdpi/helmet1.psd new file mode 100755 index 0000000..b7aab39 Binary files /dev/null and b/psd/drawables/drawable-xxhdpi/helmet1.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xxhdpi/ic_downloaded.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xxhdpi/ic_menu_down.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xxhdpi/ic_menu_up.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xxhdpi/ic_sort.psd 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 Binary files /dev/null and b/psd/drawables/drawable-xxhdpi/medal_xx.psd differ diff --git a/psd/icon/icon_512.psd b/psd/icon/icon_512.psd new file mode 100644 index 0000000..983d370 Binary files /dev/null and b/psd/icon/icon_512.psd differ diff --git a/psd/icon/icon_hdpi.psd b/psd/icon/icon_hdpi.psd new file mode 100644 index 0000000..f8e88c6 Binary files /dev/null and b/psd/icon/icon_hdpi.psd differ diff --git a/psd/icon/icon_mdpi.psd b/psd/icon/icon_mdpi.psd new file mode 100644 index 0000000..09788de Binary files /dev/null and b/psd/icon/icon_mdpi.psd differ diff --git a/psd/icon/icon_xhdpi.psd b/psd/icon/icon_xhdpi.psd new file mode 100644 index 0000000..5640b8f Binary files /dev/null and b/psd/icon/icon_xhdpi.psd differ diff --git a/psd/icon/icon_xxhdpi.psd b/psd/icon/icon_xxhdpi.psd new file mode 100644 index 0000000..22b5fe9 Binary files /dev/null and b/psd/icon/icon_xxhdpi.psd differ diff --git a/psd/icon/icon_xxxhdpi.psd b/psd/icon/icon_xxxhdpi.psd new file mode 100644 index 0000000..fa6caa5 Binary files /dev/null and b/psd/icon/icon_xxxhdpi.psd 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 Binary files /dev/null and b/res/drawable-hdpi/btn_b_down.9.png 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 Binary files /dev/null and b/res/drawable-hdpi/btn_b_up.9.png 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 Binary files /dev/null and b/res/drawable-hdpi/btn_br_down.9.png 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 Binary files /dev/null and b/res/drawable-hdpi/btn_br_up.9.png 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 Binary files /dev/null and b/res/drawable-hdpi/btn_n_down.9.png 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 Binary files /dev/null and b/res/drawable-hdpi/btn_n_up.9.png 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 Binary files /dev/null and b/res/drawable-hdpi/btn_r_down.9.png 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 Binary files /dev/null and b/res/drawable-hdpi/btn_r_up.9.png differ diff --git a/res/drawable-hdpi/codebrew.png b/res/drawable-hdpi/codebrew.png new file mode 100755 index 0000000..a6b9f38 Binary files /dev/null and b/res/drawable-hdpi/codebrew.png differ diff --git a/res/drawable-hdpi/gd.png b/res/drawable-hdpi/gd.png new file mode 100755 index 0000000..6e7d883 Binary files /dev/null and b/res/drawable-hdpi/gd.png differ diff --git a/res/drawable-hdpi/ic_downloaded.png b/res/drawable-hdpi/ic_downloaded.png new file mode 100644 index 0000000..0628b7e Binary files /dev/null and b/res/drawable-hdpi/ic_downloaded.png 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 Binary files /dev/null and b/res/drawable-hdpi/ic_downloaded_selected.png differ diff --git a/res/drawable-hdpi/ic_installed.png b/res/drawable-hdpi/ic_installed.png new file mode 100644 index 0000000..3a0880d Binary files /dev/null and b/res/drawable-hdpi/ic_installed.png 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 Binary files /dev/null and b/res/drawable-hdpi/ic_installed_selected.png differ diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png new file mode 100755 index 0000000..96a442e Binary files /dev/null and b/res/drawable-hdpi/ic_launcher.png 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 Binary files /dev/null and b/res/drawable-hdpi/ic_menu_down.png 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 Binary files /dev/null and b/res/drawable-hdpi/ic_menu_up.png 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 Binary files /dev/null and b/res/drawable-hdpi/ic_sort_down.png 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 Binary files /dev/null and b/res/drawable-hdpi/ic_sort_up.png differ diff --git a/res/drawable-hdpi/icon.png b/res/drawable-hdpi/icon.png new file mode 100644 index 0000000..99f917e Binary files /dev/null and b/res/drawable-hdpi/icon.png differ diff --git a/res/drawable-hdpi/levels_wheel0.png b/res/drawable-hdpi/levels_wheel0.png new file mode 100755 index 0000000..d68bb36 Binary files /dev/null and b/res/drawable-hdpi/levels_wheel0.png differ diff --git a/res/drawable-hdpi/levels_wheel1.png b/res/drawable-hdpi/levels_wheel1.png new file mode 100755 index 0000000..3a1a638 Binary files /dev/null and b/res/drawable-hdpi/levels_wheel1.png differ diff --git a/res/drawable-hdpi/levels_wheel2.png b/res/drawable-hdpi/levels_wheel2.png new file mode 100755 index 0000000..ae5bb08 Binary files /dev/null and b/res/drawable-hdpi/levels_wheel2.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_arrow_down.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_arrow_up.png differ diff --git a/res/drawable-hdpi/s_bluearm.png b/res/drawable-hdpi/s_bluearm.png new file mode 100755 index 0000000..a09323e Binary files /dev/null and b/res/drawable-hdpi/s_bluearm.png differ diff --git a/res/drawable-hdpi/s_bluebody.png b/res/drawable-hdpi/s_bluebody.png new file mode 100755 index 0000000..8a5241b Binary files /dev/null and b/res/drawable-hdpi/s_bluebody.png differ diff --git a/res/drawable-hdpi/s_blueleg.png b/res/drawable-hdpi/s_blueleg.png new file mode 100755 index 0000000..2a1923a Binary files /dev/null and b/res/drawable-hdpi/s_blueleg.png differ diff --git a/res/drawable-hdpi/s_engine.png b/res/drawable-hdpi/s_engine.png new file mode 100755 index 0000000..12e94db Binary files /dev/null and b/res/drawable-hdpi/s_engine.png differ diff --git a/res/drawable-hdpi/s_fender.png b/res/drawable-hdpi/s_fender.png new file mode 100755 index 0000000..5ddef54 Binary files /dev/null and b/res/drawable-hdpi/s_fender.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_flag_finish0.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_flag_finish1.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_flag_finish2.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_flag_start0.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_flag_start1.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_flag_start2.png differ diff --git a/res/drawable-hdpi/s_helmet.png b/res/drawable-hdpi/s_helmet.png new file mode 100755 index 0000000..c6b728b Binary files /dev/null and b/res/drawable-hdpi/s_helmet.png differ diff --git a/res/drawable-hdpi/s_lock0.png b/res/drawable-hdpi/s_lock0.png new file mode 100755 index 0000000..6750eb7 Binary files /dev/null and b/res/drawable-hdpi/s_lock0.png differ diff --git a/res/drawable-hdpi/s_lock1.png b/res/drawable-hdpi/s_lock1.png new file mode 100755 index 0000000..6187ff7 Binary files /dev/null and b/res/drawable-hdpi/s_lock1.png differ diff --git a/res/drawable-hdpi/s_lock2.png b/res/drawable-hdpi/s_lock2.png new file mode 100755 index 0000000..9e3313f Binary files /dev/null and b/res/drawable-hdpi/s_lock2.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_medal_bronze.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_medal_gold.png 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 Binary files /dev/null and b/res/drawable-hdpi/s_medal_silver.png differ diff --git a/res/drawable-hdpi/s_steering.png b/res/drawable-hdpi/s_steering.png new file mode 100755 index 0000000..32aa001 Binary files /dev/null and b/res/drawable-hdpi/s_steering.png differ diff --git a/res/drawable-hdpi/s_wheel1.png b/res/drawable-hdpi/s_wheel1.png new file mode 100755 index 0000000..8812bf8 Binary files /dev/null and b/res/drawable-hdpi/s_wheel1.png differ diff --git a/res/drawable-hdpi/s_wheel2.png b/res/drawable-hdpi/s_wheel2.png new file mode 100755 index 0000000..08ca382 Binary files /dev/null and b/res/drawable-hdpi/s_wheel2.png 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 Binary files /dev/null and b/res/drawable-mdpi/btn_b_down.9.png 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 Binary files /dev/null and b/res/drawable-mdpi/btn_b_up.9.png 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 Binary files /dev/null and b/res/drawable-mdpi/btn_br_down.9.png 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 Binary files /dev/null and b/res/drawable-mdpi/btn_br_up.9.png 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 Binary files /dev/null and b/res/drawable-mdpi/btn_n_down.9.png 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 Binary files /dev/null and b/res/drawable-mdpi/btn_n_up.9.png 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 Binary files /dev/null and b/res/drawable-mdpi/btn_r_down.9.png 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 Binary files /dev/null and b/res/drawable-mdpi/btn_r_up.9.png differ diff --git a/res/drawable-mdpi/codebrew.png b/res/drawable-mdpi/codebrew.png new file mode 100755 index 0000000..5e46ad2 Binary files /dev/null and b/res/drawable-mdpi/codebrew.png differ diff --git a/res/drawable-mdpi/gd.png b/res/drawable-mdpi/gd.png new file mode 100755 index 0000000..1ad92b5 Binary files /dev/null and b/res/drawable-mdpi/gd.png differ diff --git a/res/drawable-mdpi/ic_downloaded.png b/res/drawable-mdpi/ic_downloaded.png new file mode 100644 index 0000000..b61fcb1 Binary files /dev/null and b/res/drawable-mdpi/ic_downloaded.png 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 Binary files /dev/null and b/res/drawable-mdpi/ic_downloaded_selected.png differ diff --git a/res/drawable-mdpi/ic_installed.png b/res/drawable-mdpi/ic_installed.png new file mode 100644 index 0000000..be79bf9 Binary files /dev/null and b/res/drawable-mdpi/ic_installed.png 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 Binary files /dev/null and b/res/drawable-mdpi/ic_installed_selected.png differ diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png new file mode 100755 index 0000000..359047d Binary files /dev/null and b/res/drawable-mdpi/ic_launcher.png 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 Binary files /dev/null and b/res/drawable-mdpi/ic_menu_down.png 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 Binary files /dev/null and b/res/drawable-mdpi/ic_menu_up.png 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 Binary files /dev/null and b/res/drawable-mdpi/ic_sort_down.png 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 Binary files /dev/null and b/res/drawable-mdpi/ic_sort_up.png differ diff --git a/res/drawable-mdpi/icon.png b/res/drawable-mdpi/icon.png new file mode 100644 index 0000000..570f8a7 Binary files /dev/null and b/res/drawable-mdpi/icon.png differ diff --git a/res/drawable-mdpi/levels_wheel0.png b/res/drawable-mdpi/levels_wheel0.png new file mode 100755 index 0000000..89c03a4 Binary files /dev/null and b/res/drawable-mdpi/levels_wheel0.png differ diff --git a/res/drawable-mdpi/levels_wheel1.png b/res/drawable-mdpi/levels_wheel1.png new file mode 100755 index 0000000..42fe489 Binary files /dev/null and b/res/drawable-mdpi/levels_wheel1.png differ diff --git a/res/drawable-mdpi/levels_wheel2.png b/res/drawable-mdpi/levels_wheel2.png new file mode 100755 index 0000000..7e4f1a4 Binary files /dev/null and b/res/drawable-mdpi/levels_wheel2.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_arrow_down.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_arrow_up.png differ diff --git a/res/drawable-mdpi/s_bluearm.png b/res/drawable-mdpi/s_bluearm.png new file mode 100755 index 0000000..651c0e5 Binary files /dev/null and b/res/drawable-mdpi/s_bluearm.png differ diff --git a/res/drawable-mdpi/s_bluebody.png b/res/drawable-mdpi/s_bluebody.png new file mode 100755 index 0000000..4075175 Binary files /dev/null and b/res/drawable-mdpi/s_bluebody.png differ diff --git a/res/drawable-mdpi/s_blueleg.png b/res/drawable-mdpi/s_blueleg.png new file mode 100755 index 0000000..081b341 Binary files /dev/null and b/res/drawable-mdpi/s_blueleg.png differ diff --git a/res/drawable-mdpi/s_engine.png b/res/drawable-mdpi/s_engine.png new file mode 100755 index 0000000..9d6846d Binary files /dev/null and b/res/drawable-mdpi/s_engine.png differ diff --git a/res/drawable-mdpi/s_fender.png b/res/drawable-mdpi/s_fender.png new file mode 100755 index 0000000..f4abce0 Binary files /dev/null and b/res/drawable-mdpi/s_fender.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_flag_finish0.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_flag_finish1.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_flag_finish2.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_flag_start0.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_flag_start1.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_flag_start2.png differ diff --git a/res/drawable-mdpi/s_helmet.png b/res/drawable-mdpi/s_helmet.png new file mode 100755 index 0000000..81c303c Binary files /dev/null and b/res/drawable-mdpi/s_helmet.png differ diff --git a/res/drawable-mdpi/s_lock0.png b/res/drawable-mdpi/s_lock0.png new file mode 100755 index 0000000..e76031e Binary files /dev/null and b/res/drawable-mdpi/s_lock0.png differ diff --git a/res/drawable-mdpi/s_lock1.png b/res/drawable-mdpi/s_lock1.png new file mode 100755 index 0000000..0610fa1 Binary files /dev/null and b/res/drawable-mdpi/s_lock1.png differ diff --git a/res/drawable-mdpi/s_lock2.png b/res/drawable-mdpi/s_lock2.png new file mode 100755 index 0000000..3d9bd9b Binary files /dev/null and b/res/drawable-mdpi/s_lock2.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_medal_bronze.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_medal_gold.png 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 Binary files /dev/null and b/res/drawable-mdpi/s_medal_silver.png differ diff --git a/res/drawable-mdpi/s_wheel1.png b/res/drawable-mdpi/s_wheel1.png new file mode 100755 index 0000000..3c19f2c Binary files /dev/null and b/res/drawable-mdpi/s_wheel1.png differ diff --git a/res/drawable-mdpi/s_wheel2.png b/res/drawable-mdpi/s_wheel2.png new file mode 100755 index 0000000..50c4168 Binary files /dev/null and b/res/drawable-mdpi/s_wheel2.png 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 Binary files /dev/null and b/res/drawable-xhdpi/btn_b_down.9.png 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 Binary files /dev/null and b/res/drawable-xhdpi/btn_b_up.9.png 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 Binary files /dev/null and b/res/drawable-xhdpi/btn_br_down.9.png 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 Binary files /dev/null and b/res/drawable-xhdpi/btn_br_up.9.png 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 Binary files /dev/null and b/res/drawable-xhdpi/btn_n_down.9.png 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 Binary files /dev/null and b/res/drawable-xhdpi/btn_n_up.9.png 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 Binary files /dev/null and b/res/drawable-xhdpi/btn_r_down.9.png 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 Binary files /dev/null and b/res/drawable-xhdpi/btn_r_up.9.png differ diff --git a/res/drawable-xhdpi/codebrew.png b/res/drawable-xhdpi/codebrew.png new file mode 100755 index 0000000..6fb6b6b Binary files /dev/null and b/res/drawable-xhdpi/codebrew.png differ diff --git a/res/drawable-xhdpi/flag.png b/res/drawable-xhdpi/flag.png new file mode 100755 index 0000000..498ff5d Binary files /dev/null and b/res/drawable-xhdpi/flag.png differ diff --git a/res/drawable-xhdpi/gd.png b/res/drawable-xhdpi/gd.png new file mode 100755 index 0000000..78cae06 Binary files /dev/null and b/res/drawable-xhdpi/gd.png differ diff --git a/res/drawable-xhdpi/ic_downloaded.png b/res/drawable-xhdpi/ic_downloaded.png new file mode 100644 index 0000000..d0c8756 Binary files /dev/null and b/res/drawable-xhdpi/ic_downloaded.png 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 Binary files /dev/null and b/res/drawable-xhdpi/ic_downloaded_selected.png differ diff --git a/res/drawable-xhdpi/ic_installed.png b/res/drawable-xhdpi/ic_installed.png new file mode 100644 index 0000000..4e6434e Binary files /dev/null and b/res/drawable-xhdpi/ic_installed.png 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 Binary files /dev/null and b/res/drawable-xhdpi/ic_installed_selected.png differ diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png new file mode 100755 index 0000000..71c6d76 Binary files /dev/null and b/res/drawable-xhdpi/ic_launcher.png 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 Binary files /dev/null and b/res/drawable-xhdpi/ic_menu_down.png 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 Binary files /dev/null and b/res/drawable-xhdpi/ic_menu_up.png 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 Binary files /dev/null and b/res/drawable-xhdpi/ic_sort_down.png 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 Binary files /dev/null and b/res/drawable-xhdpi/ic_sort_up.png differ diff --git a/res/drawable-xhdpi/icon_xhdpi.png b/res/drawable-xhdpi/icon_xhdpi.png new file mode 100644 index 0000000..7253661 Binary files /dev/null and b/res/drawable-xhdpi/icon_xhdpi.png differ diff --git a/res/drawable-xhdpi/levels_wheel0.png b/res/drawable-xhdpi/levels_wheel0.png new file mode 100755 index 0000000..381feca Binary files /dev/null and b/res/drawable-xhdpi/levels_wheel0.png differ diff --git a/res/drawable-xhdpi/levels_wheel1.png b/res/drawable-xhdpi/levels_wheel1.png new file mode 100755 index 0000000..6c5a67f Binary files /dev/null and b/res/drawable-xhdpi/levels_wheel1.png differ diff --git a/res/drawable-xhdpi/levels_wheel2.png b/res/drawable-xhdpi/levels_wheel2.png new file mode 100755 index 0000000..f2db650 Binary files /dev/null and b/res/drawable-xhdpi/levels_wheel2.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_arrow_down.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_arrow_up.png differ diff --git a/res/drawable-xhdpi/s_bluearm.png b/res/drawable-xhdpi/s_bluearm.png new file mode 100755 index 0000000..0d58122 Binary files /dev/null and b/res/drawable-xhdpi/s_bluearm.png differ diff --git a/res/drawable-xhdpi/s_bluebody.png b/res/drawable-xhdpi/s_bluebody.png new file mode 100755 index 0000000..fba7752 Binary files /dev/null and b/res/drawable-xhdpi/s_bluebody.png differ diff --git a/res/drawable-xhdpi/s_blueleg.png b/res/drawable-xhdpi/s_blueleg.png new file mode 100755 index 0000000..7ea58e3 Binary files /dev/null and b/res/drawable-xhdpi/s_blueleg.png differ diff --git a/res/drawable-xhdpi/s_engine.png b/res/drawable-xhdpi/s_engine.png new file mode 100755 index 0000000..9945c5b Binary files /dev/null and b/res/drawable-xhdpi/s_engine.png differ diff --git a/res/drawable-xhdpi/s_fender.png b/res/drawable-xhdpi/s_fender.png new file mode 100755 index 0000000..9681018 Binary files /dev/null and b/res/drawable-xhdpi/s_fender.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_flag_finish0.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_flag_finish1.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_flag_finish2.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_flag_start0.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_flag_start1.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_flag_start2.png differ diff --git a/res/drawable-xhdpi/s_helmet.png b/res/drawable-xhdpi/s_helmet.png new file mode 100755 index 0000000..423fecc Binary files /dev/null and b/res/drawable-xhdpi/s_helmet.png differ diff --git a/res/drawable-xhdpi/s_lock0.png b/res/drawable-xhdpi/s_lock0.png new file mode 100755 index 0000000..e79b525 Binary files /dev/null and b/res/drawable-xhdpi/s_lock0.png differ diff --git a/res/drawable-xhdpi/s_lock1.png b/res/drawable-xhdpi/s_lock1.png new file mode 100755 index 0000000..57db71c Binary files /dev/null and b/res/drawable-xhdpi/s_lock1.png differ diff --git a/res/drawable-xhdpi/s_lock2.png b/res/drawable-xhdpi/s_lock2.png new file mode 100755 index 0000000..cfbd9a1 Binary files /dev/null and b/res/drawable-xhdpi/s_lock2.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_medal_bronze.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_medal_gold.png 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 Binary files /dev/null and b/res/drawable-xhdpi/s_medal_silver.png differ diff --git a/res/drawable-xhdpi/s_steering.png b/res/drawable-xhdpi/s_steering.png new file mode 100755 index 0000000..64c6d05 Binary files /dev/null and b/res/drawable-xhdpi/s_steering.png differ diff --git a/res/drawable-xhdpi/s_wheel1.png b/res/drawable-xhdpi/s_wheel1.png new file mode 100755 index 0000000..0b3f226 Binary files /dev/null and b/res/drawable-xhdpi/s_wheel1.png differ diff --git a/res/drawable-xhdpi/s_wheel2.png b/res/drawable-xhdpi/s_wheel2.png new file mode 100755 index 0000000..3c36d79 Binary files /dev/null and b/res/drawable-xhdpi/s_wheel2.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/btn_b_down.9.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/btn_b_up.9.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/btn_br_down.9.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/btn_br_up.9.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/btn_n_down.9.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/btn_n_up.9.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/btn_r_down.9.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/btn_r_up.9.png differ diff --git a/res/drawable-xxhdpi/ic_downloaded.png b/res/drawable-xxhdpi/ic_downloaded.png new file mode 100644 index 0000000..22a6f96 Binary files /dev/null and b/res/drawable-xxhdpi/ic_downloaded.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/ic_downloaded_selected.png differ diff --git a/res/drawable-xxhdpi/ic_installed.png b/res/drawable-xxhdpi/ic_installed.png new file mode 100644 index 0000000..215d7a8 Binary files /dev/null and b/res/drawable-xxhdpi/ic_installed.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/ic_installed_selected.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/ic_menu_down.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/ic_menu_up.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/ic_sort_down.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/ic_sort_up.png differ diff --git a/res/drawable-xxhdpi/icon.png b/res/drawable-xxhdpi/icon.png new file mode 100644 index 0000000..4429116 Binary files /dev/null and b/res/drawable-xxhdpi/icon.png differ diff --git a/res/drawable-xxhdpi/levels_wheel0.png b/res/drawable-xxhdpi/levels_wheel0.png new file mode 100755 index 0000000..8ed49b2 Binary files /dev/null and b/res/drawable-xxhdpi/levels_wheel0.png differ diff --git a/res/drawable-xxhdpi/levels_wheel1.png b/res/drawable-xxhdpi/levels_wheel1.png new file mode 100755 index 0000000..7020e8d Binary files /dev/null and b/res/drawable-xxhdpi/levels_wheel1.png differ diff --git a/res/drawable-xxhdpi/levels_wheel2.png b/res/drawable-xxhdpi/levels_wheel2.png new file mode 100755 index 0000000..d190665 Binary files /dev/null and b/res/drawable-xxhdpi/levels_wheel2.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_arrow_down.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_arrow_up.png differ diff --git a/res/drawable-xxhdpi/s_bluearm.png b/res/drawable-xxhdpi/s_bluearm.png new file mode 100755 index 0000000..3209303 Binary files /dev/null and b/res/drawable-xxhdpi/s_bluearm.png differ diff --git a/res/drawable-xxhdpi/s_bluebody.png b/res/drawable-xxhdpi/s_bluebody.png new file mode 100755 index 0000000..e8429f9 Binary files /dev/null and b/res/drawable-xxhdpi/s_bluebody.png differ diff --git a/res/drawable-xxhdpi/s_blueleg.png b/res/drawable-xxhdpi/s_blueleg.png new file mode 100755 index 0000000..91bf7ad Binary files /dev/null and b/res/drawable-xxhdpi/s_blueleg.png differ diff --git a/res/drawable-xxhdpi/s_engine.png b/res/drawable-xxhdpi/s_engine.png new file mode 100755 index 0000000..8a76af3 Binary files /dev/null and b/res/drawable-xxhdpi/s_engine.png differ diff --git a/res/drawable-xxhdpi/s_fender.png b/res/drawable-xxhdpi/s_fender.png new file mode 100755 index 0000000..dc196eb Binary files /dev/null and b/res/drawable-xxhdpi/s_fender.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_flag_finish0.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_flag_finish1.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_flag_finish2.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_flag_start0.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_flag_start1.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_flag_start2.png differ diff --git a/res/drawable-xxhdpi/s_helmet.png b/res/drawable-xxhdpi/s_helmet.png new file mode 100755 index 0000000..b0d1a78 Binary files /dev/null and b/res/drawable-xxhdpi/s_helmet.png differ diff --git a/res/drawable-xxhdpi/s_lock0.png b/res/drawable-xxhdpi/s_lock0.png new file mode 100755 index 0000000..7f629a6 Binary files /dev/null and b/res/drawable-xxhdpi/s_lock0.png differ diff --git a/res/drawable-xxhdpi/s_lock1.png b/res/drawable-xxhdpi/s_lock1.png new file mode 100755 index 0000000..b829b7c Binary files /dev/null and b/res/drawable-xxhdpi/s_lock1.png differ diff --git a/res/drawable-xxhdpi/s_lock2.png b/res/drawable-xxhdpi/s_lock2.png new file mode 100755 index 0000000..be683c9 Binary files /dev/null and b/res/drawable-xxhdpi/s_lock2.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_medal_bronze.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_medal_gold.png 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 Binary files /dev/null and b/res/drawable-xxhdpi/s_medal_silver.png differ diff --git a/res/drawable-xxhdpi/s_steering.png b/res/drawable-xxhdpi/s_steering.png new file mode 100755 index 0000000..426ebb8 Binary files /dev/null and b/res/drawable-xxhdpi/s_steering.png differ diff --git a/res/drawable-xxhdpi/s_wheel1.png b/res/drawable-xxhdpi/s_wheel1.png new file mode 100755 index 0000000..e624d55 Binary files /dev/null and b/res/drawable-xxhdpi/s_wheel1.png differ diff --git a/res/drawable-xxhdpi/s_wheel2.png b/res/drawable-xxhdpi/s_wheel2.png new file mode 100755 index 0000000..e394f00 Binary files /dev/null and b/res/drawable-xxhdpi/s_wheel2.png differ diff --git a/res/drawable-xxxhdpi/icon.png b/res/drawable-xxxhdpi/icon.png new file mode 100644 index 0000000..930d068 Binary files /dev/null and b/res/drawable-xxxhdpi/icon.png 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 @@ + + + + + + + + \ 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 @@ + + + + + + + + \ 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 @@ + + + + + + + + \ 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 @@ + + + + + + + + \ 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 @@ + + + + + + + \ 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 @@ + + + + + + + \ 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 @@ + + + + + + + + \ 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 @@ + + + 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 @@ + + + + + + + + + + + + + + + + + \ 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 @@ + + + + + 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 @@ + + + + + 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 @@ + + + tablet + \ 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 @@ + + + + 128dp + + 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 @@ + + + tablet + \ 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 @@ + + + + + + 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 @@ + + + + + + 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 @@ + + + + 16dp + 16dp + + 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 @@ + + + phone + \ 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 @@ + + + + No + Yes + Back + Ok + Cancel + Go to Main + On + Off + + Gravity Defied + Settings + Exit Game + Main + Play Menu + Options + Help + About + + Play + Start + + Mods + High Scores + Finished! + Ingame + Enter Name + Confirm Clear + Confirm Reset + Level + Track + League + Restart + Restart with new level + Send logs + Next + Continue + Name + Time + + Perspective + Shadows + Driver sprite + Bike sprite + Input + Look ahead + Vibrate on touch + Keyboard in menu + Clear highscore + Full Reset + Reset + Master reset. Application will be restarted. + + Installed mods + Download mods + Download options + Install levels.mrg + Here you can manage installed levels. + Here you can download and install new levels. + + Cleared + Highscores have been cleared + Clearing the highscores cannot be undone. It will remove all the registered times on all tracks. + Would you like to clear the highscores? + 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. + Would you like to do a full reset? + + Objective + 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... + + Keys + Keyset 1
+ 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.

+ Keyset 2
+ 1 accelerates, 4 brakes, 6 leans forward and 5 leans backward.

+ Keyset 3
+ 3 accelerates, 6 brakes, 5 leans forward and 4 leans backward. + ]]>
+ + Unlocking + 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. + + 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. + No Highscores + + Perspective: On/Off
+ Default: <On>
+ Turns on and off the perspective view of the tracks.

+ + Shadows: On/Off
+ Default: <On>
+ Turns on and off the shadows.

+ + Driver Sprite: On / Off
+ Default: <On>
+ <On> uses a texture for the driver. <.Off> uses line graphics.

+ + Bike Sprite: On / Off
+ Default: <On>
+ <On> uses a texture for the bike. <Off> uses line graphics.

+ + Input: Keyset 1,2,3
+ Default: <1>
+ Determines which type of input should be used when playing. See "Keys" in the help menu for more info.

+ + Look ahead: On/Off
+ Default: <On>
+ Turns on and off smart camera movement.

+ + Vibrate on touch: On/Off
+ Default: <On>
+ Enables haptic feedback when you press control keys.

+ + Keyboard in menu: On/Off
+ Default: <On>
+ Turns on and off keyboard in menu.

+ + Clear highscore
+ 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). + ]]>
+ Gravity Defied Classic ported to Android by Gregory Klyushnikov and Eugene Zinoviev
+ Кузница винрара
+ Happy Santa LLC
+ http://gdtr.net \u00A9 2014

+ + Gravity Defied - Trial Racing by Codebrew Software
+ http://codebrew.se \u00A9 2004 + ]]>
+ Ported by
+ Кузница винрара
+ and
+ Happy Santa LLC + ]]>
+ + Crashed + Wheelie! + Finished + Enjoy... + Congratulations! You have successfully unlocked a new league: + League unlocked + You have successfully unlocked a new league: + You have completed all tracks at this level. + Complete more tracks to unlock this track/league combo. + %3$s completed.]]> + + LEAGUE + + + First place! + Second place! + Third place! + + + + On + Off + + + + Keyset 1 + Keyset 2 + Keyset 3 + + + + 100cc + 175cc + 220cc + + + + 100cc + 175cc + 220cc + 325cc + + + + Easy + Medium + Hard + + + Cannot download levels list. + No internet connection + Waiting for network connection… + (%2$s)]]> + (Active)]]> + + Sort by: + + Popularity + Most recent + Oldest + Tracks count + + + Author: %1$s]]> + Added: %1$s]]> + Installed: %1$s]]> + Tracks: %1$s]]> + Install (%1$s Kb) + Install + Installing.. + Load this game + Levels name + Enter levels pack name: + Error + Oops.. + Please wait.. + Success + Levels successfully installed. + Open installed + Installed + Delete + Deleting.. + Downloading.. + Delete levels + Are you sure you want to delete these levels? This action cannot be undone. + Active + Unlock next level + + External storage is not readable. + Downloading was interrupted + No space left on device + Cannot save level into database + No network connection. + Looks like this level is damaged.\nYou can skip it and unlock next level. + +
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 @@ + + + + + + + + + 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 params = new LinkedList(); + 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 params = new LinkedList(); + 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 params = new LinkedList(); + 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 params = new LinkedList(); + 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 { + + 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 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 params; + private ResponseHandler handler; + private AsyncRequestTask task; + private String apiURL; + + public Request(String method, List params, ResponseHandler handler, boolean useDebugURL) { + construct(method, params, handler, useDebugURL ? API.DEBUG_URL : API.URL); + } + + public Request(String method, List params, ResponseHandler handler) { + construct(method, params, handler, API.URL); + } + + private void construct(String method, List 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 { + + @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 fileListenerList = new ListenerList(); + private ListenerList dirListenerList = new ListenerList(); + 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() { + public void fireEvent(FileSelectedListener listener) { + listener.fileSelected(file); + } + }); + } + + private void fireDirectorySelectedEvent(final File directory) { + dirListenerList.fireEvent(new ListenerList.FireHandler() { + public void fireEvent(DirectorySelectedListener listener) { + listener.directorySelected(directory); + } + }); + } + + private void loadFileList(File path) { + this.currentPath = path; + + ArrayList dirs = new ArrayList<>(); + ArrayList files = new ArrayList<>(); + ArrayList 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 comparator = new Comparator() { + @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 { + private List listenerList = new ArrayList(); + + public interface FireHandler { + void fireEvent(L listener); + } + + public void add(L listener) { + listenerList.add(listener); + } + + public void fireEvent(FireHandler fireHandler) { + List copy = new ArrayList(listenerList); + for (L l : copy) { + fireHandler.fireEvent(l); + } + } + + public void remove(L listener) { + listenerList.remove(listener); + } + + public List 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 commands = new ArrayList(); + 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 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 { + + @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 { + + private ArrayList levels; + + public LevelsAdapter(Context context, ArrayList 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 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 { + + @Override + protected Void doInBackground(Level[]... params) { + Level[] _levels = params[0]; + boolean checkInstalled = getThis() instanceof DownloadLevelsMenuScreen; + boolean checkActive = getThis() instanceof InstalledLevelsMenuScreen; + + ArrayList ids; + HashMap 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("" + getString(R.string.time) + ": " + 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 findInstalledLevels(ArrayList apiIds) { + HashMap 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 getAllLevels() { + Cursor cursor = db.query(LevelsSQLiteOpenHelper.TABLE_LEVELS, null, null, null, null, null, null); + + List levels = levelsFromCursor(cursor); + cursor.close(); + + return levels; + } + + public synchronized List getLevels(int offset, int count) { + Cursor cursor = db.query(LevelsSQLiteOpenHelper.TABLE_LEVELS, null, null, null, null, LevelsSQLiteOpenHelper.LEVELS_COLUMN_ID + " ASC", offset + ", " + count); + + List 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 levelsFromCursor(Cursor cursor) { + cursor.moveToFirst(); + List 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 getLevelsStat() { + Level[] levels = getAllInstalledLevels(); + HashMap 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 findInstalledLevels(ArrayList 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 { + @Override + protected Void doInBackground(Level... levels) { + delete(levels[0]); + return null; + } + } + + private class AsyncInstallLevel extends AsyncTask { + @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 { + + 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(); + } + +} -- cgit v1.2.3